Index: src/preparser.h |
diff --git a/src/preparser.h b/src/preparser.h |
index 35b65853b3f553560df54e873043ea26efc2d128..178289a59daa5ba013f9f7881b8a757f506809eb 100644 |
--- a/src/preparser.h |
+++ b/src/preparser.h |
@@ -146,9 +146,9 @@ class ParserBase : public Traits { |
void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
protected: |
- enum AllowEvalOrArgumentsAsIdentifier { |
- kAllowEvalOrArguments, |
- kDontAllowEvalOrArguments |
+ enum AllowRestrictedIdentifiers { |
rossberg
2015/04/08 11:30:11
That's nicer indeed.
conradw
2015/04/09 12:24:17
Acknowledged.
|
+ kAllowRestrictedIdentifiers, |
+ kDontAllowRestrictedIdentifiers |
}; |
enum Mode { |
@@ -479,6 +479,11 @@ class ParserBase : public Traits { |
*ok = false; |
return; |
} |
+ if (is_strong(language_mode) && this->IsUndefined(function_name)) { |
+ Traits::ReportMessageAt(function_name_loc, "strong_undefined"); |
+ *ok = false; |
+ return; |
+ } |
} |
// Checking the parameter names of a function literal. This has to be done |
@@ -486,6 +491,7 @@ class ParserBase : public Traits { |
void CheckFunctionParameterNames(LanguageMode language_mode, |
bool strict_params, |
const Scanner::Location& eval_args_error_loc, |
+ const Scanner::Location& undefined_error_loc, |
const Scanner::Location& dupe_error_loc, |
const Scanner::Location& reserved_loc, |
bool* ok) { |
@@ -496,6 +502,11 @@ class ParserBase : public Traits { |
*ok = false; |
return; |
} |
+ if (is_strong(language_mode) && undefined_error_loc.IsValid()) { |
+ Traits::ReportMessageAt(eval_args_error_loc, "strong_undefined"); |
+ *ok = false; |
+ return; |
+ } |
// TODO(arv): When we add support for destructuring in setters we also need |
// to check for duplicate names. |
if (dupe_error_loc.IsValid()) { |
@@ -547,9 +558,7 @@ class ParserBase : public Traits { |
// allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
// "arguments" as identifier even in strict mode (this is needed in cases like |
// "var foo = eval;"). |
- IdentifierT ParseIdentifier( |
- AllowEvalOrArgumentsAsIdentifier, |
- bool* ok); |
+ IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); |
// Parses an identifier or a strict mode future reserved word, and indicate |
// whether it is strict mode future reserved. |
IdentifierT ParseIdentifierOrStrictReservedWord( |
@@ -702,6 +711,9 @@ class PreParserIdentifier { |
static PreParserIdentifier Arguments() { |
return PreParserIdentifier(kArgumentsIdentifier); |
} |
+ static PreParserIdentifier Undefined() { |
+ return PreParserIdentifier(kUndefinedIdentifier); |
+ } |
static PreParserIdentifier FutureReserved() { |
return PreParserIdentifier(kFutureReservedIdentifier); |
} |
@@ -726,6 +738,7 @@ class PreParserIdentifier { |
bool IsEval() const { return type_ == kEvalIdentifier; } |
bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } |
+ bool IsUndefined() const { return type_ == kUndefinedIdentifier; } |
bool IsLet() const { return type_ == kLetIdentifier; } |
bool IsStatic() const { return type_ == kStaticIdentifier; } |
bool IsYield() const { return type_ == kYieldIdentifier; } |
@@ -737,7 +750,6 @@ class PreParserIdentifier { |
type_ == kLetIdentifier || type_ == kStaticIdentifier || |
type_ == kYieldIdentifier; |
} |
- bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } |
V8_INLINE bool IsValidArrowParam() const { |
// A valid identifier can be an arrow function parameter |
// except for eval, arguments, yield, and reserved keywords. |
@@ -762,6 +774,7 @@ class PreParserIdentifier { |
kYieldIdentifier, |
kEvalIdentifier, |
kArgumentsIdentifier, |
+ kUndefinedIdentifier, |
kPrototypeIdentifier, |
kConstructorIdentifier |
}; |
@@ -1237,6 +1250,10 @@ class PreParserTraits { |
return identifier.IsEvalOrArguments(); |
} |
+ static bool IsUndefined(PreParserIdentifier identifier) { |
+ return identifier.IsUndefined(); |
+ } |
+ |
static bool IsPrototype(PreParserIdentifier identifier) { |
return identifier.IsPrototype(); |
} |
@@ -1725,18 +1742,21 @@ void ParserBase<Traits>::ReportUnexpectedTokenAt( |
} |
-template<class Traits> |
+template <class Traits> |
typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
- AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
- bool* ok) { |
+ AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
Token::Value next = Next(); |
if (next == Token::IDENTIFIER) { |
IdentifierT name = this->GetSymbol(scanner()); |
- if (allow_eval_or_arguments == kDontAllowEvalOrArguments) { |
+ if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { |
if (is_strict(language_mode()) && this->IsEvalOrArguments(name)) { |
ReportMessage("strict_eval_arguments"); |
*ok = false; |
} |
+ if (is_strong(language_mode()) && this->IsUndefined(name)) { |
+ ReportMessage("strong_undefined"); |
+ *ok = false; |
+ } |
} else { |
if (is_strong(language_mode()) && this->IsArguments(name)) { |
ReportMessage("strong_arguments"); |
@@ -1757,7 +1777,6 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
} |
} |
- |
template <class Traits> |
typename ParserBase<Traits>::IdentifierT ParserBase< |
Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
@@ -1896,7 +1915,7 @@ ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { |
case Token::YIELD: |
case Token::FUTURE_STRICT_RESERVED_WORD: { |
// Using eval or arguments in this context is OK even in strict mode. |
- IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
+ IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, |
factory()); |
break; |
@@ -2951,13 +2970,15 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
scope->set_end_position(scanner()->location().end_pos); |
// Arrow function *parameter lists* are always checked as in strict mode. |
- // TODO(arv): eval_args_error_loc and reserved_loc needs to be set by |
- // DeclareArrowParametersFromExpression. |
+ // TODO(arv): eval_args_error_loc, undefined_error_loc, and reserved_loc |
+ // needs to be set by DeclareArrowParametersFromExpression. |
Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); |
+ Scanner::Location undefined_error_loc = Scanner::Location::invalid(); |
Scanner::Location reserved_loc = Scanner::Location::invalid(); |
const bool use_strict_params = true; |
this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
- eval_args_error_loc, dupe_error_loc, reserved_loc, CHECK_OK); |
+ eval_args_error_loc, undefined_error_loc, |
+ dupe_error_loc, reserved_loc, CHECK_OK); |
// Validate strict mode. |
if (is_strict(language_mode())) { |
@@ -3081,12 +3102,21 @@ typename ParserBase<Traits>::ExpressionT ParserBase< |
Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, |
Scanner::Location location, |
const char* message, bool* ok) { |
- if (is_strict(language_mode()) && this->IsIdentifier(expression) && |
- this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
- this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); |
- *ok = false; |
- return this->EmptyExpression(); |
- } else if (expression->IsValidReferenceExpression()) { |
+ if (this->IsIdentifier(expression)) { |
+ if (is_strict(language_mode()) && |
+ this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
+ this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); |
+ *ok = false; |
+ return this->EmptyExpression(); |
+ } |
+ if (is_strong(language_mode()) && |
+ this->IsUndefined(this->AsIdentifier(expression))) { |
+ this->ReportMessageAt(location, "strong_undefined", kSyntaxError); |
+ *ok = false; |
+ return this->EmptyExpression(); |
+ } |
+ } |
+ if (expression->IsValidReferenceExpression()) { |
return expression; |
} else if (expression->IsCall()) { |
// If it is a call, make it a runtime error for legacy web compatibility. |