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

Unified Diff: src/parsing/parser.cc

Issue 2280033002: Move Parser::Declare to Scope. (Closed)
Patch Set: code review (verwaest@) Created 4 years, 4 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
« src/ast/scopes.cc ('K') | « src/ast/scopes.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« src/ast/scopes.cc ('K') | « src/ast/scopes.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698