Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Unified Diff: src/preparser.h

Issue 1070633002: [strong] Implement static restrictions on binding/assignment to 'undefined' identifier. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index 2b61853b0c35db347cb8d4c970d422a1ed576240..986ad80ef9ba22de32a0cbb7de873d9c03c51efb 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -151,9 +151,9 @@ class ParserBase : public Traits {
void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
protected:
- enum AllowEvalOrArgumentsAsIdentifier {
- kAllowEvalOrArguments,
- kDontAllowEvalOrArguments
+ enum AllowRestrictedIdentifiers {
+ kAllowRestrictedIdentifiers,
+ kDontAllowRestrictedIdentifiers
};
enum Mode {
@@ -484,6 +484,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
@@ -491,6 +496,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) {
@@ -501,6 +507,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()) {
@@ -552,9 +563,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(
@@ -709,6 +718,9 @@ class PreParserIdentifier {
static PreParserIdentifier Arguments() {
return PreParserIdentifier(kArgumentsIdentifier);
}
+ static PreParserIdentifier Undefined() {
+ return PreParserIdentifier(kUndefinedIdentifier);
+ }
static PreParserIdentifier FutureReserved() {
return PreParserIdentifier(kFutureReservedIdentifier);
}
@@ -733,6 +745,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; }
@@ -744,7 +757,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.
@@ -769,6 +781,7 @@ class PreParserIdentifier {
kYieldIdentifier,
kEvalIdentifier,
kArgumentsIdentifier,
+ kUndefinedIdentifier,
kPrototypeIdentifier,
kConstructorIdentifier
};
@@ -1263,6 +1276,10 @@ class PreParserTraits {
return identifier.IsEvalOrArguments();
}
+ static bool IsUndefined(PreParserIdentifier identifier) {
+ return identifier.IsUndefined();
+ }
+
static bool IsPrototype(PreParserIdentifier identifier) {
return identifier.IsPrototype();
}
@@ -1785,18 +1802,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");
@@ -1817,7 +1837,6 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
}
}
-
template <class Traits>
typename ParserBase<Traits>::IdentifierT ParserBase<
Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
@@ -1956,7 +1975,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;
@@ -3059,13 +3078,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())) {
@@ -3189,12 +3210,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.
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698