| Index: src/parsing/parser.cc
|
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
| index 1d26e77039d855a2be83214a2a186e200c498e5e..4ba5dd2dfd3e2afd16d808b552b479f971be3da9 100644
|
| --- a/src/parsing/parser.cc
|
| +++ b/src/parsing/parser.cc
|
| @@ -15,6 +15,7 @@
|
| #include "src/base/platform/platform.h"
|
| #include "src/char-predicates-inl.h"
|
| #include "src/messages.h"
|
| +#include "src/parsing/declaration-descriptor.h"
|
| #include "src/parsing/duplicate-finder.h"
|
| #include "src/parsing/parameter-initializer-rewriter.h"
|
| #include "src/parsing/parse-info.h"
|
| @@ -1666,118 +1667,13 @@ Declaration* Parser::DeclareVariable(const AstRawString* name,
|
| scanner()->location().end_pos);
|
| Declaration* declaration =
|
| factory()->NewVariableDeclaration(proxy, this->scope(), pos);
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, CHECK_OK);
|
| + this->scope()->DeclareVariableOrParameter(
|
| + declaration, DeclarationDescriptor::NORMAL, mode, init,
|
| + allow_harmony_restrictive_generators(), &pending_error_handler_,
|
| + use_counts_, CHECK_OK);
|
| return declaration;
|
| }
|
|
|
| -Variable* Parser::Declare(Declaration* declaration,
|
| - DeclarationDescriptor::Kind declaration_kind,
|
| - VariableMode mode, InitializationFlag init, bool* ok,
|
| - Scope* scope) {
|
| - DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY);
|
| -
|
| - VariableProxy* proxy = declaration->proxy();
|
| - DCHECK(proxy->raw_name() != NULL);
|
| - const AstRawString* name = proxy->raw_name();
|
| -
|
| - if (scope == nullptr) scope = this->scope();
|
| - if (mode == VAR) scope = scope->GetDeclarationScope();
|
| - DCHECK(!scope->is_catch_scope());
|
| - DCHECK(!scope->is_with_scope());
|
| - DCHECK(scope->is_declaration_scope() ||
|
| - (IsLexicalVariableMode(mode) && scope->is_block_scope()));
|
| -
|
| - bool is_function_declaration = declaration->IsFunctionDeclaration();
|
| -
|
| - Variable* var = NULL;
|
| - if (scope->is_eval_scope() && is_sloppy(scope->language_mode()) &&
|
| - mode == VAR) {
|
| - // In a var binding in a sloppy direct eval, pollute the enclosing scope
|
| - // with this new binding by doing the following:
|
| - // The proxy is bound to a lookup variable to force a dynamic declaration
|
| - // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
|
| - Variable::Kind kind = Variable::NORMAL;
|
| - // TODO(sigurds) figure out if kNotAssigned is OK here
|
| - var = new (zone()) Variable(scope, name, mode, kind, init, kNotAssigned);
|
| - var->AllocateTo(VariableLocation::LOOKUP, -1);
|
| - } else {
|
| - // Declare the variable in the declaration scope.
|
| - var = scope->LookupLocal(name);
|
| - if (var == NULL) {
|
| - // Declare the name.
|
| - Variable::Kind kind = Variable::NORMAL;
|
| - if (is_function_declaration) {
|
| - kind = Variable::FUNCTION;
|
| - }
|
| - var = scope->DeclareLocal(name, mode, init, kind, kNotAssigned);
|
| - } else if (IsLexicalVariableMode(mode) ||
|
| - IsLexicalVariableMode(var->mode())) {
|
| - // Allow duplicate function decls for web compat, see bug 4693.
|
| - bool duplicate_allowed = false;
|
| - if (is_sloppy(scope->language_mode()) && is_function_declaration &&
|
| - var->is_function()) {
|
| - DCHECK(IsLexicalVariableMode(mode) &&
|
| - IsLexicalVariableMode(var->mode()));
|
| - // If the duplication is allowed, then the var will show up
|
| - // in the SloppyBlockFunctionMap and the new FunctionKind
|
| - // will be a permitted duplicate.
|
| - FunctionKind function_kind =
|
| - declaration->AsFunctionDeclaration()->fun()->kind();
|
| - duplicate_allowed =
|
| - scope->GetDeclarationScope()->sloppy_block_function_map()->Lookup(
|
| - const_cast<AstRawString*>(name), name->hash()) != nullptr &&
|
| - !IsAsyncFunction(function_kind) &&
|
| - !(allow_harmony_restrictive_generators() &&
|
| - IsGeneratorFunction(function_kind));
|
| - }
|
| - if (duplicate_allowed) {
|
| - ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
|
| - } else {
|
| - // The name was declared in this scope before; check for conflicting
|
| - // re-declarations. We have a conflict if either of the declarations
|
| - // is not a var (in script scope, we also have to ignore legacy const
|
| - // for compatibility). There is similar code in runtime.cc in the
|
| - // Declare functions. The function CheckConflictingVarDeclarations
|
| - // checks for var and let bindings from different scopes whereas this
|
| - // is a check for conflicting declarations within the same scope. This
|
| - // check also covers the special case
|
| - //
|
| - // function () { let x; { var x; } }
|
| - //
|
| - // because the var declaration is hoisted to the function scope where
|
| - // 'x' is already bound.
|
| - DCHECK(IsDeclaredVariableMode(var->mode()));
|
| - // In harmony we treat re-declarations as early errors. See
|
| - // ES5 16 for a definition of early errors.
|
| - if (declaration_kind == DeclarationDescriptor::NORMAL) {
|
| - ReportMessage(MessageTemplate::kVarRedeclaration, name);
|
| - } else {
|
| - ReportMessage(MessageTemplate::kParamDupe);
|
| - }
|
| - *ok = false;
|
| - return nullptr;
|
| - }
|
| - } else if (mode == VAR) {
|
| - var->set_maybe_assigned();
|
| - }
|
| - }
|
| - DCHECK_NOT_NULL(var);
|
| -
|
| - // We add a declaration node for every declaration. The compiler
|
| - // will only generate code if necessary. In particular, declarations
|
| - // for inner local variables that do not represent functions won't
|
| - // result in any generated code.
|
| - //
|
| - // This will lead to multiple declaration nodes for the
|
| - // same variable if it is declared several times. This is not a
|
| - // semantic issue, but it may be a performance issue since it may
|
| - // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
|
| - scope->AddDeclaration(declaration);
|
| - proxy->BindTo(var);
|
| - return var;
|
| -}
|
| -
|
| -
|
| // Language extension which is only enabled for source files loaded
|
| // through the API's extension mechanism. A native function
|
| // declaration is resolved by looking up the function through a
|
| @@ -1893,8 +1789,10 @@ Statement* Parser::ParseHoistableDeclaration(
|
| VariableProxy* proxy = NewUnresolved(variable_name);
|
| Declaration* declaration =
|
| factory()->NewFunctionDeclaration(proxy, fun, scope(), pos);
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
|
| - CHECK_OK);
|
| + this->scope()->DeclareVariableOrParameter(
|
| + declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
|
| + allow_harmony_restrictive_generators(), &pending_error_handler_,
|
| + use_counts_, CHECK_OK);
|
| if (names) names->Add(variable_name, zone());
|
| EmptyStatement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
|
| // Async functions don't undergo sloppy mode block scoped hoisting, and don't
|
| @@ -4763,8 +4661,11 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
|
| // TODO(verwaest): declare via block_state.
|
| Declaration* declaration =
|
| factory()->NewVariableDeclaration(proxy, block_state.scope(), pos);
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
|
| - DefaultInitializationFlag(CONST), CHECK_OK);
|
| + this->scope()->DeclareVariableOrParameter(
|
| + declaration, DeclarationDescriptor::NORMAL, CONST,
|
| + DefaultInitializationFlag(CONST),
|
| + allow_harmony_restrictive_generators(), &pending_error_handler_,
|
| + use_counts_, CHECK_OK);
|
| }
|
|
|
| Expression* extends = nullptr;
|
| @@ -5042,10 +4943,13 @@ void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope,
|
| VariableProxy* proxy = scope->NewUnresolved(factory(), name);
|
| Declaration* declaration =
|
| factory()->NewVariableDeclaration(proxy, scope, kNoSourcePosition);
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, VAR,
|
| - DefaultInitializationFlag(VAR), ok, scope);
|
| - DCHECK(ok); // Based on the preceding check, this should not fail
|
| - if (!ok) return;
|
| + scope->DeclareVariableOrParameter(
|
| + declaration, DeclarationDescriptor::NORMAL, VAR,
|
| + DefaultInitializationFlag(VAR),
|
| + allow_harmony_restrictive_generators(), &pending_error_handler_,
|
| + use_counts_, ok);
|
| + DCHECK(*ok); // Based on the preceding check, this should not fail
|
| + if (!*ok) return;
|
| }
|
|
|
| // Read from the local lexical scope and write to the function scope
|
|
|