Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ast/ast.h" | 5 #include "src/ast/ast.h" |
| 6 #include "src/messages.h" | 6 #include "src/messages.h" |
| 7 #include "src/objects-inl.h" | 7 #include "src/objects-inl.h" |
| 8 #include "src/parsing/parameter-initializer-rewriter.h" | 8 #include "src/parsing/parameter-initializer-rewriter.h" |
| 9 #include "src/parsing/parser.h" | 9 #include "src/parsing/parser.h" |
| 10 | 10 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 : descriptor_->scope->GetDeclarationScope(); | 155 : descriptor_->scope->GetDeclarationScope(); |
| 156 if (declaration_scope->num_var() > kMaxNumFunctionLocals) { | 156 if (declaration_scope->num_var() > kMaxNumFunctionLocals) { |
| 157 parser_->ReportMessage(MessageTemplate::kTooManyVariables); | 157 parser_->ReportMessage(MessageTemplate::kTooManyVariables); |
| 158 *ok_ = false; | 158 *ok_ = false; |
| 159 return; | 159 return; |
| 160 } | 160 } |
| 161 if (names_) { | 161 if (names_) { |
| 162 names_->Add(name, zone()); | 162 names_->Add(name, zone()); |
| 163 } | 163 } |
| 164 | 164 |
| 165 Scope* var_init_scope = descriptor_->scope; | |
| 166 MarkTopLevelVariableAsAssigned(var_init_scope, proxy); | |
|
marja
2017/01/25 12:44:10
This CL is a bit weird in that we need to remember
| |
| 167 | |
| 165 // If there's no initializer, we're done. | 168 // If there's no initializer, we're done. |
| 166 if (value == nullptr) return; | 169 if (value == nullptr) return; |
| 167 | 170 |
| 168 // A declaration of the form: | 171 // A declaration of the form: |
| 169 // | 172 // |
| 170 // var v = x; | 173 // var v = x; |
| 171 // | 174 // |
| 172 // is syntactic sugar for: | 175 // is syntactic sugar for: |
| 173 // | 176 // |
| 174 // var v; v = x; | 177 // var v; v = x; |
| 175 // | 178 // |
| 176 // In particular, we need to re-lookup 'v' as it may be a different | 179 // In particular, we need to re-lookup 'v' as it may be a different |
| 177 // 'v' than the 'v' in the declaration (e.g., if we are inside a | 180 // 'v' than the 'v' in the declaration (e.g., if we are inside a |
| 178 // 'with' statement or 'catch' block). Global var declarations | 181 // 'with' statement or 'catch' block). Global var declarations |
| 179 // also need special treatment. | 182 // also need special treatment. |
| 180 Scope* var_init_scope = descriptor_->scope; | |
| 181 | 183 |
| 182 if (descriptor_->mode == VAR && var_init_scope->is_script_scope()) { | 184 if (descriptor_->mode == VAR && var_init_scope->is_script_scope()) { |
| 183 // Global variable declarations must be compiled in a specific | 185 // Global variable declarations must be compiled in a specific |
| 184 // way. When the script containing the global variable declaration | 186 // way. When the script containing the global variable declaration |
| 185 // is entered, the global variable must be declared, so that if it | 187 // is entered, the global variable must be declared, so that if it |
| 186 // doesn't exist (on the global object itself, see ES5 errata) it | 188 // doesn't exist (on the global object itself, see ES5 errata) it |
| 187 // gets created with an initial undefined value. This is handled | 189 // gets created with an initial undefined value. This is handled |
| 188 // by the declarations part of the function representing the | 190 // by the declarations part of the function representing the |
| 189 // top-level global code; see Runtime::DeclareGlobalVariable. If | 191 // top-level global code; see Runtime::DeclareGlobalVariable. If |
| 190 // it already exists (in the object or in a prototype), it is | 192 // it already exists (in the object or in a prototype), it is |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 213 Runtime::kInitializeVarGlobal, arguments, value->position()); | 215 Runtime::kInitializeVarGlobal, arguments, value->position()); |
| 214 block_->statements()->Add( | 216 block_->statements()->Add( |
| 215 factory()->NewExpressionStatement(initialize, initialize->position()), | 217 factory()->NewExpressionStatement(initialize, initialize->position()), |
| 216 zone()); | 218 zone()); |
| 217 } else { | 219 } else { |
| 218 // For 'let' and 'const' declared variables the initialization always | 220 // For 'let' and 'const' declared variables the initialization always |
| 219 // assigns to the declared variable. | 221 // assigns to the declared variable. |
| 220 // But for var declarations we need to do a new lookup. | 222 // But for var declarations we need to do a new lookup. |
| 221 if (descriptor_->mode == VAR) { | 223 if (descriptor_->mode == VAR) { |
| 222 proxy = var_init_scope->NewUnresolved(factory(), name); | 224 proxy = var_init_scope->NewUnresolved(factory(), name); |
| 223 // TODO(neis): Set is_assigned on proxy. | |
| 224 } else { | 225 } else { |
| 225 DCHECK_NOT_NULL(proxy); | 226 DCHECK_NOT_NULL(proxy); |
| 226 DCHECK_NOT_NULL(proxy->var()); | 227 DCHECK_NOT_NULL(proxy->var()); |
| 227 if (var_init_scope->is_script_scope() || | |
| 228 var_init_scope->is_module_scope()) { | |
| 229 // We have to pessimistically assume that top-level variables will be | |
| 230 // assigned. This is because they might be accessed by a lazily parsed | |
| 231 // top-level function, which, for efficiency, we preparse without | |
| 232 // variable tracking. In the case of a script (not a module), they | |
| 233 // might also get accessed by another script. | |
| 234 proxy->set_is_assigned(); | |
| 235 } | |
| 236 } | 228 } |
| 237 // Add break location for destructured sub-pattern. | 229 // Add break location for destructured sub-pattern. |
| 238 int pos = IsSubPattern() ? pattern->position() : value->position(); | 230 int pos = IsSubPattern() ? pattern->position() : value->position(); |
| 239 Assignment* assignment = | 231 Assignment* assignment = |
| 240 factory()->NewAssignment(Token::INIT, proxy, value, pos); | 232 factory()->NewAssignment(Token::INIT, proxy, value, pos); |
| 241 block_->statements()->Add( | 233 block_->statements()->Add( |
| 242 factory()->NewExpressionStatement(assignment, pos), zone()); | 234 factory()->NewExpressionStatement(assignment, pos), zone()); |
| 243 } | 235 } |
| 244 } | 236 } |
| 245 | 237 |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 749 NOT_A_PATTERN(TryFinallyStatement) | 741 NOT_A_PATTERN(TryFinallyStatement) |
| 750 NOT_A_PATTERN(UnaryOperation) | 742 NOT_A_PATTERN(UnaryOperation) |
| 751 NOT_A_PATTERN(VariableDeclaration) | 743 NOT_A_PATTERN(VariableDeclaration) |
| 752 NOT_A_PATTERN(WhileStatement) | 744 NOT_A_PATTERN(WhileStatement) |
| 753 NOT_A_PATTERN(WithStatement) | 745 NOT_A_PATTERN(WithStatement) |
| 754 NOT_A_PATTERN(Yield) | 746 NOT_A_PATTERN(Yield) |
| 755 | 747 |
| 756 #undef NOT_A_PATTERN | 748 #undef NOT_A_PATTERN |
| 757 } // namespace internal | 749 } // namespace internal |
| 758 } // namespace v8 | 750 } // namespace v8 |
| OLD | NEW |