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

Unified Diff: src/preparser.h

Issue 1060883004: [strong] Implement static restrictions on binding 'undefined' in arrow functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: linebreak 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 986ad80ef9ba22de32a0cbb7de873d9c03c51efb..a7c27c1c649153dc250bbadb3b005c5d75bcdc69 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -495,27 +495,26 @@ class ParserBase : public Traits {
// after parsing the function, since the function can declare itself strict.
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& eval_args_loc,
+ const Scanner::Location& undefined_loc,
+ const Scanner::Location& dupe_loc,
const Scanner::Location& reserved_loc,
bool* ok) {
if (is_sloppy(language_mode) && !strict_params) return;
-
- if (is_strict(language_mode) && eval_args_error_loc.IsValid()) {
- Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
+ if (is_strict(language_mode) && eval_args_loc.IsValid()) {
+ Traits::ReportMessageAt(eval_args_loc, "strict_eval_arguments");
*ok = false;
return;
}
- if (is_strong(language_mode) && undefined_error_loc.IsValid()) {
- Traits::ReportMessageAt(eval_args_error_loc, "strong_undefined");
+ if (is_strong(language_mode) && undefined_loc.IsValid()) {
+ Traits::ReportMessageAt(undefined_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()) {
- Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe");
+ if (dupe_loc.IsValid()) {
+ Traits::ReportMessageAt(dupe_loc, "strict_param_dupe");
*ok = false;
return;
}
@@ -757,11 +756,6 @@ class PreParserIdentifier {
type_ == kLetIdentifier || type_ == kStaticIdentifier ||
type_ == kYieldIdentifier;
}
- V8_INLINE bool IsValidArrowParam() const {
- // A valid identifier can be an arrow function parameter
- // except for eval, arguments, yield, and reserved keywords.
- return !(IsEval() || IsArguments() || IsFutureStrictReserved());
- }
// Allow identifier->name()[->length()] to work. The preparser
// does not need the actual positions/lengths of the identifiers.
@@ -785,6 +779,7 @@ class PreParserIdentifier {
kPrototypeIdentifier,
kConstructorIdentifier
};
+
explicit PreParserIdentifier(Type type) : type_(type) {}
Type type_;
@@ -810,10 +805,11 @@ class PreParserExpression {
static PreParserExpression BinaryOperation(PreParserExpression left,
Token::Value op,
PreParserExpression right) {
- bool valid_arrow_param_list =
- op == Token::COMMA && !left.is_parenthesized() &&
- !right.is_parenthesized() && left.IsValidArrowParams() &&
- right.IsValidArrowParams();
+ ValidArrowParam valid_arrow_param_list =
+ (op == Token::COMMA && !left.is_parenthesized() &&
+ !right.is_parenthesized()) ?
+ std::min(left.ValidateArrowParams(), right.ValidateArrowParams())
+ : kInvalidArrowParam;
return PreParserExpression(
TypeField::encode(kBinaryOperationExpression) |
IsValidArrowParamListField::encode(valid_arrow_param_list));
@@ -915,10 +911,21 @@ class PreParserExpression {
return IsIdentifier() || IsProperty();
}
- bool IsValidArrowParamList() const {
- return IsValidArrowParams() &&
- ParenthesizationField::decode(code_) !=
- kMultiParenthesizedExpression;
+ bool IsValidArrowParamList(Scanner::Location* undefined_loc) const {
+ ValidArrowParam valid = ValidateArrowParams();
+ if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) {
+ return false;
+ }
+ if (valid == kValidArrowParam) {
+ return true;
+ } else if (valid == kInvalidStrongArrowParam) {
+ // Return true for now regardless of strong mode for compatibility with
+ // parser.
+ *undefined_loc = Scanner::Location();
+ return true;
+ } else {
+ return false;
+ }
}
// At the moment PreParser doesn't track these expression types.
@@ -984,13 +991,34 @@ class PreParserExpression {
kNoTemplateTagExpression
};
+ enum ValidArrowParam {
+ kInvalidArrowParam,
+ kInvalidStrongArrowParam,
+ kValidArrowParam
+ };
+
explicit PreParserExpression(uint32_t expression_code)
: code_(expression_code) {}
- V8_INLINE bool IsValidArrowParams() const {
- return IsBinaryOperation()
- ? IsValidArrowParamListField::decode(code_)
- : (IsIdentifier() && AsIdentifier().IsValidArrowParam());
+ V8_INLINE ValidArrowParam ValidateArrowParams() const {
+ if (IsBinaryOperation()) {
+ return IsValidArrowParamListField::decode(code_);
+ }
+ if (!IsIdentifier()) {
+ return kInvalidArrowParam;
+ }
+ PreParserIdentifier ident = AsIdentifier();
+ // A valid identifier can be an arrow function parameter
+ // except for eval, arguments, yield, and reserved keywords.
+ if (ident.IsEval() || ident.IsArguments() ||
+ ident.IsFutureStrictReserved()) {
+ return kInvalidArrowParam;
+ }
+ // In strong mode, 'undefined' is similarly restricted.
+ if (ident.IsUndefined()) {
+ return kInvalidStrongArrowParam;
+ }
+ return kValidArrowParam;
}
// The first five bits are for the Type and Parenthesization.
@@ -1003,7 +1031,7 @@ class PreParserExpression {
ExpressionTypeField;
typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField;
typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField;
- typedef BitField<bool, ParenthesizationField::kNext, 1>
+ typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2>
IsValidArrowParamListField;
typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10>
IdentifierTypeField;
@@ -1491,10 +1519,11 @@ class PreParserTraits {
// Utility functions
int DeclareArrowParametersFromExpression(PreParserExpression expression,
Scope* scope,
+ Scanner::Location* undefined_loc,
Scanner::Location* dupe_loc,
bool* ok) {
// TODO(aperez): Detect duplicated identifiers in paramlists.
- *ok = expression.IsValidArrowParamList();
+ *ok = expression.IsValidArrowParamList(undefined_loc);
return 0;
}
@@ -3022,10 +3051,11 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
typename Traits::Type::Factory function_factory(ast_value_factory());
FunctionState function_state(&function_state_, &scope_, scope,
kArrowFunction, &function_factory);
- Scanner::Location dupe_error_loc = Scanner::Location::invalid();
- // TODO(arv): Pass in eval_args_error_loc and reserved_loc here.
+ Scanner::Location undefined_loc = Scanner::Location::invalid();
+ Scanner::Location dupe_loc = Scanner::Location::invalid();
+ // TODO(arv): Pass in eval_args_loc and reserved_loc here.
num_parameters = Traits::DeclareArrowParametersFromExpression(
- params_ast, scope_, &dupe_error_loc, ok);
+ params_ast, scope_, &undefined_loc, &dupe_loc, ok);
if (!*ok) {
ReportMessageAt(
Scanner::Location(start_pos, scanner()->location().beg_pos),
@@ -3033,6 +3063,11 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
return this->EmptyExpression();
}
+ if (undefined_loc.IsValid()) {
+ // Workaround for preparser not keeping track of positions.
+ undefined_loc = Scanner::Location(start_pos,
+ scanner()->location().end_pos);
+ }
if (num_parameters > Code::kMaxArguments) {
ReportMessageAt(Scanner::Location(params_ast->position(), position()),
"too_many_parameters");
@@ -3043,7 +3078,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
Expect(Token::ARROW, CHECK_OK);
if (peek() == Token::LBRACE) {
- // Multiple statemente body
+ // Multiple statement body
Consume(Token::LBRACE);
bool is_lazily_parsed =
(mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
@@ -3078,15 +3113,14 @@ 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, 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();
+ // TODO(arv): eval_args_loc and reserved_loc needs to be set by
+ // DeclareArrowParametersFromExpression.
+ Scanner::Location eval_args_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, undefined_error_loc,
- dupe_error_loc, reserved_loc, CHECK_OK);
+ eval_args_loc, undefined_loc, dupe_loc,
+ reserved_loc, CHECK_OK);
// Validate strict mode.
if (is_strict(language_mode())) {
« 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