OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/scopes.h" | 7 #include "src/scopes.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 InitializationFlag initialization_flag, | 36 InitializationFlag initialization_flag, |
37 MaybeAssignedFlag maybe_assigned_flag, | 37 MaybeAssignedFlag maybe_assigned_flag, |
38 Interface* interface) { | 38 Interface* interface) { |
39 // AstRawStrings are unambiguous, i.e., the same string is always represented | 39 // AstRawStrings are unambiguous, i.e., the same string is always represented |
40 // by the same AstRawString*. | 40 // by the same AstRawString*. |
41 // FIXME(marja): fix the type of Lookup. | 41 // FIXME(marja): fix the type of Lookup. |
42 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(), | 42 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(), |
43 true, ZoneAllocationPolicy(zone())); | 43 true, ZoneAllocationPolicy(zone())); |
44 if (p->value == NULL) { | 44 if (p->value == NULL) { |
45 // The variable has not been declared yet -> insert it. | 45 // The variable has not been declared yet -> insert it. |
46 ASSERT(p->key == name); | 46 DCHECK(p->key == name); |
47 p->value = new (zone()) | 47 p->value = new (zone()) |
48 Variable(scope, name, mode, is_valid_lhs, kind, initialization_flag, | 48 Variable(scope, name, mode, is_valid_lhs, kind, initialization_flag, |
49 maybe_assigned_flag, interface); | 49 maybe_assigned_flag, interface); |
50 } | 50 } |
51 return reinterpret_cast<Variable*>(p->value); | 51 return reinterpret_cast<Variable*>(p->value); |
52 } | 52 } |
53 | 53 |
54 | 54 |
55 Variable* VariableMap::Lookup(const AstRawString* name) { | 55 Variable* VariableMap::Lookup(const AstRawString* name) { |
56 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(), | 56 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash(), |
57 false, ZoneAllocationPolicy(NULL)); | 57 false, ZoneAllocationPolicy(NULL)); |
58 if (p != NULL) { | 58 if (p != NULL) { |
59 ASSERT(reinterpret_cast<const AstRawString*>(p->key) == name); | 59 DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name); |
60 ASSERT(p->value != NULL); | 60 DCHECK(p->value != NULL); |
61 return reinterpret_cast<Variable*>(p->value); | 61 return reinterpret_cast<Variable*>(p->value); |
62 } | 62 } |
63 return NULL; | 63 return NULL; |
64 } | 64 } |
65 | 65 |
66 | 66 |
67 // ---------------------------------------------------------------------------- | 67 // ---------------------------------------------------------------------------- |
68 // Implementation of Scope | 68 // Implementation of Scope |
69 | 69 |
70 Scope::Scope(Scope* outer_scope, ScopeType scope_type, | 70 Scope::Scope(Scope* outer_scope, ScopeType scope_type, |
71 AstValueFactory* ast_value_factory, Zone* zone) | 71 AstValueFactory* ast_value_factory, Zone* zone) |
72 : isolate_(zone->isolate()), | 72 : isolate_(zone->isolate()), |
73 inner_scopes_(4, zone), | 73 inner_scopes_(4, zone), |
74 variables_(zone), | 74 variables_(zone), |
75 internals_(4, zone), | 75 internals_(4, zone), |
76 temps_(4, zone), | 76 temps_(4, zone), |
77 params_(4, zone), | 77 params_(4, zone), |
78 unresolved_(16, zone), | 78 unresolved_(16, zone), |
79 decls_(4, zone), | 79 decls_(4, zone), |
80 interface_(FLAG_harmony_modules && | 80 interface_(FLAG_harmony_modules && |
81 (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE) | 81 (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE) |
82 ? Interface::NewModule(zone) : NULL), | 82 ? Interface::NewModule(zone) : NULL), |
83 already_resolved_(false), | 83 already_resolved_(false), |
84 ast_value_factory_(ast_value_factory), | 84 ast_value_factory_(ast_value_factory), |
85 zone_(zone) { | 85 zone_(zone) { |
86 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null()); | 86 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null()); |
87 // The outermost scope must be a global scope. | 87 // The outermost scope must be a global scope. |
88 ASSERT(scope_type == GLOBAL_SCOPE || outer_scope != NULL); | 88 DCHECK(scope_type == GLOBAL_SCOPE || outer_scope != NULL); |
89 ASSERT(!HasIllegalRedeclaration()); | 89 DCHECK(!HasIllegalRedeclaration()); |
90 } | 90 } |
91 | 91 |
92 | 92 |
93 Scope::Scope(Scope* inner_scope, | 93 Scope::Scope(Scope* inner_scope, |
94 ScopeType scope_type, | 94 ScopeType scope_type, |
95 Handle<ScopeInfo> scope_info, | 95 Handle<ScopeInfo> scope_info, |
96 AstValueFactory* value_factory, | 96 AstValueFactory* value_factory, |
97 Zone* zone) | 97 Zone* zone) |
98 : isolate_(zone->isolate()), | 98 : isolate_(zone->isolate()), |
99 inner_scopes_(4, zone), | 99 inner_scopes_(4, zone), |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 global_scope->ast_value_factory_, | 223 global_scope->ast_value_factory_, |
224 zone); | 224 zone); |
225 } else if (context->IsBlockContext()) { | 225 } else if (context->IsBlockContext()) { |
226 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 226 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); |
227 current_scope = new(zone) Scope(current_scope, | 227 current_scope = new(zone) Scope(current_scope, |
228 BLOCK_SCOPE, | 228 BLOCK_SCOPE, |
229 Handle<ScopeInfo>(scope_info), | 229 Handle<ScopeInfo>(scope_info), |
230 global_scope->ast_value_factory_, | 230 global_scope->ast_value_factory_, |
231 zone); | 231 zone); |
232 } else { | 232 } else { |
233 ASSERT(context->IsCatchContext()); | 233 DCHECK(context->IsCatchContext()); |
234 String* name = String::cast(context->extension()); | 234 String* name = String::cast(context->extension()); |
235 current_scope = new (zone) Scope( | 235 current_scope = new (zone) Scope( |
236 current_scope, | 236 current_scope, |
237 global_scope->ast_value_factory_->GetString(Handle<String>(name)), | 237 global_scope->ast_value_factory_->GetString(Handle<String>(name)), |
238 global_scope->ast_value_factory_, zone); | 238 global_scope->ast_value_factory_, zone); |
239 } | 239 } |
240 if (contains_with) current_scope->RecordWithStatement(); | 240 if (contains_with) current_scope->RecordWithStatement(); |
241 if (innermost_scope == NULL) innermost_scope = current_scope; | 241 if (innermost_scope == NULL) innermost_scope = current_scope; |
242 | 242 |
243 // Forget about a with when we move to a context for a different function. | 243 // Forget about a with when we move to a context for a different function. |
244 if (context->previous()->closure() != context->closure()) { | 244 if (context->previous()->closure() != context->closure()) { |
245 contains_with = false; | 245 contains_with = false; |
246 } | 246 } |
247 context = context->previous(); | 247 context = context->previous(); |
248 } | 248 } |
249 | 249 |
250 global_scope->AddInnerScope(current_scope); | 250 global_scope->AddInnerScope(current_scope); |
251 global_scope->PropagateScopeInfo(false); | 251 global_scope->PropagateScopeInfo(false); |
252 return (innermost_scope == NULL) ? global_scope : innermost_scope; | 252 return (innermost_scope == NULL) ? global_scope : innermost_scope; |
253 } | 253 } |
254 | 254 |
255 | 255 |
256 bool Scope::Analyze(CompilationInfo* info) { | 256 bool Scope::Analyze(CompilationInfo* info) { |
257 ASSERT(info->function() != NULL); | 257 DCHECK(info->function() != NULL); |
258 Scope* scope = info->function()->scope(); | 258 Scope* scope = info->function()->scope(); |
259 Scope* top = scope; | 259 Scope* top = scope; |
260 | 260 |
261 // Traverse the scope tree up to the first unresolved scope or the global | 261 // Traverse the scope tree up to the first unresolved scope or the global |
262 // scope and start scope resolution and variable allocation from that scope. | 262 // scope and start scope resolution and variable allocation from that scope. |
263 while (!top->is_global_scope() && | 263 while (!top->is_global_scope() && |
264 !top->outer_scope()->already_resolved()) { | 264 !top->outer_scope()->already_resolved()) { |
265 top = top->outer_scope(); | 265 top = top->outer_scope(); |
266 } | 266 } |
267 | 267 |
(...skipping 17 matching lines...) Expand all Loading... |
285 top->interface()->Print(); | 285 top->interface()->Print(); |
286 } | 286 } |
287 #endif | 287 #endif |
288 | 288 |
289 info->PrepareForCompilation(scope); | 289 info->PrepareForCompilation(scope); |
290 return true; | 290 return true; |
291 } | 291 } |
292 | 292 |
293 | 293 |
294 void Scope::Initialize() { | 294 void Scope::Initialize() { |
295 ASSERT(!already_resolved()); | 295 DCHECK(!already_resolved()); |
296 | 296 |
297 // Add this scope as a new inner scope of the outer scope. | 297 // Add this scope as a new inner scope of the outer scope. |
298 if (outer_scope_ != NULL) { | 298 if (outer_scope_ != NULL) { |
299 outer_scope_->inner_scopes_.Add(this, zone()); | 299 outer_scope_->inner_scopes_.Add(this, zone()); |
300 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | 300 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); |
301 } else { | 301 } else { |
302 scope_inside_with_ = is_with_scope(); | 302 scope_inside_with_ = is_with_scope(); |
303 } | 303 } |
304 | 304 |
305 // Declare convenience variables. | 305 // Declare convenience variables. |
306 // Declare and allocate receiver (even for the global scope, and even | 306 // Declare and allocate receiver (even for the global scope, and even |
307 // if naccesses_ == 0). | 307 // if naccesses_ == 0). |
308 // NOTE: When loading parameters in the global scope, we must take | 308 // NOTE: When loading parameters in the global scope, we must take |
309 // care not to access them as properties of the global object, but | 309 // care not to access them as properties of the global object, but |
310 // instead load them directly from the stack. Currently, the only | 310 // instead load them directly from the stack. Currently, the only |
311 // such parameter is 'this' which is passed on the stack when | 311 // such parameter is 'this' which is passed on the stack when |
312 // invoking scripts | 312 // invoking scripts |
313 if (is_declaration_scope()) { | 313 if (is_declaration_scope()) { |
314 Variable* var = | 314 Variable* var = |
315 variables_.Declare(this, | 315 variables_.Declare(this, |
316 ast_value_factory_->this_string(), | 316 ast_value_factory_->this_string(), |
317 VAR, | 317 VAR, |
318 false, | 318 false, |
319 Variable::THIS, | 319 Variable::THIS, |
320 kCreatedInitialized); | 320 kCreatedInitialized); |
321 var->AllocateTo(Variable::PARAMETER, -1); | 321 var->AllocateTo(Variable::PARAMETER, -1); |
322 receiver_ = var; | 322 receiver_ = var; |
323 } else { | 323 } else { |
324 ASSERT(outer_scope() != NULL); | 324 DCHECK(outer_scope() != NULL); |
325 receiver_ = outer_scope()->receiver(); | 325 receiver_ = outer_scope()->receiver(); |
326 } | 326 } |
327 | 327 |
328 if (is_function_scope()) { | 328 if (is_function_scope()) { |
329 // Declare 'arguments' variable which exists in all functions. | 329 // Declare 'arguments' variable which exists in all functions. |
330 // Note that it might never be accessed, in which case it won't be | 330 // Note that it might never be accessed, in which case it won't be |
331 // allocated during variable allocation. | 331 // allocated during variable allocation. |
332 variables_.Declare(this, | 332 variables_.Declare(this, |
333 ast_value_factory_->arguments_string(), | 333 ast_value_factory_->arguments_string(), |
334 VAR, | 334 VAR, |
335 true, | 335 true, |
336 Variable::ARGUMENTS, | 336 Variable::ARGUMENTS, |
337 kCreatedInitialized); | 337 kCreatedInitialized); |
338 } | 338 } |
339 } | 339 } |
340 | 340 |
341 | 341 |
342 Scope* Scope::FinalizeBlockScope() { | 342 Scope* Scope::FinalizeBlockScope() { |
343 ASSERT(is_block_scope()); | 343 DCHECK(is_block_scope()); |
344 ASSERT(internals_.is_empty()); | 344 DCHECK(internals_.is_empty()); |
345 ASSERT(temps_.is_empty()); | 345 DCHECK(temps_.is_empty()); |
346 ASSERT(params_.is_empty()); | 346 DCHECK(params_.is_empty()); |
347 | 347 |
348 if (num_var_or_const() > 0) return this; | 348 if (num_var_or_const() > 0) return this; |
349 | 349 |
350 // Remove this scope from outer scope. | 350 // Remove this scope from outer scope. |
351 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { | 351 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { |
352 if (outer_scope_->inner_scopes_[i] == this) { | 352 if (outer_scope_->inner_scopes_[i] == this) { |
353 outer_scope_->inner_scopes_.Remove(i); | 353 outer_scope_->inner_scopes_.Remove(i); |
354 break; | 354 break; |
355 } | 355 } |
356 } | 356 } |
(...skipping 16 matching lines...) Expand all Loading... |
373 Variable* result = variables_.Lookup(name); | 373 Variable* result = variables_.Lookup(name); |
374 if (result != NULL || scope_info_.is_null()) { | 374 if (result != NULL || scope_info_.is_null()) { |
375 return result; | 375 return result; |
376 } | 376 } |
377 // The Scope is backed up by ScopeInfo. This means it cannot operate in a | 377 // The Scope is backed up by ScopeInfo. This means it cannot operate in a |
378 // heap-independent mode, and all strings must be internalized immediately. So | 378 // heap-independent mode, and all strings must be internalized immediately. So |
379 // it's ok to get the Handle<String> here. | 379 // it's ok to get the Handle<String> here. |
380 Handle<String> name_handle = name->string(); | 380 Handle<String> name_handle = name->string(); |
381 // If we have a serialized scope info, we might find the variable there. | 381 // If we have a serialized scope info, we might find the variable there. |
382 // There should be no local slot with the given name. | 382 // There should be no local slot with the given name. |
383 ASSERT(scope_info_->StackSlotIndex(*name_handle) < 0); | 383 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0); |
384 | 384 |
385 // Check context slot lookup. | 385 // Check context slot lookup. |
386 VariableMode mode; | 386 VariableMode mode; |
387 Variable::Location location = Variable::CONTEXT; | 387 Variable::Location location = Variable::CONTEXT; |
388 InitializationFlag init_flag; | 388 InitializationFlag init_flag; |
389 MaybeAssignedFlag maybe_assigned_flag; | 389 MaybeAssignedFlag maybe_assigned_flag; |
390 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, | 390 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, |
391 &init_flag, &maybe_assigned_flag); | 391 &init_flag, &maybe_assigned_flag); |
392 if (index < 0) { | 392 if (index < 0) { |
393 // Check parameters. | 393 // Check parameters. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 scope != NULL; | 439 scope != NULL; |
440 scope = scope->outer_scope()) { | 440 scope = scope->outer_scope()) { |
441 Variable* var = scope->LookupLocal(name); | 441 Variable* var = scope->LookupLocal(name); |
442 if (var != NULL) return var; | 442 if (var != NULL) return var; |
443 } | 443 } |
444 return NULL; | 444 return NULL; |
445 } | 445 } |
446 | 446 |
447 | 447 |
448 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode) { | 448 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode) { |
449 ASSERT(!already_resolved()); | 449 DCHECK(!already_resolved()); |
450 ASSERT(is_function_scope()); | 450 DCHECK(is_function_scope()); |
451 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, | 451 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, |
452 kCreatedInitialized); | 452 kCreatedInitialized); |
453 params_.Add(var, zone()); | 453 params_.Add(var, zone()); |
454 return var; | 454 return var; |
455 } | 455 } |
456 | 456 |
457 | 457 |
458 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, | 458 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, |
459 InitializationFlag init_flag, | 459 InitializationFlag init_flag, |
460 MaybeAssignedFlag maybe_assigned_flag, | 460 MaybeAssignedFlag maybe_assigned_flag, |
461 Interface* interface) { | 461 Interface* interface) { |
462 ASSERT(!already_resolved()); | 462 DCHECK(!already_resolved()); |
463 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 463 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
464 // introduces during variable allocation, INTERNAL variables are allocated | 464 // introduces during variable allocation, INTERNAL variables are allocated |
465 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). | 465 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). |
466 ASSERT(IsDeclaredVariableMode(mode)); | 466 DCHECK(IsDeclaredVariableMode(mode)); |
467 ++num_var_or_const_; | 467 ++num_var_or_const_; |
468 return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag, | 468 return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag, |
469 maybe_assigned_flag, interface); | 469 maybe_assigned_flag, interface); |
470 } | 470 } |
471 | 471 |
472 | 472 |
473 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { | 473 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { |
474 ASSERT(is_global_scope()); | 474 DCHECK(is_global_scope()); |
475 return variables_.Declare(this, | 475 return variables_.Declare(this, |
476 name, | 476 name, |
477 DYNAMIC_GLOBAL, | 477 DYNAMIC_GLOBAL, |
478 true, | 478 true, |
479 Variable::NORMAL, | 479 Variable::NORMAL, |
480 kCreatedInitialized); | 480 kCreatedInitialized); |
481 } | 481 } |
482 | 482 |
483 | 483 |
484 void Scope::RemoveUnresolved(VariableProxy* var) { | 484 void Scope::RemoveUnresolved(VariableProxy* var) { |
485 // Most likely (always?) any variable we want to remove | 485 // Most likely (always?) any variable we want to remove |
486 // was just added before, so we search backwards. | 486 // was just added before, so we search backwards. |
487 for (int i = unresolved_.length(); i-- > 0;) { | 487 for (int i = unresolved_.length(); i-- > 0;) { |
488 if (unresolved_[i] == var) { | 488 if (unresolved_[i] == var) { |
489 unresolved_.Remove(i); | 489 unresolved_.Remove(i); |
490 return; | 490 return; |
491 } | 491 } |
492 } | 492 } |
493 } | 493 } |
494 | 494 |
495 | 495 |
496 Variable* Scope::NewInternal(const AstRawString* name) { | 496 Variable* Scope::NewInternal(const AstRawString* name) { |
497 ASSERT(!already_resolved()); | 497 DCHECK(!already_resolved()); |
498 Variable* var = new(zone()) Variable(this, | 498 Variable* var = new(zone()) Variable(this, |
499 name, | 499 name, |
500 INTERNAL, | 500 INTERNAL, |
501 false, | 501 false, |
502 Variable::NORMAL, | 502 Variable::NORMAL, |
503 kCreatedInitialized); | 503 kCreatedInitialized); |
504 internals_.Add(var, zone()); | 504 internals_.Add(var, zone()); |
505 return var; | 505 return var; |
506 } | 506 } |
507 | 507 |
508 | 508 |
509 Variable* Scope::NewTemporary(const AstRawString* name) { | 509 Variable* Scope::NewTemporary(const AstRawString* name) { |
510 ASSERT(!already_resolved()); | 510 DCHECK(!already_resolved()); |
511 Variable* var = new(zone()) Variable(this, | 511 Variable* var = new(zone()) Variable(this, |
512 name, | 512 name, |
513 TEMPORARY, | 513 TEMPORARY, |
514 true, | 514 true, |
515 Variable::NORMAL, | 515 Variable::NORMAL, |
516 kCreatedInitialized); | 516 kCreatedInitialized); |
517 temps_.Add(var, zone()); | 517 temps_.Add(var, zone()); |
518 return var; | 518 return var; |
519 } | 519 } |
520 | 520 |
521 | 521 |
522 void Scope::AddDeclaration(Declaration* declaration) { | 522 void Scope::AddDeclaration(Declaration* declaration) { |
523 decls_.Add(declaration, zone()); | 523 decls_.Add(declaration, zone()); |
524 } | 524 } |
525 | 525 |
526 | 526 |
527 void Scope::SetIllegalRedeclaration(Expression* expression) { | 527 void Scope::SetIllegalRedeclaration(Expression* expression) { |
528 // Record only the first illegal redeclaration. | 528 // Record only the first illegal redeclaration. |
529 if (!HasIllegalRedeclaration()) { | 529 if (!HasIllegalRedeclaration()) { |
530 illegal_redecl_ = expression; | 530 illegal_redecl_ = expression; |
531 } | 531 } |
532 ASSERT(HasIllegalRedeclaration()); | 532 DCHECK(HasIllegalRedeclaration()); |
533 } | 533 } |
534 | 534 |
535 | 535 |
536 void Scope::VisitIllegalRedeclaration(AstVisitor* visitor) { | 536 void Scope::VisitIllegalRedeclaration(AstVisitor* visitor) { |
537 ASSERT(HasIllegalRedeclaration()); | 537 DCHECK(HasIllegalRedeclaration()); |
538 illegal_redecl_->Accept(visitor); | 538 illegal_redecl_->Accept(visitor); |
539 } | 539 } |
540 | 540 |
541 | 541 |
542 Declaration* Scope::CheckConflictingVarDeclarations() { | 542 Declaration* Scope::CheckConflictingVarDeclarations() { |
543 int length = decls_.length(); | 543 int length = decls_.length(); |
544 for (int i = 0; i < length; i++) { | 544 for (int i = 0; i < length; i++) { |
545 Declaration* decl = decls_[i]; | 545 Declaration* decl = decls_[i]; |
546 if (decl->mode() != VAR) continue; | 546 if (decl->mode() != VAR) continue; |
547 const AstRawString* name = decl->proxy()->raw_name(); | 547 const AstRawString* name = decl->proxy()->raw_name(); |
(...skipping 25 matching lines...) Expand all Loading... |
573 } | 573 } |
574 | 574 |
575 private: | 575 private: |
576 Variable* var_; | 576 Variable* var_; |
577 int order_; | 577 int order_; |
578 }; | 578 }; |
579 | 579 |
580 | 580 |
581 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, | 581 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
582 ZoneList<Variable*>* context_locals) { | 582 ZoneList<Variable*>* context_locals) { |
583 ASSERT(stack_locals != NULL); | 583 DCHECK(stack_locals != NULL); |
584 ASSERT(context_locals != NULL); | 584 DCHECK(context_locals != NULL); |
585 | 585 |
586 // Collect internals which are always allocated on the heap. | 586 // Collect internals which are always allocated on the heap. |
587 for (int i = 0; i < internals_.length(); i++) { | 587 for (int i = 0; i < internals_.length(); i++) { |
588 Variable* var = internals_[i]; | 588 Variable* var = internals_[i]; |
589 if (var->is_used()) { | 589 if (var->is_used()) { |
590 ASSERT(var->IsContextSlot()); | 590 DCHECK(var->IsContextSlot()); |
591 context_locals->Add(var, zone()); | 591 context_locals->Add(var, zone()); |
592 } | 592 } |
593 } | 593 } |
594 | 594 |
595 // Collect temporaries which are always allocated on the stack, unless the | 595 // Collect temporaries which are always allocated on the stack, unless the |
596 // context as a whole has forced context allocation. | 596 // context as a whole has forced context allocation. |
597 for (int i = 0; i < temps_.length(); i++) { | 597 for (int i = 0; i < temps_.length(); i++) { |
598 Variable* var = temps_[i]; | 598 Variable* var = temps_[i]; |
599 if (var->is_used()) { | 599 if (var->is_used()) { |
600 if (var->IsContextSlot()) { | 600 if (var->IsContextSlot()) { |
601 ASSERT(has_forced_context_allocation()); | 601 DCHECK(has_forced_context_allocation()); |
602 context_locals->Add(var, zone()); | 602 context_locals->Add(var, zone()); |
603 } else { | 603 } else { |
604 ASSERT(var->IsStackLocal()); | 604 DCHECK(var->IsStackLocal()); |
605 stack_locals->Add(var, zone()); | 605 stack_locals->Add(var, zone()); |
606 } | 606 } |
607 } | 607 } |
608 } | 608 } |
609 | 609 |
610 // Collect declared local variables. | 610 // Collect declared local variables. |
611 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 611 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
612 for (VariableMap::Entry* p = variables_.Start(); | 612 for (VariableMap::Entry* p = variables_.Start(); |
613 p != NULL; | 613 p != NULL; |
614 p = variables_.Next(p)) { | 614 p = variables_.Next(p)) { |
(...skipping 21 matching lines...) Expand all Loading... |
636 bool outer_scope_calls_sloppy_eval = false; | 636 bool outer_scope_calls_sloppy_eval = false; |
637 if (outer_scope_ != NULL) { | 637 if (outer_scope_ != NULL) { |
638 outer_scope_calls_sloppy_eval = | 638 outer_scope_calls_sloppy_eval = |
639 outer_scope_->outer_scope_calls_sloppy_eval() | | 639 outer_scope_->outer_scope_calls_sloppy_eval() | |
640 outer_scope_->calls_sloppy_eval(); | 640 outer_scope_->calls_sloppy_eval(); |
641 } | 641 } |
642 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 642 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
643 | 643 |
644 // 2) Allocate module instances. | 644 // 2) Allocate module instances. |
645 if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) { | 645 if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) { |
646 ASSERT(num_modules_ == 0); | 646 DCHECK(num_modules_ == 0); |
647 AllocateModulesRecursively(this); | 647 AllocateModulesRecursively(this); |
648 } | 648 } |
649 | 649 |
650 // 3) Resolve variables. | 650 // 3) Resolve variables. |
651 if (!ResolveVariablesRecursively(info, factory)) return false; | 651 if (!ResolveVariablesRecursively(info, factory)) return false; |
652 | 652 |
653 // 4) Allocate variables. | 653 // 4) Allocate variables. |
654 AllocateVariablesRecursively(); | 654 AllocateVariablesRecursively(); |
655 | 655 |
656 return true; | 656 return true; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 | 705 |
706 | 706 |
707 bool Scope::AllowsLazyCompilationWithoutContext() const { | 707 bool Scope::AllowsLazyCompilationWithoutContext() const { |
708 return !force_eager_compilation_ && HasTrivialOuterContext(); | 708 return !force_eager_compilation_ && HasTrivialOuterContext(); |
709 } | 709 } |
710 | 710 |
711 | 711 |
712 int Scope::ContextChainLength(Scope* scope) { | 712 int Scope::ContextChainLength(Scope* scope) { |
713 int n = 0; | 713 int n = 0; |
714 for (Scope* s = this; s != scope; s = s->outer_scope_) { | 714 for (Scope* s = this; s != scope; s = s->outer_scope_) { |
715 ASSERT(s != NULL); // scope must be in the scope chain | 715 DCHECK(s != NULL); // scope must be in the scope chain |
716 if (s->is_with_scope() || s->num_heap_slots() > 0) n++; | 716 if (s->is_with_scope() || s->num_heap_slots() > 0) n++; |
717 // Catch and module scopes always have heap slots. | 717 // Catch and module scopes always have heap slots. |
718 ASSERT(!s->is_catch_scope() || s->num_heap_slots() > 0); | 718 DCHECK(!s->is_catch_scope() || s->num_heap_slots() > 0); |
719 ASSERT(!s->is_module_scope() || s->num_heap_slots() > 0); | 719 DCHECK(!s->is_module_scope() || s->num_heap_slots() > 0); |
720 } | 720 } |
721 return n; | 721 return n; |
722 } | 722 } |
723 | 723 |
724 | 724 |
725 Scope* Scope::GlobalScope() { | 725 Scope* Scope::GlobalScope() { |
726 Scope* scope = this; | 726 Scope* scope = this; |
727 while (!scope->is_global_scope()) { | 727 while (!scope->is_global_scope()) { |
728 scope = scope->outer_scope(); | 728 scope = scope->outer_scope(); |
729 } | 729 } |
(...skipping 20 matching lines...) Expand all Loading... |
750 | 750 |
751 void Scope::GetNestedScopeChain( | 751 void Scope::GetNestedScopeChain( |
752 List<Handle<ScopeInfo> >* chain, | 752 List<Handle<ScopeInfo> >* chain, |
753 int position) { | 753 int position) { |
754 if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo())); | 754 if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo())); |
755 | 755 |
756 for (int i = 0; i < inner_scopes_.length(); i++) { | 756 for (int i = 0; i < inner_scopes_.length(); i++) { |
757 Scope* scope = inner_scopes_[i]; | 757 Scope* scope = inner_scopes_[i]; |
758 int beg_pos = scope->start_position(); | 758 int beg_pos = scope->start_position(); |
759 int end_pos = scope->end_position(); | 759 int end_pos = scope->end_position(); |
760 ASSERT(beg_pos >= 0 && end_pos >= 0); | 760 DCHECK(beg_pos >= 0 && end_pos >= 0); |
761 if (beg_pos <= position && position < end_pos) { | 761 if (beg_pos <= position && position < end_pos) { |
762 scope->GetNestedScopeChain(chain, position); | 762 scope->GetNestedScopeChain(chain, position); |
763 return; | 763 return; |
764 } | 764 } |
765 } | 765 } |
766 } | 766 } |
767 | 767 |
768 | 768 |
769 #ifdef DEBUG | 769 #ifdef DEBUG |
770 static const char* Header(ScopeType scope_type) { | 770 static const char* Header(ScopeType scope_type) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 // Allocate it by giving it a dynamic lookup. | 953 // Allocate it by giving it a dynamic lookup. |
954 var->AllocateTo(Variable::LOOKUP, -1); | 954 var->AllocateTo(Variable::LOOKUP, -1); |
955 } | 955 } |
956 return var; | 956 return var; |
957 } | 957 } |
958 | 958 |
959 | 959 |
960 Variable* Scope::LookupRecursive(VariableProxy* proxy, | 960 Variable* Scope::LookupRecursive(VariableProxy* proxy, |
961 BindingKind* binding_kind, | 961 BindingKind* binding_kind, |
962 AstNodeFactory<AstNullVisitor>* factory) { | 962 AstNodeFactory<AstNullVisitor>* factory) { |
963 ASSERT(binding_kind != NULL); | 963 DCHECK(binding_kind != NULL); |
964 if (already_resolved() && is_with_scope()) { | 964 if (already_resolved() && is_with_scope()) { |
965 // Short-cut: if the scope is deserialized from a scope info, variable | 965 // Short-cut: if the scope is deserialized from a scope info, variable |
966 // allocation is already fixed. We can simply return with dynamic lookup. | 966 // allocation is already fixed. We can simply return with dynamic lookup. |
967 *binding_kind = DYNAMIC_LOOKUP; | 967 *binding_kind = DYNAMIC_LOOKUP; |
968 return NULL; | 968 return NULL; |
969 } | 969 } |
970 | 970 |
971 // Try to find the variable in this scope. | 971 // Try to find the variable in this scope. |
972 Variable* var = LookupLocal(proxy->raw_name()); | 972 Variable* var = LookupLocal(proxy->raw_name()); |
973 | 973 |
(...skipping 11 matching lines...) Expand all Loading... |
985 *binding_kind = UNBOUND; | 985 *binding_kind = UNBOUND; |
986 var = LookupFunctionVar(proxy->raw_name(), factory); | 986 var = LookupFunctionVar(proxy->raw_name(), factory); |
987 if (var != NULL) { | 987 if (var != NULL) { |
988 *binding_kind = BOUND; | 988 *binding_kind = BOUND; |
989 } else if (outer_scope_ != NULL) { | 989 } else if (outer_scope_ != NULL) { |
990 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory); | 990 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory); |
991 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 991 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { |
992 var->ForceContextAllocation(); | 992 var->ForceContextAllocation(); |
993 } | 993 } |
994 } else { | 994 } else { |
995 ASSERT(is_global_scope()); | 995 DCHECK(is_global_scope()); |
996 } | 996 } |
997 | 997 |
998 if (is_with_scope()) { | 998 if (is_with_scope()) { |
999 ASSERT(!already_resolved()); | 999 DCHECK(!already_resolved()); |
1000 // The current scope is a with scope, so the variable binding can not be | 1000 // The current scope is a with scope, so the variable binding can not be |
1001 // statically resolved. However, note that it was necessary to do a lookup | 1001 // statically resolved. However, note that it was necessary to do a lookup |
1002 // in the outer scope anyway, because if a binding exists in an outer scope, | 1002 // in the outer scope anyway, because if a binding exists in an outer scope, |
1003 // the associated variable has to be marked as potentially being accessed | 1003 // the associated variable has to be marked as potentially being accessed |
1004 // from inside of an inner with scope (the property may not be in the 'with' | 1004 // from inside of an inner with scope (the property may not be in the 'with' |
1005 // object). | 1005 // object). |
1006 if (var != NULL && proxy->is_assigned()) var->set_maybe_assigned(); | 1006 if (var != NULL && proxy->is_assigned()) var->set_maybe_assigned(); |
1007 *binding_kind = DYNAMIC_LOOKUP; | 1007 *binding_kind = DYNAMIC_LOOKUP; |
1008 return NULL; | 1008 return NULL; |
1009 } else if (calls_sloppy_eval()) { | 1009 } else if (calls_sloppy_eval()) { |
1010 // A variable binding may have been found in an outer scope, but the current | 1010 // A variable binding may have been found in an outer scope, but the current |
1011 // scope makes a sloppy 'eval' call, so the found variable may not be | 1011 // scope makes a sloppy 'eval' call, so the found variable may not be |
1012 // the correct one (the 'eval' may introduce a binding with the same name). | 1012 // the correct one (the 'eval' may introduce a binding with the same name). |
1013 // In that case, change the lookup result to reflect this situation. | 1013 // In that case, change the lookup result to reflect this situation. |
1014 if (*binding_kind == BOUND) { | 1014 if (*binding_kind == BOUND) { |
1015 *binding_kind = BOUND_EVAL_SHADOWED; | 1015 *binding_kind = BOUND_EVAL_SHADOWED; |
1016 } else if (*binding_kind == UNBOUND) { | 1016 } else if (*binding_kind == UNBOUND) { |
1017 *binding_kind = UNBOUND_EVAL_SHADOWED; | 1017 *binding_kind = UNBOUND_EVAL_SHADOWED; |
1018 } | 1018 } |
1019 } | 1019 } |
1020 return var; | 1020 return var; |
1021 } | 1021 } |
1022 | 1022 |
1023 | 1023 |
1024 bool Scope::ResolveVariable(CompilationInfo* info, | 1024 bool Scope::ResolveVariable(CompilationInfo* info, |
1025 VariableProxy* proxy, | 1025 VariableProxy* proxy, |
1026 AstNodeFactory<AstNullVisitor>* factory) { | 1026 AstNodeFactory<AstNullVisitor>* factory) { |
1027 ASSERT(info->global_scope()->is_global_scope()); | 1027 DCHECK(info->global_scope()->is_global_scope()); |
1028 | 1028 |
1029 // If the proxy is already resolved there's nothing to do | 1029 // If the proxy is already resolved there's nothing to do |
1030 // (functions and consts may be resolved by the parser). | 1030 // (functions and consts may be resolved by the parser). |
1031 if (proxy->var() != NULL) return true; | 1031 if (proxy->var() != NULL) return true; |
1032 | 1032 |
1033 // Otherwise, try to resolve the variable. | 1033 // Otherwise, try to resolve the variable. |
1034 BindingKind binding_kind; | 1034 BindingKind binding_kind; |
1035 Variable* var = LookupRecursive(proxy, &binding_kind, factory); | 1035 Variable* var = LookupRecursive(proxy, &binding_kind, factory); |
1036 switch (binding_kind) { | 1036 switch (binding_kind) { |
1037 case BOUND: | 1037 case BOUND: |
(...skipping 25 matching lines...) Expand all Loading... |
1063 // No binding has been found. But some scope makes a sloppy 'eval' call. | 1063 // No binding has been found. But some scope makes a sloppy 'eval' call. |
1064 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); | 1064 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
1065 break; | 1065 break; |
1066 | 1066 |
1067 case DYNAMIC_LOOKUP: | 1067 case DYNAMIC_LOOKUP: |
1068 // The variable could not be resolved statically. | 1068 // The variable could not be resolved statically. |
1069 var = NonLocal(proxy->raw_name(), DYNAMIC); | 1069 var = NonLocal(proxy->raw_name(), DYNAMIC); |
1070 break; | 1070 break; |
1071 } | 1071 } |
1072 | 1072 |
1073 ASSERT(var != NULL); | 1073 DCHECK(var != NULL); |
1074 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1074 if (proxy->is_assigned()) var->set_maybe_assigned(); |
1075 | 1075 |
1076 if (FLAG_harmony_scoping && strict_mode() == STRICT && | 1076 if (FLAG_harmony_scoping && strict_mode() == STRICT && |
1077 var->is_const_mode() && proxy->is_assigned()) { | 1077 var->is_const_mode() && proxy->is_assigned()) { |
1078 // Assignment to const. Throw a syntax error. | 1078 // Assignment to const. Throw a syntax error. |
1079 MessageLocation location( | 1079 MessageLocation location( |
1080 info->script(), proxy->position(), proxy->position()); | 1080 info->script(), proxy->position(), proxy->position()); |
1081 Isolate* isolate = info->isolate(); | 1081 Isolate* isolate = info->isolate(); |
1082 Factory* factory = isolate->factory(); | 1082 Factory* factory = isolate->factory(); |
1083 Handle<JSArray> array = factory->NewJSArray(0); | 1083 Handle<JSArray> array = factory->NewJSArray(0); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 | 1124 |
1125 proxy->BindTo(var); | 1125 proxy->BindTo(var); |
1126 | 1126 |
1127 return true; | 1127 return true; |
1128 } | 1128 } |
1129 | 1129 |
1130 | 1130 |
1131 bool Scope::ResolveVariablesRecursively( | 1131 bool Scope::ResolveVariablesRecursively( |
1132 CompilationInfo* info, | 1132 CompilationInfo* info, |
1133 AstNodeFactory<AstNullVisitor>* factory) { | 1133 AstNodeFactory<AstNullVisitor>* factory) { |
1134 ASSERT(info->global_scope()->is_global_scope()); | 1134 DCHECK(info->global_scope()->is_global_scope()); |
1135 | 1135 |
1136 // Resolve unresolved variables for this scope. | 1136 // Resolve unresolved variables for this scope. |
1137 for (int i = 0; i < unresolved_.length(); i++) { | 1137 for (int i = 0; i < unresolved_.length(); i++) { |
1138 if (!ResolveVariable(info, unresolved_[i], factory)) return false; | 1138 if (!ResolveVariable(info, unresolved_[i], factory)) return false; |
1139 } | 1139 } |
1140 | 1140 |
1141 // Resolve unresolved variables for inner scopes. | 1141 // Resolve unresolved variables for inner scopes. |
1142 for (int i = 0; i < inner_scopes_.length(); i++) { | 1142 for (int i = 0; i < inner_scopes_.length(); i++) { |
1143 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) | 1143 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) |
1144 return false; | 1144 return false; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 var->AllocateTo(Variable::LOCAL, num_stack_slots_++); | 1226 var->AllocateTo(Variable::LOCAL, num_stack_slots_++); |
1227 } | 1227 } |
1228 | 1228 |
1229 | 1229 |
1230 void Scope::AllocateHeapSlot(Variable* var) { | 1230 void Scope::AllocateHeapSlot(Variable* var) { |
1231 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); | 1231 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); |
1232 } | 1232 } |
1233 | 1233 |
1234 | 1234 |
1235 void Scope::AllocateParameterLocals() { | 1235 void Scope::AllocateParameterLocals() { |
1236 ASSERT(is_function_scope()); | 1236 DCHECK(is_function_scope()); |
1237 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string()); | 1237 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string()); |
1238 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly | 1238 DCHECK(arguments != NULL); // functions have 'arguments' declared implicitly |
1239 | 1239 |
1240 bool uses_sloppy_arguments = false; | 1240 bool uses_sloppy_arguments = false; |
1241 | 1241 |
1242 if (MustAllocate(arguments) && !HasArgumentsParameter()) { | 1242 if (MustAllocate(arguments) && !HasArgumentsParameter()) { |
1243 // 'arguments' is used. Unless there is also a parameter called | 1243 // 'arguments' is used. Unless there is also a parameter called |
1244 // 'arguments', we must be conservative and allocate all parameters to | 1244 // 'arguments', we must be conservative and allocate all parameters to |
1245 // the context assuming they will be captured by the arguments object. | 1245 // the context assuming they will be captured by the arguments object. |
1246 // If we have a parameter named 'arguments', a (new) value is always | 1246 // If we have a parameter named 'arguments', a (new) value is always |
1247 // assigned to it via the function invocation. Then 'arguments' denotes | 1247 // assigned to it via the function invocation. Then 'arguments' denotes |
1248 // that specific parameter value and cannot be used to access the | 1248 // that specific parameter value and cannot be used to access the |
1249 // parameters, which is why we don't need to allocate an arguments | 1249 // parameters, which is why we don't need to allocate an arguments |
1250 // object in that case. | 1250 // object in that case. |
1251 | 1251 |
1252 // We are using 'arguments'. Tell the code generator that is needs to | 1252 // We are using 'arguments'. Tell the code generator that is needs to |
1253 // allocate the arguments object by setting 'arguments_'. | 1253 // allocate the arguments object by setting 'arguments_'. |
1254 arguments_ = arguments; | 1254 arguments_ = arguments; |
1255 | 1255 |
1256 // In strict mode 'arguments' does not alias formal parameters. | 1256 // In strict mode 'arguments' does not alias formal parameters. |
1257 // Therefore in strict mode we allocate parameters as if 'arguments' | 1257 // Therefore in strict mode we allocate parameters as if 'arguments' |
1258 // were not used. | 1258 // were not used. |
1259 uses_sloppy_arguments = strict_mode() == SLOPPY; | 1259 uses_sloppy_arguments = strict_mode() == SLOPPY; |
1260 } | 1260 } |
1261 | 1261 |
1262 // The same parameter may occur multiple times in the parameters_ list. | 1262 // The same parameter may occur multiple times in the parameters_ list. |
1263 // If it does, and if it is not copied into the context object, it must | 1263 // If it does, and if it is not copied into the context object, it must |
1264 // receive the highest parameter index for that parameter; thus iteration | 1264 // receive the highest parameter index for that parameter; thus iteration |
1265 // order is relevant! | 1265 // order is relevant! |
1266 for (int i = params_.length() - 1; i >= 0; --i) { | 1266 for (int i = params_.length() - 1; i >= 0; --i) { |
1267 Variable* var = params_[i]; | 1267 Variable* var = params_[i]; |
1268 ASSERT(var->scope() == this); | 1268 DCHECK(var->scope() == this); |
1269 if (uses_sloppy_arguments || has_forced_context_allocation()) { | 1269 if (uses_sloppy_arguments || has_forced_context_allocation()) { |
1270 // Force context allocation of the parameter. | 1270 // Force context allocation of the parameter. |
1271 var->ForceContextAllocation(); | 1271 var->ForceContextAllocation(); |
1272 } | 1272 } |
1273 | 1273 |
1274 if (MustAllocate(var)) { | 1274 if (MustAllocate(var)) { |
1275 if (MustAllocateInContext(var)) { | 1275 if (MustAllocateInContext(var)) { |
1276 ASSERT(var->IsUnallocated() || var->IsContextSlot()); | 1276 DCHECK(var->IsUnallocated() || var->IsContextSlot()); |
1277 if (var->IsUnallocated()) { | 1277 if (var->IsUnallocated()) { |
1278 AllocateHeapSlot(var); | 1278 AllocateHeapSlot(var); |
1279 } | 1279 } |
1280 } else { | 1280 } else { |
1281 ASSERT(var->IsUnallocated() || var->IsParameter()); | 1281 DCHECK(var->IsUnallocated() || var->IsParameter()); |
1282 if (var->IsUnallocated()) { | 1282 if (var->IsUnallocated()) { |
1283 var->AllocateTo(Variable::PARAMETER, i); | 1283 var->AllocateTo(Variable::PARAMETER, i); |
1284 } | 1284 } |
1285 } | 1285 } |
1286 } | 1286 } |
1287 } | 1287 } |
1288 } | 1288 } |
1289 | 1289 |
1290 | 1290 |
1291 void Scope::AllocateNonParameterLocal(Variable* var) { | 1291 void Scope::AllocateNonParameterLocal(Variable* var) { |
1292 ASSERT(var->scope() == this); | 1292 DCHECK(var->scope() == this); |
1293 ASSERT(!var->IsVariable(isolate_->factory()->dot_result_string()) || | 1293 DCHECK(!var->IsVariable(isolate_->factory()->dot_result_string()) || |
1294 !var->IsStackLocal()); | 1294 !var->IsStackLocal()); |
1295 if (var->IsUnallocated() && MustAllocate(var)) { | 1295 if (var->IsUnallocated() && MustAllocate(var)) { |
1296 if (MustAllocateInContext(var)) { | 1296 if (MustAllocateInContext(var)) { |
1297 AllocateHeapSlot(var); | 1297 AllocateHeapSlot(var); |
1298 } else { | 1298 } else { |
1299 AllocateStackSlot(var); | 1299 AllocateStackSlot(var); |
1300 } | 1300 } |
1301 } | 1301 } |
1302 } | 1302 } |
1303 | 1303 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 bool must_have_context = is_with_scope() || is_module_scope() || | 1360 bool must_have_context = is_with_scope() || is_module_scope() || |
1361 (is_function_scope() && calls_eval()); | 1361 (is_function_scope() && calls_eval()); |
1362 | 1362 |
1363 // If we didn't allocate any locals in the local context, then we only | 1363 // If we didn't allocate any locals in the local context, then we only |
1364 // need the minimal number of slots if we must have a context. | 1364 // need the minimal number of slots if we must have a context. |
1365 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1365 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
1366 num_heap_slots_ = 0; | 1366 num_heap_slots_ = 0; |
1367 } | 1367 } |
1368 | 1368 |
1369 // Allocation done. | 1369 // Allocation done. |
1370 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1370 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1371 } | 1371 } |
1372 | 1372 |
1373 | 1373 |
1374 void Scope::AllocateModulesRecursively(Scope* host_scope) { | 1374 void Scope::AllocateModulesRecursively(Scope* host_scope) { |
1375 if (already_resolved()) return; | 1375 if (already_resolved()) return; |
1376 if (is_module_scope()) { | 1376 if (is_module_scope()) { |
1377 ASSERT(interface_->IsFrozen()); | 1377 DCHECK(interface_->IsFrozen()); |
1378 ASSERT(module_var_ == NULL); | 1378 DCHECK(module_var_ == NULL); |
1379 module_var_ = | 1379 module_var_ = |
1380 host_scope->NewInternal(ast_value_factory_->dot_module_string()); | 1380 host_scope->NewInternal(ast_value_factory_->dot_module_string()); |
1381 ++host_scope->num_modules_; | 1381 ++host_scope->num_modules_; |
1382 } | 1382 } |
1383 | 1383 |
1384 for (int i = 0; i < inner_scopes_.length(); i++) { | 1384 for (int i = 0; i < inner_scopes_.length(); i++) { |
1385 Scope* inner_scope = inner_scopes_.at(i); | 1385 Scope* inner_scope = inner_scopes_.at(i); |
1386 inner_scope->AllocateModulesRecursively(host_scope); | 1386 inner_scope->AllocateModulesRecursively(host_scope); |
1387 } | 1387 } |
1388 } | 1388 } |
1389 | 1389 |
1390 | 1390 |
1391 int Scope::StackLocalCount() const { | 1391 int Scope::StackLocalCount() const { |
1392 return num_stack_slots() - | 1392 return num_stack_slots() - |
1393 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1393 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1394 } | 1394 } |
1395 | 1395 |
1396 | 1396 |
1397 int Scope::ContextLocalCount() const { | 1397 int Scope::ContextLocalCount() const { |
1398 if (num_heap_slots() == 0) return 0; | 1398 if (num_heap_slots() == 0) return 0; |
1399 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1399 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1400 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1400 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1401 } | 1401 } |
1402 | 1402 |
1403 } } // namespace v8::internal | 1403 } } // namespace v8::internal |
OLD | NEW |