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

Unified Diff: src/parsing/pattern-rewriter.cc

Issue 2219223002: Remove more vestigial CONST_LEGACY support and clean up var declaration code (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « no previous file | src/runtime/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/pattern-rewriter.cc
diff --git a/src/parsing/pattern-rewriter.cc b/src/parsing/pattern-rewriter.cc
index 30d521dfa76c47616cbdaf9ecf89399881263795..8d3847237ee2aca8b4fd87bba18b135df2d9ee61 100644
--- a/src/parsing/pattern-rewriter.cc
+++ b/src/parsing/pattern-rewriter.cc
@@ -161,6 +161,9 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
DCHECK(initializer_position_ != kNoSourcePosition);
+ // TODO(adamk): This should probably be checking hoist_scope.
+ // Move it to Parser::Declare() to make it easier to test
+ // the right scope.
Scope* declaration_scope = IsLexicalVariableMode(descriptor_->mode)
? descriptor_->scope
: descriptor_->scope->GetDeclarationScope();
@@ -173,8 +176,10 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
names_->Add(name, zone());
}
- // Initialize variables if needed. A
- // declaration of the form:
+ // If there's no initializer, we're done.
+ if (value == nullptr) return;
+
+ // A declaration of the form:
//
// var v = x;
//
@@ -182,119 +187,57 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
//
// var v; v = x;
//
- // In particular, we need to re-lookup 'v' (in scope_, not
- // declaration_scope) as it may be a different 'v' than the 'v' in the
- // declaration (e.g., if we are inside a 'with' statement or 'catch'
- // block).
- //
- // However, note that const declarations are different! A const
- // declaration of the form:
- //
- // const c = x;
- //
- // is *not* syntactic sugar for:
- //
- // const c; c = x;
- //
- // The "variable" c initialized to x is the same as the declared
- // one - there is no re-lookup (see the last parameter of the
- // Declare() call above).
- Scope* initialization_scope = IsImmutableVariableMode(descriptor_->mode)
- ? declaration_scope
- : descriptor_->scope;
-
-
- // Global variable declarations must be compiled in a specific
- // way. When the script containing the global variable declaration
- // is entered, the global variable must be declared, so that if it
- // doesn't exist (on the global object itself, see ES5 errata) it
- // gets created with an initial undefined value. This is handled
- // by the declarations part of the function representing the
- // top-level global code; see Runtime::DeclareGlobalVariable. If
- // it already exists (in the object or in a prototype), it is
- // *not* touched until the variable declaration statement is
- // executed.
- //
- // Executing the variable declaration statement will always
- // guarantee to give the global object an own property.
- // This way, global variable declarations can shadow
- // properties in the prototype chain, but only after the variable
- // declaration statement has been executed. This is important in
- // browsers where the global object (window) has lots of
- // properties defined in prototype objects.
- if (initialization_scope->is_script_scope() &&
- !IsLexicalVariableMode(descriptor_->mode)) {
- // Compute the arguments for the runtime
- // call.test-parsing/InitializedDeclarationsInStrictForOfError
+ // In particular, we need to re-lookup 'v' as it may be a different
+ // 'v' than the 'v' in the declaration (e.g., if we are inside a
+ // 'with' statement or 'catch' block). Global var declarations
+ // also need special treatment.
+ Scope* var_init_scope = descriptor_->scope;
+
+ if (descriptor_->mode == VAR && var_init_scope->is_script_scope()) {
+ // Global variable declarations must be compiled in a specific
+ // way. When the script containing the global variable declaration
+ // is entered, the global variable must be declared, so that if it
+ // doesn't exist (on the global object itself, see ES5 errata) it
+ // gets created with an initial undefined value. This is handled
+ // by the declarations part of the function representing the
+ // top-level global code; see Runtime::DeclareGlobalVariable. If
+ // it already exists (in the object or in a prototype), it is
+ // *not* touched until the variable declaration statement is
+ // executed.
+ //
+ // Executing the variable declaration statement will always
+ // guarantee to give the global object an own property.
+ // This way, global variable declarations can shadow
+ // properties in the prototype chain, but only after the variable
+ // declaration statement has been executed. This is important in
+ // browsers where the global object (window) has lots of
+ // properties defined in prototype objects.
+
ZoneList<Expression*>* arguments =
new (zone()) ZoneList<Expression*>(3, zone());
- // We have at least 1 parameter.
arguments->Add(
factory()->NewStringLiteral(name, descriptor_->declaration_pos),
zone());
- CallRuntime* initialize;
-
- if (IsImmutableVariableMode(descriptor_->mode)) {
- arguments->Add(value, zone());
- // Construct the call to Runtime_InitializeConstGlobal
- // and add it to the initialization statement block.
- // Note that the function does different things depending on
- // the number of arguments (1 or 2).
- initialize = factory()->NewCallRuntime(Runtime::kInitializeConstGlobal,
- arguments, value->position());
- value = NULL; // zap the value to avoid the unnecessary assignment
- } else {
- // Add language mode.
- // We may want to pass singleton to avoid Literal allocations.
- LanguageMode language_mode = initialization_scope->language_mode();
- arguments->Add(
- factory()->NewNumberLiteral(language_mode, kNoSourcePosition),
- zone());
+ arguments->Add(factory()->NewNumberLiteral(var_init_scope->language_mode(),
+ kNoSourcePosition),
+ zone());
+ arguments->Add(value, zone());
- // Be careful not to assign a value to the global variable if
- // we're in a with. The initialization value should not
- // necessarily be stored in the global object in that case,
- // which is why we need to generate a separate assignment node.
- if (value != NULL && !descriptor_->scope->inside_with()) {
- arguments->Add(value, zone());
- // Construct the call to Runtime_InitializeVarGlobal
- // and add it to the initialization statement block.
- initialize = factory()->NewCallRuntime(Runtime::kInitializeVarGlobal,
- arguments, value->position());
- value = NULL; // zap the value to avoid the unnecessary assignment
- } else {
- initialize = NULL;
- }
- }
-
- if (initialize != NULL) {
- block_->statements()->Add(
- factory()->NewExpressionStatement(initialize, initialize->position()),
- zone());
- }
- } else if (value != nullptr && IsLexicalVariableMode(descriptor_->mode)) {
+ CallRuntime* initialize = factory()->NewCallRuntime(
+ Runtime::kInitializeVarGlobal, arguments, value->position());
+ block_->statements()->Add(
+ factory()->NewExpressionStatement(initialize, initialize->position()),
+ zone());
+ } else {
// For 'let' and 'const' declared variables the initialization always
// assigns to the declared variable.
- DCHECK_NOT_NULL(proxy);
- DCHECK_NOT_NULL(proxy->var());
- DCHECK_NOT_NULL(value);
- // Add break location for destructured sub-pattern.
- int pos = IsSubPattern() ? pattern->position() : value->position();
- Assignment* assignment =
- factory()->NewAssignment(Token::INIT, proxy, value, pos);
- block_->statements()->Add(
- factory()->NewExpressionStatement(assignment, pos), zone());
- value = NULL;
- }
-
- // Add an assignment node to the initialization statement block if we still
- // have a pending initialization value.
- if (value != NULL) {
- DCHECK(descriptor_->mode == VAR);
- // 'var' initializations are simply assignments (with all the consequences
- // if they are inside a 'with' statement - they may change a 'with' object
- // property).
- VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
+ // But for var declarations we need to do a new lookup.
+ if (descriptor_->mode == VAR) {
+ proxy = var_init_scope->NewUnresolved(factory(), name);
+ } else {
+ DCHECK_NOT_NULL(proxy);
+ DCHECK_NOT_NULL(proxy->var());
+ }
// Add break location for destructured sub-pattern.
int pos = IsSubPattern() ? pattern->position() : value->position();
Assignment* assignment =
« no previous file with comments | « no previous file | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698