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

Unified Diff: src/parsing/parser.cc

Issue 2217973003: Clean up and simplify Parser::Declare (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix bad merge 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
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/pattern-rewriter.cc » ('j') | 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 19b4891281a1bf82676755a39f64bfca5be9feb9..53506a9d91c1253a115401c6bc8a1e6b948bb826 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -1690,7 +1690,7 @@ Statement* Parser::ParseExportDefault(bool* ok) {
VariableProxy* proxy = NewUnresolved(local_name, CONST);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, CONST, scope(), pos);
- Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
+ Declare(declaration, DeclarationDescriptor::NORMAL, CHECK_OK);
proxy->var()->set_initializer_position(position());
Assignment* assignment = factory()->NewAssignment(
@@ -1980,13 +1980,12 @@ void Parser::DeclareConstVariable(const AstRawString* name,
VariableProxy* proxy = NewUnresolved(name, CONST);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, CONST, scope(), init, pos);
- Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK_VOID);
+ Declare(declaration, DeclarationDescriptor::NORMAL, CHECK_OK_VOID);
}
-
Variable* Parser::Declare(Declaration* declaration,
DeclarationDescriptor::Kind declaration_kind,
- bool resolve, bool* ok, Scope* scope) {
+ bool* ok, Scope* scope) {
VariableProxy* proxy = declaration->proxy();
DCHECK(proxy->raw_name() != NULL);
const AstRawString* name = proxy->raw_name();
@@ -1994,40 +1993,41 @@ Variable* Parser::Declare(Declaration* declaration,
DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY);
bool is_function_declaration = declaration->IsFunctionDeclaration();
if (scope == nullptr) scope = this->scope();
- Scope* declaration_scope =
- IsLexicalVariableMode(mode) ? scope : scope->GetDeclarationScope();
- Variable* var = NULL;
+ if (mode == VAR) scope = scope->GetDeclarationScope();
- // If a suitable scope exists, then we can statically declare this
- // variable and also set its mode. In any case, a Declaration node
- // will be added to the scope so that the declaration can be added
- // to the corresponding activation frame at runtime if necessary.
- // For instance, var declarations inside a sloppy eval scope need
- // to be added to the calling function context. Similarly, strict
- // mode eval scope and lexical eval bindings do not leak variable
- // declarations to the caller's scope so we declare all locals, too.
- if (declaration_scope->is_function_scope() ||
- declaration_scope->is_block_scope() ||
- declaration_scope->is_module_scope() ||
- declaration_scope->is_script_scope() ||
- (declaration_scope->is_eval_scope() &&
- (is_strict(declaration_scope->language_mode()) ||
- IsLexicalVariableMode(mode)))) {
+ DCHECK(!scope->is_catch_scope());
+ DCHECK(!scope->is_with_scope());
+ DCHECK(scope->is_declaration_scope() ||
+ (IsLexicalVariableMode(mode) && scope->is_block_scope()));
+
+ 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,
+ declaration->initialization(), kNotAssigned);
+ var->AllocateTo(VariableLocation::LOOKUP, -1);
+ } else {
// Declare the variable in the declaration scope.
- var = declaration_scope->LookupLocal(name);
+ var = scope->LookupLocal(name);
if (var == NULL) {
// Declare the name.
Variable::Kind kind = Variable::NORMAL;
if (is_function_declaration) {
kind = Variable::FUNCTION;
}
- var = declaration_scope->DeclareLocal(
- name, mode, declaration->initialization(), kind, kNotAssigned);
+ var = scope->DeclareLocal(name, mode, declaration->initialization(), 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(language_mode()) && is_function_declaration &&
+ if (is_sloppy(scope->language_mode()) && is_function_declaration &&
var->is_function()) {
DCHECK(IsLexicalVariableMode(mode) &&
IsLexicalVariableMode(var->mode()));
@@ -2073,67 +2073,20 @@ Variable* Parser::Declare(Declaration* declaration,
} else if (mode == VAR) {
var->set_maybe_assigned();
}
- } else if (declaration_scope->is_eval_scope() &&
- is_sloppy(declaration_scope->language_mode()) &&
- !IsLexicalVariableMode(mode)) {
- // 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(declaration_scope, name, mode, kind,
- declaration->initialization(), kNotAssigned);
- var->AllocateTo(VariableLocation::LOOKUP, -1);
- resolve = true;
}
-
+ 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.
//
- // Note that we always add an unresolved proxy even if it's not
- // used, simply because we don't know in this method (w/o extra
- // parameters) if the proxy is needed or not. The proxy will be
- // bound during variable resolution time unless it was pre-bound
- // below.
- //
- // WARNING: This will lead to multiple declaration nodes for the
+ // This will lead to multiple declaration nodes for the
// same variable if it is declared several times. This is not a
- // semantic issue as long as we keep the source order, but it may be
- // a performance issue since it may lead to repeated
- // DeclareEvalVar or DeclareEvalFunction calls.
- declaration_scope->AddDeclaration(declaration);
-
- // If requested and we have a local variable, bind the proxy to the variable
- // at parse-time. This is used for functions (and consts) declared inside
- // statements: the corresponding function (or const) variable must be in the
- // function scope and not a statement-local scope, e.g. as provided with a
- // 'with' statement:
- //
- // with (obj) {
- // function f() {}
- // }
- //
- // which is translated into:
- //
- // with (obj) {
- // // in this case this is not: 'var f; f = function () {};'
- // var f = function () {};
- // }
- //
- // Note that if 'f' is accessed from inside the 'with' statement, it
- // will be allocated in the context (because we must be able to look
- // it up dynamically) but it will also be accessed statically, i.e.,
- // with a context slot index and a context chain length for this
- // initialization code. Thus, inside the 'with' statement, we need
- // both access to the static and the dynamic context chain; the
- // runtime needs to provide both.
- if (resolve && var != NULL) {
- proxy->BindTo(var);
- }
+ // 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;
}
@@ -2173,7 +2126,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
VariableProxy* proxy = NewUnresolved(name, VAR);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, VAR, scope(), pos);
- Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
+ Declare(declaration, DeclarationDescriptor::NORMAL, CHECK_OK);
NativeFunctionLiteral* lit =
factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
return factory()->NewExpressionStatement(
@@ -2263,7 +2216,7 @@ Statement* Parser::ParseHoistableDeclaration(
VariableProxy* proxy = NewUnresolved(variable_name, mode);
Declaration* declaration =
factory()->NewFunctionDeclaration(proxy, mode, fun, scope(), pos);
- Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
+ Declare(declaration, DeclarationDescriptor::NORMAL, 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
@@ -2322,7 +2275,7 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
VariableProxy* proxy = NewUnresolved(variable_name, LET);
Declaration* declaration =
factory()->NewVariableDeclaration(proxy, LET, scope(), pos);
- Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
+ Declare(declaration, DeclarationDescriptor::NORMAL, CHECK_OK);
proxy->var()->set_initializer_position(position());
Assignment* assignment =
factory()->NewAssignment(Token::INIT, proxy, value, pos);
@@ -3555,7 +3508,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
VariableProxy* proxy = NewUnresolved(names->at(i), mode);
Declaration* declaration = factory()->NewVariableDeclaration(
proxy, mode, scope(), kNoSourcePosition);
- Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
+ Declare(declaration, DeclarationDescriptor::NORMAL, CHECK_OK);
inner_vars.Add(declaration->proxy()->var(), zone());
VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
Assignment* assignment = factory()->NewAssignment(
@@ -3906,8 +3859,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET);
Declaration* tdz_decl = factory()->NewVariableDeclaration(
tdz_proxy, LET, scope(), kNoSourcePosition);
- Variable* tdz_var = Declare(
- tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK);
+ Variable* tdz_var =
+ Declare(tdz_decl, DeclarationDescriptor::NORMAL, CHECK_OK);
tdz_var->set_initializer_position(position());
}
}
@@ -5088,7 +5041,7 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
// TODO(verwaest): declare via block_state.
Declaration* declaration = factory()->NewVariableDeclaration(
proxy, CONST, block_state.scope(), pos);
- Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
+ Declare(declaration, DeclarationDescriptor::NORMAL, CHECK_OK);
}
Expression* extends = nullptr;
@@ -5366,7 +5319,7 @@ void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope,
VariableProxy* proxy = scope->NewUnresolved(factory(), name);
Declaration* declaration = factory()->NewVariableDeclaration(
proxy, VAR, scope, kNoSourcePosition);
- Declare(declaration, DeclarationDescriptor::NORMAL, true, ok, scope);
+ Declare(declaration, DeclarationDescriptor::NORMAL, ok, scope);
DCHECK(ok); // Based on the preceding check, this should not fail
if (!ok) return;
}
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698