Index: src/scopeinfo.cc |
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc |
deleted file mode 100644 |
index c061b8fcebf8c3bfffb7b1a98aa2c65ddf02f049..0000000000000000000000000000000000000000 |
--- a/src/scopeinfo.cc |
+++ /dev/null |
@@ -1,852 +0,0 @@ |
-// Copyright 2011 the V8 project authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "src/scopeinfo.h" |
- |
-#include <stdlib.h> |
- |
-#include "src/bootstrapper.h" |
-#include "src/scopes.h" |
- |
-namespace v8 { |
-namespace internal { |
- |
- |
-Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
- Scope* scope) { |
- // Collect stack and context locals. |
- ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); |
- ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); |
- ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone); |
- ZoneList<Variable*> strong_mode_free_variables(0, zone); |
- |
- scope->CollectStackAndContextLocals(&stack_locals, &context_locals, |
- &context_globals, |
- &strong_mode_free_variables); |
- const int stack_local_count = stack_locals.length(); |
- const int context_local_count = context_locals.length(); |
- const int context_global_count = context_globals.length(); |
- const int strong_mode_free_variable_count = |
- strong_mode_free_variables.length(); |
- // Make sure we allocate the correct amount. |
- DCHECK_EQ(scope->ContextLocalCount(), context_local_count); |
- DCHECK_EQ(scope->ContextGlobalCount(), context_global_count); |
- |
- // Determine use and location of the "this" binding if it is present. |
- VariableAllocationInfo receiver_info; |
- if (scope->has_this_declaration()) { |
- Variable* var = scope->receiver(); |
- if (!var->is_used()) { |
- receiver_info = UNUSED; |
- } else if (var->IsContextSlot()) { |
- receiver_info = CONTEXT; |
- } else { |
- DCHECK(var->IsParameter()); |
- receiver_info = STACK; |
- } |
- } else { |
- receiver_info = NONE; |
- } |
- |
- // Determine use and location of the function variable if it is present. |
- VariableAllocationInfo function_name_info; |
- VariableMode function_variable_mode; |
- if (scope->is_function_scope() && scope->function() != NULL) { |
- Variable* var = scope->function()->proxy()->var(); |
- if (!var->is_used()) { |
- function_name_info = UNUSED; |
- } else if (var->IsContextSlot()) { |
- function_name_info = CONTEXT; |
- } else { |
- DCHECK(var->IsStackLocal()); |
- function_name_info = STACK; |
- } |
- function_variable_mode = var->mode(); |
- } else { |
- function_name_info = NONE; |
- function_variable_mode = VAR; |
- } |
- DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE); |
- |
- const bool has_function_name = function_name_info != NONE; |
- const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; |
- const int parameter_count = scope->num_parameters(); |
- const int length = kVariablePartIndex + parameter_count + |
- (1 + stack_local_count) + 2 * context_local_count + |
- 2 * context_global_count + |
- 3 * strong_mode_free_variable_count + |
- (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); |
- |
- Factory* factory = isolate->factory(); |
- Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
- |
- bool has_simple_parameters = |
- scope->is_function_scope() && scope->has_simple_parameters(); |
- |
- // Encode the flags. |
- int flags = ScopeTypeField::encode(scope->scope_type()) | |
- CallsEvalField::encode(scope->calls_eval()) | |
- LanguageModeField::encode(scope->language_mode()) | |
- DeclarationScopeField::encode(scope->is_declaration_scope()) | |
- ReceiverVariableField::encode(receiver_info) | |
- FunctionVariableField::encode(function_name_info) | |
- FunctionVariableMode::encode(function_variable_mode) | |
- AsmModuleField::encode(scope->asm_module()) | |
- AsmFunctionField::encode(scope->asm_function()) | |
- HasSimpleParametersField::encode(has_simple_parameters) | |
- FunctionKindField::encode(scope->function_kind()); |
- scope_info->SetFlags(flags); |
- scope_info->SetParameterCount(parameter_count); |
- scope_info->SetStackLocalCount(stack_local_count); |
- scope_info->SetContextLocalCount(context_local_count); |
- scope_info->SetContextGlobalCount(context_global_count); |
- scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); |
- |
- int index = kVariablePartIndex; |
- // Add parameters. |
- DCHECK(index == scope_info->ParameterEntriesIndex()); |
- for (int i = 0; i < parameter_count; ++i) { |
- scope_info->set(index++, *scope->parameter(i)->name()); |
- } |
- |
- // Add stack locals' names. We are assuming that the stack locals' |
- // slots are allocated in increasing order, so we can simply add |
- // them to the ScopeInfo object. |
- int first_slot_index; |
- if (stack_local_count > 0) { |
- first_slot_index = stack_locals[0]->index(); |
- } else { |
- first_slot_index = 0; |
- } |
- DCHECK(index == scope_info->StackLocalFirstSlotIndex()); |
- scope_info->set(index++, Smi::FromInt(first_slot_index)); |
- DCHECK(index == scope_info->StackLocalEntriesIndex()); |
- for (int i = 0; i < stack_local_count; ++i) { |
- DCHECK(stack_locals[i]->index() == first_slot_index + i); |
- scope_info->set(index++, *stack_locals[i]->name()); |
- } |
- |
- // Due to usage analysis, context-allocated locals are not necessarily in |
- // increasing order: Some of them may be parameters which are allocated before |
- // the non-parameter locals. When the non-parameter locals are sorted |
- // according to usage, the allocated slot indices may not be in increasing |
- // order with the variable list anymore. Thus, we first need to sort them by |
- // context slot index before adding them to the ScopeInfo object. |
- context_locals.Sort(&Variable::CompareIndex); |
- |
- // Add context locals' names. |
- DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); |
- for (int i = 0; i < context_local_count; ++i) { |
- scope_info->set(index++, *context_locals[i]->name()); |
- } |
- |
- // Add context globals' names. |
- DCHECK(index == scope_info->ContextGlobalNameEntriesIndex()); |
- for (int i = 0; i < context_global_count; ++i) { |
- scope_info->set(index++, *context_globals[i]->name()); |
- } |
- |
- // Add context locals' info. |
- DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); |
- for (int i = 0; i < context_local_count; ++i) { |
- Variable* var = context_locals[i]; |
- uint32_t value = |
- ContextLocalMode::encode(var->mode()) | |
- ContextLocalInitFlag::encode(var->initialization_flag()) | |
- ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); |
- scope_info->set(index++, Smi::FromInt(value)); |
- } |
- |
- // Add context globals' info. |
- DCHECK(index == scope_info->ContextGlobalInfoEntriesIndex()); |
- for (int i = 0; i < context_global_count; ++i) { |
- Variable* var = context_globals[i]; |
- // TODO(ishell): do we need this kind of info for globals here? |
- uint32_t value = |
- ContextLocalMode::encode(var->mode()) | |
- ContextLocalInitFlag::encode(var->initialization_flag()) | |
- ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); |
- scope_info->set(index++, Smi::FromInt(value)); |
- } |
- |
- DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); |
- for (int i = 0; i < strong_mode_free_variable_count; ++i) { |
- scope_info->set(index++, *strong_mode_free_variables[i]->name()); |
- } |
- |
- DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); |
- for (int i = 0; i < strong_mode_free_variable_count; ++i) { |
- // Unfortunately, the source code positions are stored as int even though |
- // int32_t would be enough (given the maximum source code length). |
- Handle<Object> start_position = factory->NewNumberFromInt( |
- static_cast<int32_t>(strong_mode_free_variables[i] |
- ->strong_mode_reference_start_position())); |
- scope_info->set(index++, *start_position); |
- Handle<Object> end_position = factory->NewNumberFromInt( |
- static_cast<int32_t>(strong_mode_free_variables[i] |
- ->strong_mode_reference_end_position())); |
- scope_info->set(index++, *end_position); |
- } |
- |
- // If the receiver is allocated, add its index. |
- DCHECK(index == scope_info->ReceiverEntryIndex()); |
- if (has_receiver) { |
- int var_index = scope->receiver()->index(); |
- scope_info->set(index++, Smi::FromInt(var_index)); |
- // ?? DCHECK(receiver_info != CONTEXT || var_index == |
- // scope_info->ContextLength() - 1); |
- } |
- |
- // If present, add the function variable name and its index. |
- DCHECK(index == scope_info->FunctionNameEntryIndex()); |
- if (has_function_name) { |
- int var_index = scope->function()->proxy()->var()->index(); |
- scope_info->set(index++, *scope->function()->proxy()->name()); |
- scope_info->set(index++, Smi::FromInt(var_index)); |
- DCHECK(function_name_info != CONTEXT || |
- var_index == scope_info->ContextLength() - 1); |
- } |
- |
- DCHECK(index == scope_info->length()); |
- DCHECK(scope->num_parameters() == scope_info->ParameterCount()); |
- DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || |
- (scope->num_heap_slots() == kVariablePartIndex && |
- scope_info->ContextLength() == 0)); |
- return scope_info; |
-} |
- |
- |
-Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { |
- DCHECK(isolate->bootstrapper()->IsActive()); |
- |
- const int stack_local_count = 0; |
- const int context_local_count = 1; |
- const int context_global_count = 0; |
- const int strong_mode_free_variable_count = 0; |
- const bool has_simple_parameters = true; |
- const VariableAllocationInfo receiver_info = CONTEXT; |
- const VariableAllocationInfo function_name_info = NONE; |
- const VariableMode function_variable_mode = VAR; |
- const bool has_function_name = false; |
- const bool has_receiver = true; |
- const int parameter_count = 0; |
- const int length = kVariablePartIndex + parameter_count + |
- (1 + stack_local_count) + 2 * context_local_count + |
- 2 * context_global_count + |
- 3 * strong_mode_free_variable_count + |
- (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); |
- |
- Factory* factory = isolate->factory(); |
- Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
- |
- // Encode the flags. |
- int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | |
- CallsEvalField::encode(false) | |
- LanguageModeField::encode(SLOPPY) | |
- DeclarationScopeField::encode(true) | |
- ReceiverVariableField::encode(receiver_info) | |
- FunctionVariableField::encode(function_name_info) | |
- FunctionVariableMode::encode(function_variable_mode) | |
- AsmModuleField::encode(false) | AsmFunctionField::encode(false) | |
- HasSimpleParametersField::encode(has_simple_parameters) | |
- FunctionKindField::encode(FunctionKind::kNormalFunction); |
- scope_info->SetFlags(flags); |
- scope_info->SetParameterCount(parameter_count); |
- scope_info->SetStackLocalCount(stack_local_count); |
- scope_info->SetContextLocalCount(context_local_count); |
- scope_info->SetContextGlobalCount(context_global_count); |
- scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); |
- |
- int index = kVariablePartIndex; |
- const int first_slot_index = 0; |
- DCHECK(index == scope_info->StackLocalFirstSlotIndex()); |
- scope_info->set(index++, Smi::FromInt(first_slot_index)); |
- DCHECK(index == scope_info->StackLocalEntriesIndex()); |
- |
- // Here we add info for context-allocated "this". |
- DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); |
- scope_info->set(index++, *isolate->factory()->this_string()); |
- DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); |
- const uint32_t value = ContextLocalMode::encode(CONST) | |
- ContextLocalInitFlag::encode(kCreatedInitialized) | |
- ContextLocalMaybeAssignedFlag::encode(kNotAssigned); |
- scope_info->set(index++, Smi::FromInt(value)); |
- |
- DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); |
- DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); |
- |
- // And here we record that this scopeinfo binds a receiver. |
- DCHECK(index == scope_info->ReceiverEntryIndex()); |
- const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0; |
- scope_info->set(index++, Smi::FromInt(receiver_index)); |
- |
- DCHECK(index == scope_info->FunctionNameEntryIndex()); |
- |
- DCHECK_EQ(index, scope_info->length()); |
- DCHECK_EQ(scope_info->ParameterCount(), 0); |
- DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1); |
- |
- return scope_info; |
-} |
- |
- |
-ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { |
- return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array()); |
-} |
- |
- |
-ScopeType ScopeInfo::scope_type() { |
- DCHECK(length() > 0); |
- return ScopeTypeField::decode(Flags()); |
-} |
- |
- |
-bool ScopeInfo::CallsEval() { |
- return length() > 0 && CallsEvalField::decode(Flags()); |
-} |
- |
- |
-LanguageMode ScopeInfo::language_mode() { |
- return length() > 0 ? LanguageModeField::decode(Flags()) : SLOPPY; |
-} |
- |
- |
-bool ScopeInfo::is_declaration_scope() { |
- return DeclarationScopeField::decode(Flags()); |
-} |
- |
- |
-int ScopeInfo::LocalCount() { |
- return StackLocalCount() + ContextLocalCount(); |
-} |
- |
- |
-int ScopeInfo::StackSlotCount() { |
- if (length() > 0) { |
- bool function_name_stack_slot = |
- FunctionVariableField::decode(Flags()) == STACK; |
- return StackLocalCount() + (function_name_stack_slot ? 1 : 0); |
- } |
- return 0; |
-} |
- |
- |
-int ScopeInfo::ContextLength() { |
- if (length() > 0) { |
- int context_locals = ContextLocalCount(); |
- int context_globals = ContextGlobalCount(); |
- bool function_name_context_slot = |
- FunctionVariableField::decode(Flags()) == CONTEXT; |
- bool has_context = context_locals > 0 || context_globals > 0 || |
- function_name_context_slot || |
- scope_type() == WITH_SCOPE || |
- (scope_type() == BLOCK_SCOPE && CallsSloppyEval() && |
- is_declaration_scope()) || |
- (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || |
- scope_type() == MODULE_SCOPE; |
- |
- if (has_context) { |
- return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals + |
- (function_name_context_slot ? 1 : 0); |
- } |
- } |
- return 0; |
-} |
- |
- |
-bool ScopeInfo::HasReceiver() { |
- if (length() > 0) { |
- return NONE != ReceiverVariableField::decode(Flags()); |
- } else { |
- return false; |
- } |
-} |
- |
- |
-bool ScopeInfo::HasAllocatedReceiver() { |
- if (length() > 0) { |
- VariableAllocationInfo allocation = ReceiverVariableField::decode(Flags()); |
- return allocation == STACK || allocation == CONTEXT; |
- } else { |
- return false; |
- } |
-} |
- |
- |
-bool ScopeInfo::HasFunctionName() { |
- if (length() > 0) { |
- return NONE != FunctionVariableField::decode(Flags()); |
- } else { |
- return false; |
- } |
-} |
- |
- |
-bool ScopeInfo::HasHeapAllocatedLocals() { |
- if (length() > 0) { |
- return ContextLocalCount() > 0; |
- } else { |
- return false; |
- } |
-} |
- |
- |
-bool ScopeInfo::HasContext() { |
- return ContextLength() > 0; |
-} |
- |
- |
-String* ScopeInfo::FunctionName() { |
- DCHECK(HasFunctionName()); |
- return String::cast(get(FunctionNameEntryIndex())); |
-} |
- |
- |
-String* ScopeInfo::ParameterName(int var) { |
- DCHECK(0 <= var && var < ParameterCount()); |
- int info_index = ParameterEntriesIndex() + var; |
- return String::cast(get(info_index)); |
-} |
- |
- |
-String* ScopeInfo::LocalName(int var) { |
- DCHECK(0 <= var && var < LocalCount()); |
- DCHECK(StackLocalEntriesIndex() + StackLocalCount() == |
- ContextLocalNameEntriesIndex()); |
- int info_index = StackLocalEntriesIndex() + var; |
- return String::cast(get(info_index)); |
-} |
- |
- |
-String* ScopeInfo::StackLocalName(int var) { |
- DCHECK(0 <= var && var < StackLocalCount()); |
- int info_index = StackLocalEntriesIndex() + var; |
- return String::cast(get(info_index)); |
-} |
- |
- |
-int ScopeInfo::StackLocalIndex(int var) { |
- DCHECK(0 <= var && var < StackLocalCount()); |
- int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value(); |
- return first_slot_index + var; |
-} |
- |
- |
-String* ScopeInfo::ContextLocalName(int var) { |
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
- int info_index = ContextLocalNameEntriesIndex() + var; |
- return String::cast(get(info_index)); |
-} |
- |
- |
-VariableMode ScopeInfo::ContextLocalMode(int var) { |
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
- int info_index = ContextLocalInfoEntriesIndex() + var; |
- int value = Smi::cast(get(info_index))->value(); |
- return ContextLocalMode::decode(value); |
-} |
- |
- |
-InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) { |
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
- int info_index = ContextLocalInfoEntriesIndex() + var; |
- int value = Smi::cast(get(info_index))->value(); |
- return ContextLocalInitFlag::decode(value); |
-} |
- |
- |
-MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) { |
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
- int info_index = ContextLocalInfoEntriesIndex() + var; |
- int value = Smi::cast(get(info_index))->value(); |
- return ContextLocalMaybeAssignedFlag::decode(value); |
-} |
- |
- |
-bool ScopeInfo::LocalIsSynthetic(int var) { |
- DCHECK(0 <= var && var < LocalCount()); |
- // There's currently no flag stored on the ScopeInfo to indicate that a |
- // variable is a compiler-introduced temporary. However, to avoid conflict |
- // with user declarations, the current temporaries like .generator_object and |
- // .result start with a dot, so we can use that as a flag. It's a hack! |
- Handle<String> name(LocalName(var)); |
- return (name->length() > 0 && name->Get(0) == '.') || |
- name->Equals(*GetIsolate()->factory()->this_string()); |
-} |
- |
- |
-String* ScopeInfo::StrongModeFreeVariableName(int var) { |
- DCHECK(0 <= var && var < StrongModeFreeVariableCount()); |
- int info_index = StrongModeFreeVariableNameEntriesIndex() + var; |
- return String::cast(get(info_index)); |
-} |
- |
- |
-int ScopeInfo::StrongModeFreeVariableStartPosition(int var) { |
- DCHECK(0 <= var && var < StrongModeFreeVariableCount()); |
- int info_index = StrongModeFreeVariablePositionEntriesIndex() + var * 2; |
- int32_t value = 0; |
- bool ok = get(info_index)->ToInt32(&value); |
- USE(ok); |
- DCHECK(ok); |
- return value; |
-} |
- |
- |
-int ScopeInfo::StrongModeFreeVariableEndPosition(int var) { |
- DCHECK(0 <= var && var < StrongModeFreeVariableCount()); |
- int info_index = StrongModeFreeVariablePositionEntriesIndex() + var * 2 + 1; |
- int32_t value = 0; |
- bool ok = get(info_index)->ToInt32(&value); |
- USE(ok); |
- DCHECK(ok); |
- return value; |
-} |
- |
- |
-int ScopeInfo::StackSlotIndex(String* name) { |
- DCHECK(name->IsInternalizedString()); |
- if (length() > 0) { |
- int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value(); |
- int start = StackLocalEntriesIndex(); |
- int end = StackLocalEntriesIndex() + StackLocalCount(); |
- for (int i = start; i < end; ++i) { |
- if (name == get(i)) { |
- return i - start + first_slot_index; |
- } |
- } |
- } |
- return -1; |
-} |
- |
- |
-int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, |
- Handle<String> name, VariableMode* mode, |
- InitializationFlag* init_flag, |
- MaybeAssignedFlag* maybe_assigned_flag) { |
- DCHECK(name->IsInternalizedString()); |
- DCHECK(mode != NULL); |
- DCHECK(init_flag != NULL); |
- if (scope_info->length() > 0) { |
- ContextSlotCache* context_slot_cache = |
- scope_info->GetIsolate()->context_slot_cache(); |
- int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag, |
- maybe_assigned_flag); |
- if (result != ContextSlotCache::kNotFound) { |
- DCHECK(result < scope_info->ContextLength()); |
- return result; |
- } |
- |
- int start = scope_info->ContextLocalNameEntriesIndex(); |
- int end = scope_info->ContextLocalNameEntriesIndex() + |
- scope_info->ContextLocalCount(); |
- for (int i = start; i < end; ++i) { |
- if (*name == scope_info->get(i)) { |
- int var = i - start; |
- *mode = scope_info->ContextLocalMode(var); |
- *init_flag = scope_info->ContextLocalInitFlag(var); |
- *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); |
- result = Context::MIN_CONTEXT_SLOTS + var; |
- |
- context_slot_cache->Update(scope_info, name, *mode, *init_flag, |
- *maybe_assigned_flag, result); |
- DCHECK(result < scope_info->ContextLength()); |
- return result; |
- } |
- } |
- // Cache as not found. Mode, init flag and maybe assigned flag don't matter. |
- context_slot_cache->Update(scope_info, name, TEMPORARY, |
- kNeedsInitialization, kNotAssigned, -1); |
- } |
- return -1; |
-} |
- |
- |
-int ScopeInfo::ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info, |
- Handle<String> name, VariableMode* mode, |
- InitializationFlag* init_flag, |
- MaybeAssignedFlag* maybe_assigned_flag) { |
- DCHECK(name->IsInternalizedString()); |
- DCHECK(mode != NULL); |
- DCHECK(init_flag != NULL); |
- if (scope_info->length() > 0) { |
- // This is to ensure that ContextLocalMode() and co. queries would work. |
- DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(), |
- scope_info->ContextLocalNameEntriesIndex() + |
- scope_info->ContextLocalCount()); |
- int base = scope_info->ContextLocalNameEntriesIndex(); |
- int start = scope_info->ContextGlobalNameEntriesIndex(); |
- int end = scope_info->ContextGlobalNameEntriesIndex() + |
- scope_info->ContextGlobalCount(); |
- for (int i = start; i < end; ++i) { |
- if (*name == scope_info->get(i)) { |
- int var = i - base; |
- *mode = scope_info->ContextLocalMode(var); |
- *init_flag = scope_info->ContextLocalInitFlag(var); |
- *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); |
- int result = Context::MIN_CONTEXT_SLOTS + var; |
- DCHECK(result < scope_info->ContextLength()); |
- return result; |
- } |
- } |
- } |
- return -1; |
-} |
- |
- |
-String* ScopeInfo::ContextSlotName(int slot_index) { |
- int const var = slot_index - Context::MIN_CONTEXT_SLOTS; |
- DCHECK_LE(0, var); |
- DCHECK_LT(var, ContextLocalCount() + ContextGlobalCount()); |
- return ContextLocalName(var); |
-} |
- |
- |
-int ScopeInfo::ParameterIndex(String* name) { |
- DCHECK(name->IsInternalizedString()); |
- if (length() > 0) { |
- // We must read parameters from the end since for |
- // multiply declared parameters the value of the |
- // last declaration of that parameter is used |
- // inside a function (and thus we need to look |
- // at the last index). Was bug# 1110337. |
- int start = ParameterEntriesIndex(); |
- int end = ParameterEntriesIndex() + ParameterCount(); |
- for (int i = end - 1; i >= start; --i) { |
- if (name == get(i)) { |
- return i - start; |
- } |
- } |
- } |
- return -1; |
-} |
- |
- |
-int ScopeInfo::ReceiverContextSlotIndex() { |
- if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT) |
- return Smi::cast(get(ReceiverEntryIndex()))->value(); |
- return -1; |
-} |
- |
- |
-int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) { |
- DCHECK(name->IsInternalizedString()); |
- DCHECK(mode != NULL); |
- if (length() > 0) { |
- if (FunctionVariableField::decode(Flags()) == CONTEXT && |
- FunctionName() == name) { |
- *mode = FunctionVariableMode::decode(Flags()); |
- return Smi::cast(get(FunctionNameEntryIndex() + 1))->value(); |
- } |
- } |
- return -1; |
-} |
- |
- |
-FunctionKind ScopeInfo::function_kind() { |
- return FunctionKindField::decode(Flags()); |
-} |
- |
- |
-int ScopeInfo::ParameterEntriesIndex() { |
- DCHECK(length() > 0); |
- return kVariablePartIndex; |
-} |
- |
- |
-int ScopeInfo::StackLocalFirstSlotIndex() { |
- return ParameterEntriesIndex() + ParameterCount(); |
-} |
- |
- |
-int ScopeInfo::StackLocalEntriesIndex() { |
- return StackLocalFirstSlotIndex() + 1; |
-} |
- |
- |
-int ScopeInfo::ContextLocalNameEntriesIndex() { |
- return StackLocalEntriesIndex() + StackLocalCount(); |
-} |
- |
- |
-int ScopeInfo::ContextGlobalNameEntriesIndex() { |
- return ContextLocalNameEntriesIndex() + ContextLocalCount(); |
-} |
- |
- |
-int ScopeInfo::ContextLocalInfoEntriesIndex() { |
- return ContextGlobalNameEntriesIndex() + ContextGlobalCount(); |
-} |
- |
- |
-int ScopeInfo::ContextGlobalInfoEntriesIndex() { |
- return ContextLocalInfoEntriesIndex() + ContextLocalCount(); |
-} |
- |
- |
-int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() { |
- return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); |
-} |
- |
- |
-int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { |
- return StrongModeFreeVariableNameEntriesIndex() + |
- StrongModeFreeVariableCount(); |
-} |
- |
- |
-int ScopeInfo::ReceiverEntryIndex() { |
- return StrongModeFreeVariablePositionEntriesIndex() + |
- 2 * StrongModeFreeVariableCount(); |
-} |
- |
- |
-int ScopeInfo::FunctionNameEntryIndex() { |
- return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); |
-} |
- |
- |
-int ContextSlotCache::Hash(Object* data, String* name) { |
- // Uses only lower 32 bits if pointers are larger. |
- uintptr_t addr_hash = |
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; |
- return static_cast<int>((addr_hash ^ name->Hash()) % kLength); |
-} |
- |
- |
-int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, |
- InitializationFlag* init_flag, |
- MaybeAssignedFlag* maybe_assigned_flag) { |
- int index = Hash(data, name); |
- Key& key = keys_[index]; |
- if ((key.data == data) && key.name->Equals(name)) { |
- Value result(values_[index]); |
- if (mode != NULL) *mode = result.mode(); |
- if (init_flag != NULL) *init_flag = result.initialization_flag(); |
- if (maybe_assigned_flag != NULL) |
- *maybe_assigned_flag = result.maybe_assigned_flag(); |
- return result.index() + kNotFound; |
- } |
- return kNotFound; |
-} |
- |
- |
-void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, |
- VariableMode mode, InitializationFlag init_flag, |
- MaybeAssignedFlag maybe_assigned_flag, |
- int slot_index) { |
- DisallowHeapAllocation no_gc; |
- Handle<String> internalized_name; |
- DCHECK(slot_index > kNotFound); |
- if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). |
- ToHandle(&internalized_name)) { |
- int index = Hash(*data, *internalized_name); |
- Key& key = keys_[index]; |
- key.data = *data; |
- key.name = *internalized_name; |
- // Please note value only takes a uint as index. |
- values_[index] = Value(mode, init_flag, maybe_assigned_flag, |
- slot_index - kNotFound).raw(); |
-#ifdef DEBUG |
- ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); |
-#endif |
- } |
-} |
- |
- |
-void ContextSlotCache::Clear() { |
- for (int index = 0; index < kLength; index++) keys_[index].data = NULL; |
-} |
- |
- |
-#ifdef DEBUG |
- |
-void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, |
- VariableMode mode, |
- InitializationFlag init_flag, |
- MaybeAssignedFlag maybe_assigned_flag, |
- int slot_index) { |
- DisallowHeapAllocation no_gc; |
- Handle<String> internalized_name; |
- if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). |
- ToHandle(&internalized_name)) { |
- int index = Hash(*data, *name); |
- Key& key = keys_[index]; |
- DCHECK(key.data == *data); |
- DCHECK(key.name->Equals(*name)); |
- Value result(values_[index]); |
- DCHECK(result.mode() == mode); |
- DCHECK(result.initialization_flag() == init_flag); |
- DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); |
- DCHECK(result.index() + kNotFound == slot_index); |
- } |
-} |
- |
- |
-static void PrintList(const char* list_name, |
- int nof_internal_slots, |
- int start, |
- int end, |
- ScopeInfo* scope_info) { |
- if (start < end) { |
- PrintF("\n // %s\n", list_name); |
- if (nof_internal_slots > 0) { |
- PrintF(" %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1); |
- } |
- for (int i = nof_internal_slots; start < end; ++i, ++start) { |
- PrintF(" %2d ", i); |
- String::cast(scope_info->get(start))->ShortPrint(); |
- PrintF("\n"); |
- } |
- } |
-} |
- |
- |
-void ScopeInfo::Print() { |
- PrintF("ScopeInfo "); |
- if (HasFunctionName()) { |
- FunctionName()->ShortPrint(); |
- } else { |
- PrintF("/* no function name */"); |
- } |
- PrintF("{"); |
- |
- if (length() > 0) { |
- PrintList("parameters", 0, ParameterEntriesIndex(), |
- ParameterEntriesIndex() + ParameterCount(), this); |
- PrintList("stack slots", 0, StackLocalEntriesIndex(), |
- StackLocalEntriesIndex() + StackLocalCount(), this); |
- PrintList("context slots", Context::MIN_CONTEXT_SLOTS, |
- ContextLocalNameEntriesIndex(), |
- ContextLocalNameEntriesIndex() + ContextLocalCount(), this); |
- } |
- |
- PrintF("}\n"); |
-} |
-#endif // DEBUG |
- |
- |
-//--------------------------------------------------------------------------- |
-// ModuleInfo. |
- |
-Handle<ModuleInfo> ModuleInfo::Create(Isolate* isolate, |
- ModuleDescriptor* descriptor, |
- Scope* scope) { |
- Handle<ModuleInfo> info = Allocate(isolate, descriptor->Length()); |
- info->set_host_index(descriptor->Index()); |
- int i = 0; |
- for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done(); |
- it.Advance(), ++i) { |
- Variable* var = scope->LookupLocal(it.local_name()); |
- info->set_name(i, *(it.export_name()->string())); |
- info->set_mode(i, var->mode()); |
- DCHECK(var->index() >= 0); |
- info->set_index(i, var->index()); |
- } |
- DCHECK(i == info->length()); |
- return info; |
-} |
- |
-} // namespace internal |
-} // namespace v8 |