Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index 1b177080bb3c0f7c50c983bd4a22f441faef33b6..5439a746185e02366709b9e88355771b3e5d482b 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -334,7 +334,8 @@ void Parser::SetCachedData(ParseInfo* info) { |
| FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, |
| - int pos, int end_pos) { |
| + int pos, int end_pos, |
| + LanguageMode language_mode) { |
| int materialized_literal_count = -1; |
| int expected_property_count = -1; |
| int parameter_count = 0; |
| @@ -345,7 +346,7 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, |
| : FunctionKind::kDefaultBaseConstructor; |
| Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind); |
| function_scope->SetLanguageMode( |
| - static_cast<LanguageMode>(scope->language_mode() | STRICT_BIT)); |
| + static_cast<LanguageMode>(language_mode | STRICT_BIT)); |
| // Set start and end position to the same value |
| function_scope->set_start_position(pos); |
| function_scope->set_end_position(pos); |
| @@ -795,8 +796,9 @@ Expression* ParserTraits::NewTargetExpression(Scope* scope, |
| Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope, |
| - int pos, int end_pos) { |
| - return parser_->DefaultConstructor(call_super, scope, pos, end_pos); |
| + int pos, int end_pos, |
| + LanguageMode mode) { |
| + return parser_->DefaultConstructor(call_super, scope, pos, end_pos, mode); |
| } |
| @@ -873,10 +875,11 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
| const AstRawString* name, Scanner::Location function_name_location, |
| FunctionNameValidity function_name_validity, FunctionKind kind, |
| int function_token_position, FunctionLiteral::FunctionType type, |
| - FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
| + FunctionLiteral::ArityRestriction arity_restriction, |
| + LanguageMode language_mode, bool* ok) { |
| return parser_->ParseFunctionLiteral( |
| name, function_name_location, function_name_validity, kind, |
| - function_token_position, type, arity_restriction, ok); |
| + function_token_position, type, arity_restriction, language_mode, ok); |
| } |
| @@ -1171,7 +1174,6 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info, |
| DCHECK(is_sloppy(scope->language_mode()) || |
| is_strict(info->language_mode())); |
| DCHECK(info->language_mode() == shared_info->language_mode()); |
| - scope->SetLanguageMode(shared_info->language_mode()); |
| FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| ? (shared_info->is_anonymous() |
| ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| @@ -1182,6 +1184,7 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info, |
| if (shared_info->is_arrow()) { |
| Scope* scope = |
| NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); |
| + scope->SetLanguageMode(shared_info->language_mode()); |
| scope->set_start_position(shared_info->start_position()); |
| ExpressionClassifier formals_classifier; |
| ParserFormalParameterParsingState parsing_state(scope); |
| @@ -1227,12 +1230,13 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info, |
| } else if (shared_info->is_default_constructor()) { |
| result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), |
| scope, shared_info->start_position(), |
| - shared_info->end_position()); |
| + shared_info->end_position(), |
| + shared_info->language_mode()); |
| } else { |
| - result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), |
| - kSkipFunctionNameCheck, shared_info->kind(), |
| - RelocInfo::kNoPosition, function_type, |
| - FunctionLiteral::NORMAL_ARITY, &ok); |
| + result = ParseFunctionLiteral( |
| + raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, |
| + shared_info->kind(), RelocInfo::kNoPosition, function_type, |
| + FunctionLiteral::NORMAL_ARITY, shared_info->language_mode(), &ok); |
| } |
| // Make sure the results agree. |
| DCHECK(ok == (result != NULL)); |
| @@ -2195,14 +2199,14 @@ Statement* Parser::ParseFunctionDeclaration( |
| bool is_strict_reserved = false; |
| const AstRawString* name = ParseIdentifierOrStrictReservedWord( |
| &is_strict_reserved, CHECK_OK); |
| - FunctionLiteral* fun = |
| - ParseFunctionLiteral(name, scanner()->location(), |
| - is_strict_reserved ? kFunctionNameIsStrictReserved |
| - : kFunctionNameValidityUnknown, |
| - is_generator ? FunctionKind::kGeneratorFunction |
| - : FunctionKind::kNormalFunction, |
| - pos, FunctionLiteral::DECLARATION, |
| - FunctionLiteral::NORMAL_ARITY, CHECK_OK); |
| + FunctionLiteral* fun = ParseFunctionLiteral( |
| + name, scanner()->location(), |
| + is_strict_reserved ? kFunctionNameIsStrictReserved |
| + : kFunctionNameValidityUnknown, |
| + is_generator ? FunctionKind::kGeneratorFunction |
| + : FunctionKind::kNormalFunction, |
| + pos, FunctionLiteral::DECLARATION, FunctionLiteral::NORMAL_ARITY, |
| + language_mode(), CHECK_OK); |
| // Even if we're not at the top-level of the global or a function |
| // scope, we treat it as such and introduce the function with its |
| // initial value upon entering the corresponding scope. |
| @@ -3920,7 +3924,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| const AstRawString* function_name, Scanner::Location function_name_location, |
| FunctionNameValidity function_name_validity, FunctionKind kind, |
| int function_token_pos, FunctionLiteral::FunctionType function_type, |
| - FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
| + FunctionLiteral::ArityRestriction arity_restriction, |
| + LanguageMode language_mode, bool* ok) { |
| // Function :: |
| // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| // |
| @@ -3976,12 +3981,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| Scope* declaration_scope = scope_->DeclarationScope(); |
| Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
| Scope* scope = function_type == FunctionLiteral::DECLARATION && |
| - is_sloppy(language_mode()) && |
| - !allow_harmony_sloppy() && |
| + is_sloppy(language_mode) && !allow_harmony_sloppy() && |
| (original_scope_ == original_declaration_scope || |
| declaration_scope != original_declaration_scope) |
| ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) |
| : NewScope(scope_, FUNCTION_SCOPE, kind); |
| + scope->SetLanguageMode(language_mode); |
| ZoneList<Statement*>* body = NULL; |
| int materialized_literal_count = -1; |
| int expected_property_count = -1; |
| @@ -4035,7 +4040,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| Variable* fvar = NULL; |
| Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| - bool use_strict_const = is_strict(language_mode()) || |
| + bool use_strict_const = is_strict(language_mode) || |
|
rossberg
2015/07/15 08:36:52
Does this perhaps already fix this other inconsist
|
| (!allow_legacy_const() && allow_harmony_sloppy()); |
| if (use_strict_const) { |
| fvar_init_op = Token::INIT_CONST; |
| @@ -4118,34 +4123,37 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| fvar_init_op, kind, CHECK_OK); |
| materialized_literal_count = function_state.materialized_literal_count(); |
| expected_property_count = function_state.expected_property_count(); |
| + } |
| - if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
| - if (!function_state.super_location().IsValid()) { |
| - ReportMessageAt(function_name_location, |
| - MessageTemplate::kStrongSuperCallMissing, |
| - kReferenceError); |
| - *ok = false; |
| - return nullptr; |
| - } |
| + // Parsing the body may change the language mode in our scope. |
| + language_mode = scope->language_mode(); |
| + |
| + if (is_strong(language_mode) && IsSubclassConstructor(kind)) { |
| + if (!function_state.super_location().IsValid()) { |
| + ReportMessageAt(function_name_location, |
| + MessageTemplate::kStrongSuperCallMissing, |
| + kReferenceError); |
| + *ok = false; |
| + return nullptr; |
| } |
| } |
| // Validate name and parameter names. We can do this only after parsing the |
| // function, since the function can declare itself strict. |
| - CheckFunctionName(language_mode(), function_name, function_name_validity, |
| + CheckFunctionName(language_mode, function_name, function_name_validity, |
| function_name_location, CHECK_OK); |
| const bool use_strict_params = |
| !parsing_state.is_simple_parameter_list || IsConciseMethod(kind); |
| const bool allow_duplicate_parameters = |
| - is_sloppy(language_mode()) && !use_strict_params; |
| - ValidateFormalParameters(&formals_classifier, language_mode(), |
| + is_sloppy(language_mode) && !use_strict_params; |
| + ValidateFormalParameters(&formals_classifier, language_mode, |
| allow_duplicate_parameters, CHECK_OK); |
| - if (is_strict(language_mode())) { |
| + if (is_strict(language_mode)) { |
| CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
| CHECK_OK); |
| } |
| - if (is_strict(language_mode()) || allow_harmony_sloppy()) { |
| + if (is_strict(language_mode) || allow_harmony_sloppy()) { |
| CheckConflictingVarDeclarations(scope, CHECK_OK); |
| } |
| } |
| @@ -4534,8 +4542,8 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, |
| int end_pos = scanner()->location().end_pos; |
| if (constructor == NULL) { |
| - constructor = |
| - DefaultConstructor(extends != NULL, block_scope, pos, end_pos); |
| + constructor = DefaultConstructor(extends != NULL, block_scope, pos, end_pos, |
| + block_scope->language_mode()); |
| } |
| block_scope->set_end_position(end_pos); |