| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index b54172f72c21cc6ccf320ed04877227804a5d134..2c71094c65650c1401efc73b6202214e3332256e 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -346,8 +346,8 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
|
| FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
|
| : FunctionKind::kDefaultBaseConstructor;
|
| Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind);
|
| - function_scope->SetLanguageMode(
|
| - static_cast<LanguageMode>(language_mode | STRICT));
|
| + SetLanguageMode(function_scope,
|
| + static_cast<LanguageMode>(language_mode | STRICT));
|
| // Set start and end position to the same value
|
| function_scope->set_start_position(pos);
|
| function_scope->set_end_position(pos);
|
| @@ -1049,6 +1049,8 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
|
| FunctionState function_state(&function_state_, &scope_, scope,
|
| kNormalFunction, &function_factory);
|
|
|
| + // Don't count the mode in the use counters--give the program a chance
|
| + // to enable script/module-wide strict/strong mode below.
|
| scope_->SetLanguageMode(info->language_mode());
|
| ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
|
| bool ok = true;
|
| @@ -1191,7 +1193,7 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
|
| if (shared_info->is_arrow()) {
|
| Scope* scope =
|
| NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
|
| - scope->SetLanguageMode(shared_info->language_mode());
|
| + SetLanguageMode(scope, shared_info->language_mode());
|
| scope->set_start_position(shared_info->start_position());
|
| ExpressionClassifier formals_classifier;
|
| ParserFormalParameters formals(scope);
|
| @@ -1336,13 +1338,11 @@ void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
|
| // Strong mode implies strict mode. If there are several "use strict"
|
| // / "use strong" directives, do the strict mode changes only once.
|
| if (is_sloppy(scope_->language_mode())) {
|
| - scope_->SetLanguageMode(
|
| - static_cast<LanguageMode>(scope_->language_mode() | STRICT));
|
| + RaiseLanguageMode(STRICT);
|
| }
|
|
|
| if (use_strong_found) {
|
| - scope_->SetLanguageMode(
|
| - static_cast<LanguageMode>(scope_->language_mode() | STRONG));
|
| + RaiseLanguageMode(STRONG);
|
| if (IsClassConstructor(function_state_->kind())) {
|
| // "use strong" cannot occur in a class constructor body, to avoid
|
| // unintuitive strong class object semantics.
|
| @@ -1378,11 +1378,18 @@ void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
|
| // incremented after parsing is done.
|
| ++use_counts_[v8::Isolate::kUseAsm];
|
| scope_->SetAsmModule();
|
| + } else {
|
| + // Should not change mode, but will increment UseCounter
|
| + // if appropriate. Ditto usages below.
|
| + RaiseLanguageMode(SLOPPY);
|
| }
|
| } else {
|
| // End of the directive prologue.
|
| directive_prologue = false;
|
| + RaiseLanguageMode(SLOPPY);
|
| }
|
| + } else {
|
| + RaiseLanguageMode(SLOPPY);
|
| }
|
|
|
| body->Add(stat, zone());
|
| @@ -1459,8 +1466,7 @@ void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
|
| // ModuleItem*
|
|
|
| DCHECK(scope_->is_module_scope());
|
| - scope_->SetLanguageMode(
|
| - static_cast<LanguageMode>(scope_->language_mode() | STRICT));
|
| + RaiseLanguageMode(STRICT);
|
|
|
| while (peek() != Token::EOS) {
|
| Statement* stat = ParseModuleItem(CHECK_OK);
|
| @@ -4183,7 +4189,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| declaration_scope != original_declaration_scope)
|
| ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
|
| : NewScope(scope_, FUNCTION_SCOPE, kind);
|
| - scope->SetLanguageMode(language_mode);
|
| + SetLanguageMode(scope, language_mode);
|
| ZoneList<Statement*>* body = NULL;
|
| int arity = -1;
|
| int materialized_literal_count = -1;
|
| @@ -4415,7 +4421,7 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
|
| total_preparse_skipped_ += scope_->end_position() - function_block_pos;
|
| *materialized_literal_count = entry.literal_count();
|
| *expected_property_count = entry.property_count();
|
| - scope_->SetLanguageMode(entry.language_mode());
|
| + SetLanguageMode(scope_, entry.language_mode());
|
| if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
|
| if (entry.calls_eval()) scope_->RecordEvalCall();
|
| return;
|
| @@ -4451,7 +4457,7 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
|
| total_preparse_skipped_ += scope_->end_position() - function_block_pos;
|
| *materialized_literal_count = logger.literals();
|
| *expected_property_count = logger.properties();
|
| - scope_->SetLanguageMode(logger.language_mode());
|
| + SetLanguageMode(scope_, logger.language_mode());
|
| if (logger.uses_super_property()) {
|
| scope_->RecordSuperPropertyUsage();
|
| }
|
| @@ -4744,7 +4750,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
|
| if (!parameters.is_simple) {
|
| DCHECK_NOT_NULL(inner_scope);
|
| DCHECK_EQ(body, inner_block->statements());
|
| - scope_->SetLanguageMode(inner_scope->language_mode());
|
| + SetLanguageMode(scope_, inner_scope->language_mode());
|
| Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
|
| DCHECK_NOT_NULL(init_block);
|
|
|
| @@ -4848,8 +4854,7 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
|
|
|
| Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
|
| BlockState block_state(&scope_, block_scope);
|
| - scope_->SetLanguageMode(
|
| - static_cast<LanguageMode>(scope_->language_mode() | STRICT));
|
| + RaiseLanguageMode(STRICT);
|
| scope_->SetScopeName(name);
|
|
|
| VariableProxy* proxy = NULL;
|
| @@ -6386,5 +6391,27 @@ Expression* Parser::SpreadCallNew(Expression* function,
|
|
|
| return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
|
| }
|
| +
|
| +
|
| +void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
|
| + v8::Isolate::UseCounterFeature feature;
|
| + if (is_sloppy(mode))
|
| + feature = v8::Isolate::kSloppyMode;
|
| + else if (is_strong(mode))
|
| + feature = v8::Isolate::kStrongMode;
|
| + else if (is_strict(mode))
|
| + feature = v8::Isolate::kStrictMode;
|
| + else
|
| + UNREACHABLE();
|
| + ++use_counts_[feature];
|
| + scope->SetLanguageMode(mode);
|
| +}
|
| +
|
| +
|
| +void Parser::RaiseLanguageMode(LanguageMode mode) {
|
| + SetLanguageMode(scope_,
|
| + static_cast<LanguageMode>(scope_->language_mode() | mode));
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|