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); |
| 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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 NOT_A_PATTERN(TryFinallyStatement) | 738 NOT_A_PATTERN(TryFinallyStatement) |
747 NOT_A_PATTERN(UnaryOperation) | 739 NOT_A_PATTERN(UnaryOperation) |
748 NOT_A_PATTERN(VariableDeclaration) | 740 NOT_A_PATTERN(VariableDeclaration) |
749 NOT_A_PATTERN(WhileStatement) | 741 NOT_A_PATTERN(WhileStatement) |
750 NOT_A_PATTERN(WithStatement) | 742 NOT_A_PATTERN(WithStatement) |
751 NOT_A_PATTERN(Yield) | 743 NOT_A_PATTERN(Yield) |
752 | 744 |
753 #undef NOT_A_PATTERN | 745 #undef NOT_A_PATTERN |
754 } // namespace internal | 746 } // namespace internal |
755 } // namespace v8 | 747 } // namespace v8 |
OLD | NEW |