| 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 <stdlib.h> | 5 #include <stdlib.h> |
| 6 | 6 |
| 7 #include "src/ast/context-slot-cache.h" | 7 #include "src/ast/context-slot-cache.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 | 10 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 function_variable_mode = var->mode(); | 64 function_variable_mode = var->mode(); |
| 65 } else { | 65 } else { |
| 66 function_name_info = NONE; | 66 function_name_info = NONE; |
| 67 function_variable_mode = VAR; | 67 function_variable_mode = VAR; |
| 68 } | 68 } |
| 69 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE); | 69 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE); |
| 70 | 70 |
| 71 const bool has_function_name = function_name_info != NONE; | 71 const bool has_function_name = function_name_info != NONE; |
| 72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; | 72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; |
| 73 const int parameter_count = scope->num_parameters(); | 73 const int parameter_count = scope->num_parameters(); |
| 74 const bool has_outer_scope_info = |
| 75 scope->GetOuterScopeWithContext() != nullptr; |
| 74 const int length = kVariablePartIndex + parameter_count + | 76 const int length = kVariablePartIndex + parameter_count + |
| 75 (1 + stack_local_count) + 2 * context_local_count + | 77 (1 + stack_local_count) + 2 * context_local_count + |
| 76 2 * context_global_count + | 78 2 * context_global_count + (has_receiver ? 1 : 0) + |
| 77 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); | 79 (has_function_name ? 2 : 0) + |
| 80 (has_outer_scope_info ? 1 : 0); |
| 78 | 81 |
| 79 Factory* factory = isolate->factory(); | 82 Factory* factory = isolate->factory(); |
| 80 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 83 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
| 81 | 84 |
| 82 bool has_simple_parameters = false; | 85 bool has_simple_parameters = false; |
| 83 bool asm_module = false; | 86 bool asm_module = false; |
| 84 bool asm_function = false; | 87 bool asm_function = false; |
| 85 FunctionKind function_kind = kNormalFunction; | 88 FunctionKind function_kind = kNormalFunction; |
| 86 if (scope->is_function_scope()) { | 89 if (scope->is_function_scope()) { |
| 87 DeclarationScope* function_scope = scope->AsDeclarationScope(); | 90 DeclarationScope* function_scope = scope->AsDeclarationScope(); |
| 88 has_simple_parameters = function_scope->has_simple_parameters(); | 91 has_simple_parameters = function_scope->has_simple_parameters(); |
| 89 asm_module = function_scope->asm_module(); | 92 asm_module = function_scope->asm_module(); |
| 90 asm_function = function_scope->asm_function(); | 93 asm_function = function_scope->asm_function(); |
| 91 function_kind = function_scope->function_kind(); | 94 function_kind = function_scope->function_kind(); |
| 92 } | 95 } |
| 93 | 96 |
| 94 // Encode the flags. | 97 // Encode the flags. |
| 95 int flags = ScopeTypeField::encode(scope->scope_type()) | | 98 int flags = ScopeTypeField::encode(scope->scope_type()) | |
| 96 CallsEvalField::encode(scope->calls_eval()) | | 99 CallsEvalField::encode(scope->calls_eval()) | |
| 97 LanguageModeField::encode(scope->language_mode()) | | 100 LanguageModeField::encode(scope->language_mode()) | |
| 98 DeclarationScopeField::encode(scope->is_declaration_scope()) | | 101 DeclarationScopeField::encode(scope->is_declaration_scope()) | |
| 99 ReceiverVariableField::encode(receiver_info) | | 102 ReceiverVariableField::encode(receiver_info) | |
| 100 HasNewTargetField::encode(has_new_target) | | 103 HasNewTargetField::encode(has_new_target) | |
| 101 FunctionVariableField::encode(function_name_info) | | 104 FunctionVariableField::encode(function_name_info) | |
| 102 FunctionVariableMode::encode(function_variable_mode) | | 105 FunctionVariableMode::encode(function_variable_mode) | |
| 103 AsmModuleField::encode(asm_module) | | 106 AsmModuleField::encode(asm_module) | |
| 104 AsmFunctionField::encode(asm_function) | | 107 AsmFunctionField::encode(asm_function) | |
| 105 HasSimpleParametersField::encode(has_simple_parameters) | | 108 HasSimpleParametersField::encode(has_simple_parameters) | |
| 106 FunctionKindField::encode(function_kind); | 109 FunctionKindField::encode(function_kind) | |
| 110 HasOuterScopeInfoField::encode(has_outer_scope_info); |
| 107 scope_info->SetFlags(flags); | 111 scope_info->SetFlags(flags); |
| 108 scope_info->SetParameterCount(parameter_count); | 112 scope_info->SetParameterCount(parameter_count); |
| 109 scope_info->SetStackLocalCount(stack_local_count); | 113 scope_info->SetStackLocalCount(stack_local_count); |
| 110 scope_info->SetContextLocalCount(context_local_count); | 114 scope_info->SetContextLocalCount(context_local_count); |
| 111 scope_info->SetContextGlobalCount(context_global_count); | 115 scope_info->SetContextGlobalCount(context_global_count); |
| 112 | 116 |
| 113 int index = kVariablePartIndex; | 117 int index = kVariablePartIndex; |
| 114 // Add parameters. | 118 // Add parameters. |
| 115 DCHECK_EQ(index, scope_info->ParameterEntriesIndex()); | 119 DCHECK_EQ(index, scope_info->ParameterEntriesIndex()); |
| 116 if (scope->is_declaration_scope()) { | 120 if (scope->is_declaration_scope()) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 DCHECK(index == scope_info->FunctionNameEntryIndex()); | 188 DCHECK(index == scope_info->FunctionNameEntryIndex()); |
| 185 if (has_function_name) { | 189 if (has_function_name) { |
| 186 int var_index = scope->AsDeclarationScope()->function_var()->index(); | 190 int var_index = scope->AsDeclarationScope()->function_var()->index(); |
| 187 scope_info->set(index++, | 191 scope_info->set(index++, |
| 188 *scope->AsDeclarationScope()->function_var()->name()); | 192 *scope->AsDeclarationScope()->function_var()->name()); |
| 189 scope_info->set(index++, Smi::FromInt(var_index)); | 193 scope_info->set(index++, Smi::FromInt(var_index)); |
| 190 DCHECK(function_name_info != CONTEXT || | 194 DCHECK(function_name_info != CONTEXT || |
| 191 var_index == scope_info->ContextLength() - 1); | 195 var_index == scope_info->ContextLength() - 1); |
| 192 } | 196 } |
| 193 | 197 |
| 198 // If present, add the outer scope info. |
| 199 DCHECK(index == scope_info->OuterScopeInfoEntryIndex()); |
| 200 if (has_outer_scope_info) { |
| 201 Handle<ScopeInfo> outer_scope_info = |
| 202 scope->GetOuterScopeWithContext()->GetScopeInfo(isolate); |
| 203 scope_info->set(index++, *outer_scope_info); |
| 204 } |
| 205 |
| 194 DCHECK(index == scope_info->length()); | 206 DCHECK(index == scope_info->length()); |
| 195 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); | 207 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); |
| 196 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || | 208 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || |
| 197 (scope->num_heap_slots() == kVariablePartIndex && | 209 (scope->num_heap_slots() == kVariablePartIndex && |
| 198 scope_info->ContextLength() == 0)); | 210 scope_info->ContextLength() == 0)); |
| 199 return scope_info; | 211 return scope_info; |
| 200 } | 212 } |
| 201 | 213 |
| 202 | 214 |
| 203 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { | 215 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { |
| 204 DCHECK(isolate->bootstrapper()->IsActive()); | 216 DCHECK(isolate->bootstrapper()->IsActive()); |
| 205 | 217 |
| 206 const int stack_local_count = 0; | 218 const int stack_local_count = 0; |
| 207 const int context_local_count = 1; | 219 const int context_local_count = 1; |
| 208 const int context_global_count = 0; | 220 const int context_global_count = 0; |
| 209 const bool has_simple_parameters = true; | 221 const bool has_simple_parameters = true; |
| 210 const VariableAllocationInfo receiver_info = CONTEXT; | 222 const VariableAllocationInfo receiver_info = CONTEXT; |
| 211 const VariableAllocationInfo function_name_info = NONE; | 223 const VariableAllocationInfo function_name_info = NONE; |
| 212 const VariableMode function_variable_mode = VAR; | 224 const VariableMode function_variable_mode = VAR; |
| 213 const bool has_function_name = false; | 225 const bool has_function_name = false; |
| 214 const bool has_receiver = true; | 226 const bool has_receiver = true; |
| 227 const bool has_outer_scope_info = false; |
| 215 const int parameter_count = 0; | 228 const int parameter_count = 0; |
| 216 const int length = kVariablePartIndex + parameter_count + | 229 const int length = kVariablePartIndex + parameter_count + |
| 217 (1 + stack_local_count) + 2 * context_local_count + | 230 (1 + stack_local_count) + 2 * context_local_count + |
| 218 2 * context_global_count + | 231 2 * context_global_count + (has_receiver ? 1 : 0) + |
| 219 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); | 232 (has_function_name ? 2 : 0) + |
| 233 (has_outer_scope_info ? 1 : 0); |
| 220 | 234 |
| 221 Factory* factory = isolate->factory(); | 235 Factory* factory = isolate->factory(); |
| 222 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 236 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
| 223 | 237 |
| 224 // Encode the flags. | 238 // Encode the flags. |
| 225 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | | 239 int flags = |
| 226 CallsEvalField::encode(false) | | 240 ScopeTypeField::encode(SCRIPT_SCOPE) | CallsEvalField::encode(false) | |
| 227 LanguageModeField::encode(SLOPPY) | | 241 LanguageModeField::encode(SLOPPY) | DeclarationScopeField::encode(true) | |
| 228 DeclarationScopeField::encode(true) | | 242 ReceiverVariableField::encode(receiver_info) | |
| 229 ReceiverVariableField::encode(receiver_info) | | 243 FunctionVariableField::encode(function_name_info) | |
| 230 FunctionVariableField::encode(function_name_info) | | 244 FunctionVariableMode::encode(function_variable_mode) | |
| 231 FunctionVariableMode::encode(function_variable_mode) | | 245 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | |
| 232 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | | 246 HasSimpleParametersField::encode(has_simple_parameters) | |
| 233 HasSimpleParametersField::encode(has_simple_parameters) | | 247 FunctionKindField::encode(FunctionKind::kNormalFunction) | |
| 234 FunctionKindField::encode(FunctionKind::kNormalFunction); | 248 HasOuterScopeInfoField::encode(has_outer_scope_info); |
| 235 scope_info->SetFlags(flags); | 249 scope_info->SetFlags(flags); |
| 236 scope_info->SetParameterCount(parameter_count); | 250 scope_info->SetParameterCount(parameter_count); |
| 237 scope_info->SetStackLocalCount(stack_local_count); | 251 scope_info->SetStackLocalCount(stack_local_count); |
| 238 scope_info->SetContextLocalCount(context_local_count); | 252 scope_info->SetContextLocalCount(context_local_count); |
| 239 scope_info->SetContextGlobalCount(context_global_count); | 253 scope_info->SetContextGlobalCount(context_global_count); |
| 240 | 254 |
| 241 int index = kVariablePartIndex; | 255 int index = kVariablePartIndex; |
| 242 const int first_slot_index = 0; | 256 const int first_slot_index = 0; |
| 243 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); | 257 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); |
| 244 scope_info->set(index++, Smi::FromInt(first_slot_index)); | 258 scope_info->set(index++, Smi::FromInt(first_slot_index)); |
| 245 DCHECK(index == scope_info->StackLocalEntriesIndex()); | 259 DCHECK(index == scope_info->StackLocalEntriesIndex()); |
| 246 | 260 |
| 247 // Here we add info for context-allocated "this". | 261 // Here we add info for context-allocated "this". |
| 248 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); | 262 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); |
| 249 scope_info->set(index++, *isolate->factory()->this_string()); | 263 scope_info->set(index++, *isolate->factory()->this_string()); |
| 250 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); | 264 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); |
| 251 const uint32_t value = VariableModeField::encode(CONST) | | 265 const uint32_t value = VariableModeField::encode(CONST) | |
| 252 InitFlagField::encode(kCreatedInitialized) | | 266 InitFlagField::encode(kCreatedInitialized) | |
| 253 MaybeAssignedFlagField::encode(kNotAssigned); | 267 MaybeAssignedFlagField::encode(kNotAssigned); |
| 254 scope_info->set(index++, Smi::FromInt(value)); | 268 scope_info->set(index++, Smi::FromInt(value)); |
| 255 | 269 |
| 256 // And here we record that this scopeinfo binds a receiver. | 270 // And here we record that this scopeinfo binds a receiver. |
| 257 DCHECK(index == scope_info->ReceiverEntryIndex()); | 271 DCHECK(index == scope_info->ReceiverEntryIndex()); |
| 258 const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0; | 272 const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0; |
| 259 scope_info->set(index++, Smi::FromInt(receiver_index)); | 273 scope_info->set(index++, Smi::FromInt(receiver_index)); |
| 260 | 274 |
| 261 DCHECK(index == scope_info->FunctionNameEntryIndex()); | 275 DCHECK(index == scope_info->FunctionNameEntryIndex()); |
| 276 DCHECK(index == scope_info->OuterScopeInfoEntryIndex()); |
| 262 | 277 |
| 263 DCHECK_EQ(index, scope_info->length()); | 278 DCHECK_EQ(index, scope_info->length()); |
| 264 DCHECK_EQ(scope_info->ParameterCount(), 0); | 279 DCHECK_EQ(scope_info->ParameterCount(), 0); |
| 265 DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1); | 280 DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1); |
| 266 | 281 |
| 267 return scope_info; | 282 return scope_info; |
| 268 } | 283 } |
| 269 | 284 |
| 270 | 285 |
| 271 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { | 286 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 | 370 |
| 356 | 371 |
| 357 bool ScopeInfo::HasFunctionName() { | 372 bool ScopeInfo::HasFunctionName() { |
| 358 if (length() > 0) { | 373 if (length() > 0) { |
| 359 return NONE != FunctionVariableField::decode(Flags()); | 374 return NONE != FunctionVariableField::decode(Flags()); |
| 360 } else { | 375 } else { |
| 361 return false; | 376 return false; |
| 362 } | 377 } |
| 363 } | 378 } |
| 364 | 379 |
| 380 bool ScopeInfo::HasOuterScopeInfo() { |
| 381 if (length() > 0) { |
| 382 return HasOuterScopeInfoField::decode(Flags()); |
| 383 } else { |
| 384 return false; |
| 385 } |
| 386 } |
| 365 | 387 |
| 366 bool ScopeInfo::HasHeapAllocatedLocals() { | 388 bool ScopeInfo::HasHeapAllocatedLocals() { |
| 367 if (length() > 0) { | 389 if (length() > 0) { |
| 368 return ContextLocalCount() > 0; | 390 return ContextLocalCount() > 0; |
| 369 } else { | 391 } else { |
| 370 return false; | 392 return false; |
| 371 } | 393 } |
| 372 } | 394 } |
| 373 | 395 |
| 374 | 396 |
| 375 bool ScopeInfo::HasContext() { | 397 bool ScopeInfo::HasContext() { |
| 376 return ContextLength() > 0; | 398 return ContextLength() > 0; |
| 377 } | 399 } |
| 378 | 400 |
| 379 | 401 |
| 380 String* ScopeInfo::FunctionName() { | 402 String* ScopeInfo::FunctionName() { |
| 381 DCHECK(HasFunctionName()); | 403 DCHECK(HasFunctionName()); |
| 382 return String::cast(get(FunctionNameEntryIndex())); | 404 return String::cast(get(FunctionNameEntryIndex())); |
| 383 } | 405 } |
| 384 | 406 |
| 407 ScopeInfo* ScopeInfo::OuterScopeInfo() { |
| 408 DCHECK(HasOuterScopeInfo()); |
| 409 return ScopeInfo::cast(get(OuterScopeInfoEntryIndex())); |
| 410 } |
| 385 | 411 |
| 386 String* ScopeInfo::ParameterName(int var) { | 412 String* ScopeInfo::ParameterName(int var) { |
| 387 DCHECK(0 <= var && var < ParameterCount()); | 413 DCHECK(0 <= var && var < ParameterCount()); |
| 388 int info_index = ParameterEntriesIndex() + var; | 414 int info_index = ParameterEntriesIndex() + var; |
| 389 return String::cast(get(info_index)); | 415 return String::cast(get(info_index)); |
| 390 } | 416 } |
| 391 | 417 |
| 392 | 418 |
| 393 String* ScopeInfo::LocalName(int var) { | 419 String* ScopeInfo::LocalName(int var) { |
| 394 DCHECK(0 <= var && var < LocalCount()); | 420 DCHECK(0 <= var && var < LocalCount()); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 | 662 |
| 637 int ScopeInfo::ReceiverEntryIndex() { | 663 int ScopeInfo::ReceiverEntryIndex() { |
| 638 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); | 664 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); |
| 639 } | 665 } |
| 640 | 666 |
| 641 | 667 |
| 642 int ScopeInfo::FunctionNameEntryIndex() { | 668 int ScopeInfo::FunctionNameEntryIndex() { |
| 643 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); | 669 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); |
| 644 } | 670 } |
| 645 | 671 |
| 672 int ScopeInfo::OuterScopeInfoEntryIndex() { |
| 673 return FunctionNameEntryIndex() + (HasFunctionName() ? 2 : 0); |
| 674 } |
| 675 |
| 646 #ifdef DEBUG | 676 #ifdef DEBUG |
| 647 | 677 |
| 648 static void PrintList(const char* list_name, | 678 static void PrintList(const char* list_name, |
| 649 int nof_internal_slots, | 679 int nof_internal_slots, |
| 650 int start, | 680 int start, |
| 651 int end, | 681 int end, |
| 652 ScopeInfo* scope_info) { | 682 ScopeInfo* scope_info) { |
| 653 if (start < end) { | 683 if (start < end) { |
| 654 PrintF("\n // %s\n", list_name); | 684 PrintF("\n // %s\n", list_name); |
| 655 if (nof_internal_slots > 0) { | 685 if (nof_internal_slots > 0) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 683 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); | 713 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); |
| 684 } | 714 } |
| 685 | 715 |
| 686 PrintF("}\n"); | 716 PrintF("}\n"); |
| 687 } | 717 } |
| 688 #endif // DEBUG | 718 #endif // DEBUG |
| 689 | 719 |
| 690 | 720 |
| 691 } // namespace internal | 721 } // namespace internal |
| 692 } // namespace v8 | 722 } // namespace v8 |
| OLD | NEW |