OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 } | 76 } |
77 | 77 |
78 | 78 |
79 // Dummy constructor | 79 // Dummy constructor |
80 VariableMap::VariableMap(bool gotta_love_static_overloading) : HashMap() {} | 80 VariableMap::VariableMap(bool gotta_love_static_overloading) : HashMap() {} |
81 | 81 |
82 VariableMap::VariableMap() : HashMap(Match, &LocalsMapAllocator, 8) {} | 82 VariableMap::VariableMap() : HashMap(Match, &LocalsMapAllocator, 8) {} |
83 VariableMap::~VariableMap() {} | 83 VariableMap::~VariableMap() {} |
84 | 84 |
85 | 85 |
86 Variable* VariableMap::Declare(Scope* scope, | 86 Variable* VariableMap::Declare( |
87 Handle<String> name, | 87 Scope* scope, |
88 VariableMode mode, | 88 Handle<String> name, |
89 bool is_valid_lhs, | 89 VariableMode mode, |
90 Variable::Kind kind) { | 90 bool is_valid_lhs, |
| 91 Variable::Kind kind, |
| 92 InitializationFlag initialization_flag) { |
91 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true); | 93 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true); |
92 if (p->value == NULL) { | 94 if (p->value == NULL) { |
93 // The variable has not been declared yet -> insert it. | 95 // The variable has not been declared yet -> insert it. |
94 ASSERT(p->key == name.location()); | 96 ASSERT(p->key == name.location()); |
95 p->value = new Variable(scope, name, mode, is_valid_lhs, kind); | 97 p->value = new Variable(scope, |
| 98 name, |
| 99 mode, |
| 100 is_valid_lhs, |
| 101 kind, |
| 102 initialization_flag); |
96 } | 103 } |
97 return reinterpret_cast<Variable*>(p->value); | 104 return reinterpret_cast<Variable*>(p->value); |
98 } | 105 } |
99 | 106 |
100 | 107 |
101 Variable* VariableMap::Lookup(Handle<String> name) { | 108 Variable* VariableMap::Lookup(Handle<String> name) { |
102 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false); | 109 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false); |
103 if (p != NULL) { | 110 if (p != NULL) { |
104 ASSERT(*reinterpret_cast<String**>(p->key) == *name); | 111 ASSERT(*reinterpret_cast<String**>(p->key) == *name); |
105 ASSERT(p->value != NULL); | 112 ASSERT(p->value != NULL); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 unresolved_(0), | 180 unresolved_(0), |
174 decls_(0), | 181 decls_(0), |
175 already_resolved_(true) { | 182 already_resolved_(true) { |
176 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 183 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
177 AddInnerScope(inner_scope); | 184 AddInnerScope(inner_scope); |
178 ++num_var_or_const_; | 185 ++num_var_or_const_; |
179 Variable* variable = variables_.Declare(this, | 186 Variable* variable = variables_.Declare(this, |
180 catch_variable_name, | 187 catch_variable_name, |
181 VAR, | 188 VAR, |
182 true, // Valid left-hand side. | 189 true, // Valid left-hand side. |
183 Variable::NORMAL); | 190 Variable::NORMAL, |
| 191 CREATED_INITIALIZED); |
184 AllocateHeapSlot(variable); | 192 AllocateHeapSlot(variable); |
185 } | 193 } |
186 | 194 |
187 | 195 |
188 void Scope::SetDefaults(ScopeType type, | 196 void Scope::SetDefaults(ScopeType type, |
189 Scope* outer_scope, | 197 Scope* outer_scope, |
190 Handle<ScopeInfo> scope_info) { | 198 Handle<ScopeInfo> scope_info) { |
191 outer_scope_ = outer_scope; | 199 outer_scope_ = outer_scope; |
192 type_ = type; | 200 type_ = type; |
193 scope_name_ = isolate_->factory()->empty_symbol(); | 201 scope_name_ = isolate_->factory()->empty_symbol(); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 // 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 |
302 // instead load them directly from the stack. Currently, the only | 310 // instead load them directly from the stack. Currently, the only |
303 // such parameter is 'this' which is passed on the stack when | 311 // such parameter is 'this' which is passed on the stack when |
304 // invoking scripts | 312 // invoking scripts |
305 if (is_declaration_scope()) { | 313 if (is_declaration_scope()) { |
306 Variable* var = | 314 Variable* var = |
307 variables_.Declare(this, | 315 variables_.Declare(this, |
308 isolate_->factory()->this_symbol(), | 316 isolate_->factory()->this_symbol(), |
309 VAR, | 317 VAR, |
310 false, | 318 false, |
311 Variable::THIS); | 319 Variable::THIS, |
| 320 CREATED_INITIALIZED); |
312 var->AllocateTo(Variable::PARAMETER, -1); | 321 var->AllocateTo(Variable::PARAMETER, -1); |
313 receiver_ = var; | 322 receiver_ = var; |
314 } else { | 323 } else { |
315 ASSERT(outer_scope() != NULL); | 324 ASSERT(outer_scope() != NULL); |
316 receiver_ = outer_scope()->receiver(); | 325 receiver_ = outer_scope()->receiver(); |
317 } | 326 } |
318 | 327 |
319 if (is_function_scope()) { | 328 if (is_function_scope()) { |
320 // Declare 'arguments' variable which exists in all functions. | 329 // Declare 'arguments' variable which exists in all functions. |
321 // 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 |
322 // allocated during variable allocation. | 331 // allocated during variable allocation. |
323 variables_.Declare(this, | 332 variables_.Declare(this, |
324 isolate_->factory()->arguments_symbol(), | 333 isolate_->factory()->arguments_symbol(), |
325 VAR, | 334 VAR, |
326 true, | 335 true, |
327 Variable::ARGUMENTS); | 336 Variable::ARGUMENTS, |
| 337 CREATED_INITIALIZED); |
328 } | 338 } |
329 } | 339 } |
330 | 340 |
331 | 341 |
332 Scope* Scope::FinalizeBlockScope() { | 342 Scope* Scope::FinalizeBlockScope() { |
333 ASSERT(is_block_scope()); | 343 ASSERT(is_block_scope()); |
334 ASSERT(temps_.is_empty()); | 344 ASSERT(temps_.is_empty()); |
335 ASSERT(params_.is_empty()); | 345 ASSERT(params_.is_empty()); |
336 | 346 |
337 if (num_var_or_const() > 0) return this; | 347 if (num_var_or_const() > 0) return this; |
(...skipping 28 matching lines...) Expand all Loading... |
366 // If we have a serialized scope info, we might find the variable there. | 376 // If we have a serialized scope info, we might find the variable there. |
367 // | 377 // |
368 // We should never lookup 'arguments' in this scope as it is implicitly | 378 // We should never lookup 'arguments' in this scope as it is implicitly |
369 // present in every scope. | 379 // present in every scope. |
370 ASSERT(*name != *isolate_->factory()->arguments_symbol()); | 380 ASSERT(*name != *isolate_->factory()->arguments_symbol()); |
371 // There should be no local slot with the given name. | 381 // There should be no local slot with the given name. |
372 ASSERT(scope_info_->StackSlotIndex(*name) < 0); | 382 ASSERT(scope_info_->StackSlotIndex(*name) < 0); |
373 | 383 |
374 // Check context slot lookup. | 384 // Check context slot lookup. |
375 VariableMode mode; | 385 VariableMode mode; |
376 int index = scope_info_->ContextSlotIndex(*name, &mode); | 386 InitializationFlag init_flag; |
| 387 int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag); |
377 if (index < 0) { | 388 if (index < 0) { |
378 // Check parameters. | 389 // Check parameters. |
379 mode = VAR; | 390 mode = VAR; |
| 391 init_flag = CREATED_INITIALIZED; |
380 index = scope_info_->ParameterIndex(*name); | 392 index = scope_info_->ParameterIndex(*name); |
381 if (index < 0) { | 393 if (index < 0) { |
382 // Check the function name. | 394 // Check the function name. |
383 index = scope_info_->FunctionContextSlotIndex(*name, NULL); | 395 index = scope_info_->FunctionContextSlotIndex(*name, &mode); |
384 if (index < 0) return NULL; | 396 if (index < 0) return NULL; |
385 } | 397 } |
386 } | 398 } |
387 | 399 |
388 Variable* var = | 400 Variable* var = |
389 variables_.Declare(this, name, mode, true, Variable::NORMAL); | 401 variables_.Declare(this, |
| 402 name, |
| 403 mode, |
| 404 true, |
| 405 Variable::NORMAL, |
| 406 init_flag); |
390 var->AllocateTo(Variable::CONTEXT, index); | 407 var->AllocateTo(Variable::CONTEXT, index); |
391 return var; | 408 return var; |
392 } | 409 } |
393 | 410 |
394 | 411 |
395 Variable* Scope::Lookup(Handle<String> name) { | 412 Variable* Scope::Lookup(Handle<String> name) { |
396 for (Scope* scope = this; | 413 for (Scope* scope = this; |
397 scope != NULL; | 414 scope != NULL; |
398 scope = scope->outer_scope()) { | 415 scope = scope->outer_scope()) { |
399 Variable* var = scope->LocalLookup(name); | 416 Variable* var = scope->LocalLookup(name); |
400 if (var != NULL) return var; | 417 if (var != NULL) return var; |
401 } | 418 } |
402 return NULL; | 419 return NULL; |
403 } | 420 } |
404 | 421 |
405 | 422 |
406 Variable* Scope::DeclareFunctionVar(Handle<String> name, VariableMode mode) { | 423 Variable* Scope::DeclareFunctionVar(Handle<String> name, VariableMode mode) { |
407 ASSERT(is_function_scope() && function_ == NULL); | 424 ASSERT(is_function_scope() && function_ == NULL); |
408 Variable* function_var = | 425 Variable* function_var = new Variable( |
409 new Variable(this, name, mode, true, Variable::NORMAL); | 426 this, name, mode, true, Variable::NORMAL, CREATED_INITIALIZED); |
410 function_ = new(isolate_->zone()) VariableProxy(isolate_, function_var); | 427 function_ = new(isolate_->zone()) VariableProxy(isolate_, function_var); |
411 return function_var; | 428 return function_var; |
412 } | 429 } |
413 | 430 |
414 | 431 |
415 void Scope::DeclareParameter(Handle<String> name, VariableMode mode) { | 432 void Scope::DeclareParameter(Handle<String> name, VariableMode mode) { |
416 ASSERT(!already_resolved()); | 433 ASSERT(!already_resolved()); |
417 ASSERT(is_function_scope()); | 434 ASSERT(is_function_scope()); |
418 Variable* var = | 435 Variable* var = variables_.Declare( |
419 variables_.Declare(this, name, mode, true, Variable::NORMAL); | 436 this, name, mode, true, Variable::NORMAL, CREATED_INITIALIZED); |
420 params_.Add(var); | 437 params_.Add(var); |
421 } | 438 } |
422 | 439 |
423 | 440 |
424 Variable* Scope::DeclareLocal(Handle<String> name, VariableMode mode) { | 441 Variable* Scope::DeclareLocal(Handle<String> name, |
| 442 VariableMode mode, |
| 443 InitializationFlag init_flag) { |
425 ASSERT(!already_resolved()); | 444 ASSERT(!already_resolved()); |
426 // This function handles VAR and CONST modes. DYNAMIC variables are | 445 // This function handles VAR and CONST modes. DYNAMIC variables are |
427 // introduces during variable allocation, INTERNAL variables are allocated | 446 // introduces during variable allocation, INTERNAL variables are allocated |
428 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). | 447 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). |
429 ASSERT(mode == VAR || | 448 ASSERT(mode == VAR || |
430 mode == CONST || | 449 mode == CONST || |
431 mode == CONST_HARMONY || | 450 mode == CONST_HARMONY || |
432 mode == LET); | 451 mode == LET); |
433 ++num_var_or_const_; | 452 ++num_var_or_const_; |
434 return variables_.Declare(this, name, mode, true, Variable::NORMAL); | 453 return |
| 454 variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag); |
435 } | 455 } |
436 | 456 |
437 | 457 |
438 Variable* Scope::DeclareGlobal(Handle<String> name) { | 458 Variable* Scope::DeclareGlobal(Handle<String> name) { |
439 ASSERT(is_global_scope()); | 459 ASSERT(is_global_scope()); |
440 return variables_.Declare(this, name, DYNAMIC_GLOBAL, | 460 return variables_.Declare(this, |
| 461 name, |
| 462 DYNAMIC_GLOBAL, |
441 true, | 463 true, |
442 Variable::NORMAL); | 464 Variable::NORMAL, |
| 465 CREATED_INITIALIZED); |
443 } | 466 } |
444 | 467 |
445 | 468 |
446 VariableProxy* Scope::NewUnresolved(Handle<String> name, int position) { | 469 VariableProxy* Scope::NewUnresolved(Handle<String> name, int position) { |
447 // Note that we must not share the unresolved variables with | 470 // Note that we must not share the unresolved variables with |
448 // the same name because they may be removed selectively via | 471 // the same name because they may be removed selectively via |
449 // RemoveUnresolved(). | 472 // RemoveUnresolved(). |
450 ASSERT(!already_resolved()); | 473 ASSERT(!already_resolved()); |
451 VariableProxy* proxy = new(isolate_->zone()) VariableProxy( | 474 VariableProxy* proxy = new(isolate_->zone()) VariableProxy( |
452 isolate_, name, false, position); | 475 isolate_, name, false, position); |
(...skipping 13 matching lines...) Expand all Loading... |
466 } | 489 } |
467 } | 490 } |
468 | 491 |
469 | 492 |
470 Variable* Scope::NewTemporary(Handle<String> name) { | 493 Variable* Scope::NewTemporary(Handle<String> name) { |
471 ASSERT(!already_resolved()); | 494 ASSERT(!already_resolved()); |
472 Variable* var = new Variable(this, | 495 Variable* var = new Variable(this, |
473 name, | 496 name, |
474 TEMPORARY, | 497 TEMPORARY, |
475 true, | 498 true, |
476 Variable::NORMAL); | 499 Variable::NORMAL, |
| 500 CREATED_INITIALIZED); |
477 temps_.Add(var); | 501 temps_.Add(var); |
478 return var; | 502 return var; |
479 } | 503 } |
480 | 504 |
481 | 505 |
482 void Scope::AddDeclaration(Declaration* declaration) { | 506 void Scope::AddDeclaration(Declaration* declaration) { |
483 decls_.Add(declaration); | 507 decls_.Add(declaration); |
484 } | 508 } |
485 | 509 |
486 | 510 |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 } | 829 } |
806 #endif // DEBUG | 830 #endif // DEBUG |
807 | 831 |
808 | 832 |
809 Variable* Scope::NonLocal(Handle<String> name, VariableMode mode) { | 833 Variable* Scope::NonLocal(Handle<String> name, VariableMode mode) { |
810 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); | 834 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); |
811 VariableMap* map = dynamics_->GetMap(mode); | 835 VariableMap* map = dynamics_->GetMap(mode); |
812 Variable* var = map->Lookup(name); | 836 Variable* var = map->Lookup(name); |
813 if (var == NULL) { | 837 if (var == NULL) { |
814 // Declare a new non-local. | 838 // Declare a new non-local. |
815 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); | 839 InitializationFlag init_flag = (mode == VAR) |
| 840 ? CREATED_INITIALIZED : NEEDS_INITIALIZATION; |
| 841 var = map->Declare(NULL, |
| 842 name, |
| 843 mode, |
| 844 true, |
| 845 Variable::NORMAL, |
| 846 init_flag); |
816 // Allocate it by giving it a dynamic lookup. | 847 // Allocate it by giving it a dynamic lookup. |
817 var->AllocateTo(Variable::LOOKUP, -1); | 848 var->AllocateTo(Variable::LOOKUP, -1); |
818 } | 849 } |
819 return var; | 850 return var; |
820 } | 851 } |
821 | 852 |
822 | 853 |
823 Variable* Scope::LookupRecursive(Handle<String> name, | 854 Variable* Scope::LookupRecursive(Handle<String> name, |
824 Handle<Context> context, | 855 Handle<Context> context, |
825 BindingKind* binding_kind) { | 856 BindingKind* binding_kind) { |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 // need the minimal number of slots if we must have a context. | 1186 // need the minimal number of slots if we must have a context. |
1156 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1187 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
1157 num_heap_slots_ = 0; | 1188 num_heap_slots_ = 0; |
1158 } | 1189 } |
1159 | 1190 |
1160 // Allocation done. | 1191 // Allocation done. |
1161 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1192 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1162 } | 1193 } |
1163 | 1194 |
1164 } } // namespace v8::internal | 1195 } } // namespace v8::internal |
OLD | NEW |