| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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/scopeinfo.h" | 5 #include "src/ast/scopeinfo.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 const int length = kVariablePartIndex + parameter_count + | 234 const int length = kVariablePartIndex + parameter_count + |
| 235 (1 + stack_local_count) + 2 * context_local_count + | 235 (1 + stack_local_count) + 2 * context_local_count + |
| 236 2 * context_global_count + | 236 2 * context_global_count + |
| 237 3 * strong_mode_free_variable_count + | 237 3 * strong_mode_free_variable_count + |
| 238 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); | 238 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); |
| 239 | 239 |
| 240 Factory* factory = isolate->factory(); | 240 Factory* factory = isolate->factory(); |
| 241 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 241 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
| 242 | 242 |
| 243 // Encode the flags. | 243 // Encode the flags. |
| 244 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | | 244 int flags = |
| 245 CallsEvalField::encode(false) | | 245 ScopeTypeField::encode(SCRIPT_SCOPE) | CallsEvalField::encode(false) | |
| 246 LanguageModeField::encode(SLOPPY) | | 246 LanguageModeField::encode(SLOPPY) | DeclarationScopeField::encode(true) | |
| 247 DeclarationScopeField::encode(true) | | 247 ReceiverVariableField::encode(receiver_info) | |
| 248 ReceiverVariableField::encode(receiver_info) | | 248 FunctionVariableField::encode(function_name_info) | |
| 249 FunctionVariableField::encode(function_name_info) | | 249 FunctionVariableMode::encode(function_variable_mode) | |
| 250 FunctionVariableMode::encode(function_variable_mode) | | 250 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | |
| 251 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | | 251 HasSimpleParametersField::encode(has_simple_parameters) | |
| 252 HasSimpleParametersField::encode(has_simple_parameters) | | 252 FunctionKindField::encode(FunctionKind::kNormalFunction); |
| 253 FunctionKindField::encode(FunctionKind::kNormalFunction); | |
| 254 scope_info->SetFlags(flags); | 253 scope_info->SetFlags(flags); |
| 255 scope_info->SetParameterCount(parameter_count); | 254 scope_info->SetParameterCount(parameter_count); |
| 256 scope_info->SetStackLocalCount(stack_local_count); | 255 scope_info->SetStackLocalCount(stack_local_count); |
| 257 scope_info->SetContextLocalCount(context_local_count); | 256 scope_info->SetContextLocalCount(context_local_count); |
| 258 scope_info->SetContextGlobalCount(context_global_count); | 257 scope_info->SetContextGlobalCount(context_global_count); |
| 259 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); | 258 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); |
| 260 | 259 |
| 261 int index = kVariablePartIndex; | 260 int index = kVariablePartIndex; |
| 262 const int first_slot_index = 0; | 261 const int first_slot_index = 0; |
| 263 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); | 262 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 LanguageMode ScopeInfo::language_mode() { | 309 LanguageMode ScopeInfo::language_mode() { |
| 311 return length() > 0 ? LanguageModeField::decode(Flags()) : SLOPPY; | 310 return length() > 0 ? LanguageModeField::decode(Flags()) : SLOPPY; |
| 312 } | 311 } |
| 313 | 312 |
| 314 | 313 |
| 315 bool ScopeInfo::is_declaration_scope() { | 314 bool ScopeInfo::is_declaration_scope() { |
| 316 return DeclarationScopeField::decode(Flags()); | 315 return DeclarationScopeField::decode(Flags()); |
| 317 } | 316 } |
| 318 | 317 |
| 319 | 318 |
| 320 int ScopeInfo::LocalCount() { | 319 int ScopeInfo::LocalCount() { return StackLocalCount() + ContextLocalCount(); } |
| 321 return StackLocalCount() + ContextLocalCount(); | |
| 322 } | |
| 323 | 320 |
| 324 | 321 |
| 325 int ScopeInfo::StackSlotCount() { | 322 int ScopeInfo::StackSlotCount() { |
| 326 if (length() > 0) { | 323 if (length() > 0) { |
| 327 bool function_name_stack_slot = | 324 bool function_name_stack_slot = |
| 328 FunctionVariableField::decode(Flags()) == STACK; | 325 FunctionVariableField::decode(Flags()) == STACK; |
| 329 return StackLocalCount() + (function_name_stack_slot ? 1 : 0); | 326 return StackLocalCount() + (function_name_stack_slot ? 1 : 0); |
| 330 } | 327 } |
| 331 return 0; | 328 return 0; |
| 332 } | 329 } |
| 333 | 330 |
| 334 | 331 |
| 335 int ScopeInfo::ContextLength() { | 332 int ScopeInfo::ContextLength() { |
| 336 if (length() > 0) { | 333 if (length() > 0) { |
| 337 int context_locals = ContextLocalCount(); | 334 int context_locals = ContextLocalCount(); |
| 338 int context_globals = ContextGlobalCount(); | 335 int context_globals = ContextGlobalCount(); |
| 339 bool function_name_context_slot = | 336 bool function_name_context_slot = |
| 340 FunctionVariableField::decode(Flags()) == CONTEXT; | 337 FunctionVariableField::decode(Flags()) == CONTEXT; |
| 341 bool has_context = context_locals > 0 || context_globals > 0 || | 338 bool has_context = context_locals > 0 || context_globals > 0 || |
| 342 function_name_context_slot || | 339 function_name_context_slot || |
| 343 scope_type() == WITH_SCOPE || | 340 scope_type() == WITH_SCOPE || |
| 344 (scope_type() == BLOCK_SCOPE && CallsSloppyEval() && | 341 (scope_type() == BLOCK_SCOPE && CallsSloppyEval() && |
| 345 is_declaration_scope()) || | 342 is_declaration_scope()) || |
| 346 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || | 343 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || |
| 347 scope_type() == MODULE_SCOPE; | 344 scope_type() == MODULE_SCOPE; |
| 348 | 345 |
| 349 if (has_context) { | 346 if (has_context) { |
| 350 return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals + | 347 return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals + |
| 351 (function_name_context_slot ? 1 : 0); | 348 (function_name_context_slot ? 1 : 0); |
| 352 } | 349 } |
| 353 } | 350 } |
| 354 return 0; | 351 return 0; |
| 355 } | 352 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 385 | 382 |
| 386 bool ScopeInfo::HasHeapAllocatedLocals() { | 383 bool ScopeInfo::HasHeapAllocatedLocals() { |
| 387 if (length() > 0) { | 384 if (length() > 0) { |
| 388 return ContextLocalCount() > 0; | 385 return ContextLocalCount() > 0; |
| 389 } else { | 386 } else { |
| 390 return false; | 387 return false; |
| 391 } | 388 } |
| 392 } | 389 } |
| 393 | 390 |
| 394 | 391 |
| 395 bool ScopeInfo::HasContext() { | 392 bool ScopeInfo::HasContext() { return ContextLength() > 0; } |
| 396 return ContextLength() > 0; | |
| 397 } | |
| 398 | 393 |
| 399 | 394 |
| 400 String* ScopeInfo::FunctionName() { | 395 String* ScopeInfo::FunctionName() { |
| 401 DCHECK(HasFunctionName()); | 396 DCHECK(HasFunctionName()); |
| 402 return String::cast(get(FunctionNameEntryIndex())); | 397 return String::cast(get(FunctionNameEntryIndex())); |
| 403 } | 398 } |
| 404 | 399 |
| 405 | 400 |
| 406 String* ScopeInfo::ParameterName(int var) { | 401 String* ScopeInfo::ParameterName(int var) { |
| 407 DCHECK(0 <= var && var < ParameterCount()); | 402 DCHECK(0 <= var && var < ParameterCount()); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 } | 727 } |
| 733 | 728 |
| 734 | 729 |
| 735 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, | 730 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, |
| 736 VariableMode mode, InitializationFlag init_flag, | 731 VariableMode mode, InitializationFlag init_flag, |
| 737 MaybeAssignedFlag maybe_assigned_flag, | 732 MaybeAssignedFlag maybe_assigned_flag, |
| 738 int slot_index) { | 733 int slot_index) { |
| 739 DisallowHeapAllocation no_gc; | 734 DisallowHeapAllocation no_gc; |
| 740 Handle<String> internalized_name; | 735 Handle<String> internalized_name; |
| 741 DCHECK(slot_index > kNotFound); | 736 DCHECK(slot_index > kNotFound); |
| 742 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). | 737 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name) |
| 743 ToHandle(&internalized_name)) { | 738 .ToHandle(&internalized_name)) { |
| 744 int index = Hash(*data, *internalized_name); | 739 int index = Hash(*data, *internalized_name); |
| 745 Key& key = keys_[index]; | 740 Key& key = keys_[index]; |
| 746 key.data = *data; | 741 key.data = *data; |
| 747 key.name = *internalized_name; | 742 key.name = *internalized_name; |
| 748 // Please note value only takes a uint as index. | 743 // Please note value only takes a uint as index. |
| 749 values_[index] = Value(mode, init_flag, maybe_assigned_flag, | 744 values_[index] = |
| 750 slot_index - kNotFound).raw(); | 745 Value(mode, init_flag, maybe_assigned_flag, slot_index - kNotFound) |
| 746 .raw(); |
| 751 #ifdef DEBUG | 747 #ifdef DEBUG |
| 752 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); | 748 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); |
| 753 #endif | 749 #endif |
| 754 } | 750 } |
| 755 } | 751 } |
| 756 | 752 |
| 757 | 753 |
| 758 void ContextSlotCache::Clear() { | 754 void ContextSlotCache::Clear() { |
| 759 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; | 755 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; |
| 760 } | 756 } |
| 761 | 757 |
| 762 | 758 |
| 763 #ifdef DEBUG | 759 #ifdef DEBUG |
| 764 | 760 |
| 765 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, | 761 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, |
| 766 VariableMode mode, | 762 VariableMode mode, |
| 767 InitializationFlag init_flag, | 763 InitializationFlag init_flag, |
| 768 MaybeAssignedFlag maybe_assigned_flag, | 764 MaybeAssignedFlag maybe_assigned_flag, |
| 769 int slot_index) { | 765 int slot_index) { |
| 770 DisallowHeapAllocation no_gc; | 766 DisallowHeapAllocation no_gc; |
| 771 Handle<String> internalized_name; | 767 Handle<String> internalized_name; |
| 772 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). | 768 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name) |
| 773 ToHandle(&internalized_name)) { | 769 .ToHandle(&internalized_name)) { |
| 774 int index = Hash(*data, *name); | 770 int index = Hash(*data, *name); |
| 775 Key& key = keys_[index]; | 771 Key& key = keys_[index]; |
| 776 DCHECK(key.data == *data); | 772 DCHECK(key.data == *data); |
| 777 DCHECK(key.name->Equals(*name)); | 773 DCHECK(key.name->Equals(*name)); |
| 778 Value result(values_[index]); | 774 Value result(values_[index]); |
| 779 DCHECK(result.mode() == mode); | 775 DCHECK(result.mode() == mode); |
| 780 DCHECK(result.initialization_flag() == init_flag); | 776 DCHECK(result.initialization_flag() == init_flag); |
| 781 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); | 777 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); |
| 782 DCHECK(result.index() + kNotFound == slot_index); | 778 DCHECK(result.index() + kNotFound == slot_index); |
| 783 } | 779 } |
| 784 } | 780 } |
| 785 | 781 |
| 786 | 782 |
| 787 static void PrintList(const char* list_name, | 783 static void PrintList(const char* list_name, int nof_internal_slots, int start, |
| 788 int nof_internal_slots, | 784 int end, ScopeInfo* scope_info) { |
| 789 int start, | |
| 790 int end, | |
| 791 ScopeInfo* scope_info) { | |
| 792 if (start < end) { | 785 if (start < end) { |
| 793 PrintF("\n // %s\n", list_name); | 786 PrintF("\n // %s\n", list_name); |
| 794 if (nof_internal_slots > 0) { | 787 if (nof_internal_slots > 0) { |
| 795 PrintF(" %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1); | 788 PrintF(" %2d - %2d [internal slots]\n", 0, nof_internal_slots - 1); |
| 796 } | 789 } |
| 797 for (int i = nof_internal_slots; start < end; ++i, ++start) { | 790 for (int i = nof_internal_slots; start < end; ++i, ++start) { |
| 798 PrintF(" %2d ", i); | 791 PrintF(" %2d ", i); |
| 799 String::cast(scope_info->get(start))->ShortPrint(); | 792 String::cast(scope_info->get(start))->ShortPrint(); |
| 800 PrintF("\n"); | 793 PrintF("\n"); |
| 801 } | 794 } |
| 802 } | 795 } |
| 803 } | 796 } |
| 804 | 797 |
| 805 | 798 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 info->set_mode(i, var->mode()); | 836 info->set_mode(i, var->mode()); |
| 844 DCHECK(var->index() >= 0); | 837 DCHECK(var->index() >= 0); |
| 845 info->set_index(i, var->index()); | 838 info->set_index(i, var->index()); |
| 846 } | 839 } |
| 847 DCHECK(i == info->length()); | 840 DCHECK(i == info->length()); |
| 848 return info; | 841 return info; |
| 849 } | 842 } |
| 850 | 843 |
| 851 } // namespace internal | 844 } // namespace internal |
| 852 } // namespace v8 | 845 } // namespace v8 |
| OLD | NEW |