| 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 |