Chromium Code Reviews| Index: src/parsing/parser.cc |
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
| index 1d26e77039d855a2be83214a2a186e200c498e5e..1ceace172e41dc47fcc3e3590ee87910b160f4b7 100644 |
| --- a/src/parsing/parser.cc |
| +++ b/src/parsing/parser.cc |
| @@ -1674,110 +1674,27 @@ 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(); |
| + if (scope == nullptr) { |
| + scope = this->scope(); |
| + } |
| + bool sloppy_mode_block_scope_function_redefinition = false; |
| + Variable* variable = scope->DeclareVariable( |
| + declaration, mode, init, allow_harmony_restrictive_generators(), |
| + &sloppy_mode_block_scope_function_redefinition, ok); |
| + if (!*ok) { |
| + if (declaration_kind == DeclarationDescriptor::NORMAL) { |
| + ReportMessage(MessageTemplate::kVarRedeclaration, |
| + declaration->proxy()->raw_name()); |
| + } else { |
| + ReportMessage(MessageTemplate::kParamDupe); |
| } |
|
adamk
2016/08/30 18:58:32
I'd prefer if there was an explicit "return nullpt
marja
2016/08/31 07:44:53
Ah, true, it's definitely good to return nullptr h
|
| } |
| - 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; |
| + if (sloppy_mode_block_scope_function_redefinition) { |
| + ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; |
| + } |
| + return variable; |
| } |
| - |
| // 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 |
| @@ -5044,8 +4961,8 @@ void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope, |
| 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; |
| + 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 |