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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/runtime/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/parsing/parameter-initializer-rewriter.h" 7 #include "src/parsing/parameter-initializer-rewriter.h"
8 #include "src/parsing/parser.h" 8 #include "src/parsing/parser.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 Variable* var = 154 Variable* var =
155 parser_->Declare(declaration, descriptor_->declaration_kind, 155 parser_->Declare(declaration, descriptor_->declaration_kind,
156 descriptor_->mode != VAR, ok_, descriptor_->hoist_scope); 156 descriptor_->mode != VAR, ok_, descriptor_->hoist_scope);
157 if (!*ok_) return; 157 if (!*ok_) return;
158 DCHECK_NOT_NULL(var); 158 DCHECK_NOT_NULL(var);
159 DCHECK(!proxy->is_resolved() || proxy->var() == var); 159 DCHECK(!proxy->is_resolved() || proxy->var() == var);
160 var->set_initializer_position(initializer_position_); 160 var->set_initializer_position(initializer_position_);
161 161
162 DCHECK(initializer_position_ != kNoSourcePosition); 162 DCHECK(initializer_position_ != kNoSourcePosition);
163 163
164 // TODO(adamk): This should probably be checking hoist_scope.
165 // Move it to Parser::Declare() to make it easier to test
166 // the right scope.
164 Scope* declaration_scope = IsLexicalVariableMode(descriptor_->mode) 167 Scope* declaration_scope = IsLexicalVariableMode(descriptor_->mode)
165 ? descriptor_->scope 168 ? descriptor_->scope
166 : descriptor_->scope->GetDeclarationScope(); 169 : descriptor_->scope->GetDeclarationScope();
167 if (declaration_scope->num_var() > kMaxNumFunctionLocals) { 170 if (declaration_scope->num_var() > kMaxNumFunctionLocals) {
168 parser_->ReportMessage(MessageTemplate::kTooManyVariables); 171 parser_->ReportMessage(MessageTemplate::kTooManyVariables);
169 *ok_ = false; 172 *ok_ = false;
170 return; 173 return;
171 } 174 }
172 if (names_) { 175 if (names_) {
173 names_->Add(name, zone()); 176 names_->Add(name, zone());
174 } 177 }
175 178
176 // Initialize variables if needed. A 179 // If there's no initializer, we're done.
177 // declaration of the form: 180 if (value == nullptr) return;
181
182 // A declaration of the form:
178 // 183 //
179 // var v = x; 184 // var v = x;
180 // 185 //
181 // is syntactic sugar for: 186 // is syntactic sugar for:
182 // 187 //
183 // var v; v = x; 188 // var v; v = x;
184 // 189 //
185 // In particular, we need to re-lookup 'v' (in scope_, not 190 // In particular, we need to re-lookup 'v' as it may be a different
186 // declaration_scope) as it may be a different 'v' than the 'v' in the 191 // 'v' than the 'v' in the declaration (e.g., if we are inside a
187 // declaration (e.g., if we are inside a 'with' statement or 'catch' 192 // 'with' statement or 'catch' block). Global var declarations
188 // block). 193 // also need special treatment.
189 // 194 Scope* var_init_scope = descriptor_->scope;
190 // However, note that const declarations are different! A const
191 // declaration of the form:
192 //
193 // const c = x;
194 //
195 // is *not* syntactic sugar for:
196 //
197 // const c; c = x;
198 //
199 // The "variable" c initialized to x is the same as the declared
200 // one - there is no re-lookup (see the last parameter of the
201 // Declare() call above).
202 Scope* initialization_scope = IsImmutableVariableMode(descriptor_->mode)
203 ? declaration_scope
204 : descriptor_->scope;
205 195
196 if (descriptor_->mode == VAR && var_init_scope->is_script_scope()) {
197 // Global variable declarations must be compiled in a specific
198 // way. When the script containing the global variable declaration
199 // is entered, the global variable must be declared, so that if it
200 // doesn't exist (on the global object itself, see ES5 errata) it
201 // gets created with an initial undefined value. This is handled
202 // by the declarations part of the function representing the
203 // top-level global code; see Runtime::DeclareGlobalVariable. If
204 // it already exists (in the object or in a prototype), it is
205 // *not* touched until the variable declaration statement is
206 // executed.
207 //
208 // Executing the variable declaration statement will always
209 // guarantee to give the global object an own property.
210 // This way, global variable declarations can shadow
211 // properties in the prototype chain, but only after the variable
212 // declaration statement has been executed. This is important in
213 // browsers where the global object (window) has lots of
214 // properties defined in prototype objects.
206 215
207 // Global variable declarations must be compiled in a specific
208 // way. When the script containing the global variable declaration
209 // is entered, the global variable must be declared, so that if it
210 // doesn't exist (on the global object itself, see ES5 errata) it
211 // gets created with an initial undefined value. This is handled
212 // by the declarations part of the function representing the
213 // top-level global code; see Runtime::DeclareGlobalVariable. If
214 // it already exists (in the object or in a prototype), it is
215 // *not* touched until the variable declaration statement is
216 // executed.
217 //
218 // Executing the variable declaration statement will always
219 // guarantee to give the global object an own property.
220 // This way, global variable declarations can shadow
221 // properties in the prototype chain, but only after the variable
222 // declaration statement has been executed. This is important in
223 // browsers where the global object (window) has lots of
224 // properties defined in prototype objects.
225 if (initialization_scope->is_script_scope() &&
226 !IsLexicalVariableMode(descriptor_->mode)) {
227 // Compute the arguments for the runtime
228 // call.test-parsing/InitializedDeclarationsInStrictForOfError
229 ZoneList<Expression*>* arguments = 216 ZoneList<Expression*>* arguments =
230 new (zone()) ZoneList<Expression*>(3, zone()); 217 new (zone()) ZoneList<Expression*>(3, zone());
231 // We have at least 1 parameter.
232 arguments->Add( 218 arguments->Add(
233 factory()->NewStringLiteral(name, descriptor_->declaration_pos), 219 factory()->NewStringLiteral(name, descriptor_->declaration_pos),
234 zone()); 220 zone());
235 CallRuntime* initialize; 221 arguments->Add(factory()->NewNumberLiteral(var_init_scope->language_mode(),
222 kNoSourcePosition),
223 zone());
224 arguments->Add(value, zone());
236 225
237 if (IsImmutableVariableMode(descriptor_->mode)) { 226 CallRuntime* initialize = factory()->NewCallRuntime(
238 arguments->Add(value, zone()); 227 Runtime::kInitializeVarGlobal, arguments, value->position());
239 // Construct the call to Runtime_InitializeConstGlobal 228 block_->statements()->Add(
240 // and add it to the initialization statement block. 229 factory()->NewExpressionStatement(initialize, initialize->position()),
241 // Note that the function does different things depending on 230 zone());
242 // the number of arguments (1 or 2). 231 } else {
243 initialize = factory()->NewCallRuntime(Runtime::kInitializeConstGlobal,
244 arguments, value->position());
245 value = NULL; // zap the value to avoid the unnecessary assignment
246 } else {
247 // Add language mode.
248 // We may want to pass singleton to avoid Literal allocations.
249 LanguageMode language_mode = initialization_scope->language_mode();
250 arguments->Add(
251 factory()->NewNumberLiteral(language_mode, kNoSourcePosition),
252 zone());
253
254 // Be careful not to assign a value to the global variable if
255 // we're in a with. The initialization value should not
256 // necessarily be stored in the global object in that case,
257 // which is why we need to generate a separate assignment node.
258 if (value != NULL && !descriptor_->scope->inside_with()) {
259 arguments->Add(value, zone());
260 // Construct the call to Runtime_InitializeVarGlobal
261 // and add it to the initialization statement block.
262 initialize = factory()->NewCallRuntime(Runtime::kInitializeVarGlobal,
263 arguments, value->position());
264 value = NULL; // zap the value to avoid the unnecessary assignment
265 } else {
266 initialize = NULL;
267 }
268 }
269
270 if (initialize != NULL) {
271 block_->statements()->Add(
272 factory()->NewExpressionStatement(initialize, initialize->position()),
273 zone());
274 }
275 } else if (value != nullptr && IsLexicalVariableMode(descriptor_->mode)) {
276 // For 'let' and 'const' declared variables the initialization always 232 // For 'let' and 'const' declared variables the initialization always
277 // assigns to the declared variable. 233 // assigns to the declared variable.
278 DCHECK_NOT_NULL(proxy); 234 // But for var declarations we need to do a new lookup.
279 DCHECK_NOT_NULL(proxy->var()); 235 if (descriptor_->mode == VAR) {
280 DCHECK_NOT_NULL(value); 236 proxy = var_init_scope->NewUnresolved(factory(), name);
237 } else {
238 DCHECK_NOT_NULL(proxy);
239 DCHECK_NOT_NULL(proxy->var());
240 }
281 // Add break location for destructured sub-pattern. 241 // Add break location for destructured sub-pattern.
282 int pos = IsSubPattern() ? pattern->position() : value->position(); 242 int pos = IsSubPattern() ? pattern->position() : value->position();
283 Assignment* assignment = 243 Assignment* assignment =
284 factory()->NewAssignment(Token::INIT, proxy, value, pos);
285 block_->statements()->Add(
286 factory()->NewExpressionStatement(assignment, pos), zone());
287 value = NULL;
288 }
289
290 // Add an assignment node to the initialization statement block if we still
291 // have a pending initialization value.
292 if (value != NULL) {
293 DCHECK(descriptor_->mode == VAR);
294 // 'var' initializations are simply assignments (with all the consequences
295 // if they are inside a 'with' statement - they may change a 'with' object
296 // property).
297 VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
298 // Add break location for destructured sub-pattern.
299 int pos = IsSubPattern() ? pattern->position() : value->position();
300 Assignment* assignment =
301 factory()->NewAssignment(Token::INIT, proxy, value, pos); 244 factory()->NewAssignment(Token::INIT, proxy, value, pos);
302 block_->statements()->Add( 245 block_->statements()->Add(
303 factory()->NewExpressionStatement(assignment, pos), zone()); 246 factory()->NewExpressionStatement(assignment, pos), zone());
304 } 247 }
305 } 248 }
306 249
307 250
308 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { 251 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
309 auto temp = scope()->NewTemporary(ast_value_factory()->empty_string()); 252 auto temp = scope()->NewTemporary(ast_value_factory()->empty_string());
310 if (value != nullptr) { 253 if (value != nullptr) {
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 NOT_A_PATTERN(TryFinallyStatement) 701 NOT_A_PATTERN(TryFinallyStatement)
759 NOT_A_PATTERN(UnaryOperation) 702 NOT_A_PATTERN(UnaryOperation)
760 NOT_A_PATTERN(VariableDeclaration) 703 NOT_A_PATTERN(VariableDeclaration)
761 NOT_A_PATTERN(WhileStatement) 704 NOT_A_PATTERN(WhileStatement)
762 NOT_A_PATTERN(WithStatement) 705 NOT_A_PATTERN(WithStatement)
763 NOT_A_PATTERN(Yield) 706 NOT_A_PATTERN(Yield)
764 707
765 #undef NOT_A_PATTERN 708 #undef NOT_A_PATTERN
766 } // namespace internal 709 } // namespace internal
767 } // namespace v8 710 } // namespace v8
OLDNEW
« 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