| Index: src/scopeinfo.cc
|
| diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
|
| index 8bc0a9a503440441b9ac99ffe2ae60d452c3a5cb..7657affd1df1e592092581cc267ac021a3d16e09 100644
|
| --- a/src/scopeinfo.cc
|
| +++ b/src/scopeinfo.cc
|
| @@ -19,16 +19,20 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| // 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(scope->ContextLocalCount() == context_local_count);
|
| + DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
|
| + DCHECK_EQ(scope->ContextGlobalCount(), context_global_count);
|
|
|
| bool simple_parameter_list =
|
| scope->is_function_scope() ? scope->is_simple_parameter_list() : true;
|
| @@ -67,12 +71,14 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| 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);
|
|
|
| @@ -95,6 +101,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| 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;
|
| @@ -135,6 +142,12 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| 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) {
|
| @@ -146,6 +159,18 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| 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());
|
| @@ -198,6 +223,7 @@ Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
|
|
|
| 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 simple_parameter_list = true;
|
| const VariableAllocationInfo receiver_info = CONTEXT;
|
| @@ -208,6 +234,7 @@ Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
|
| 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);
|
|
|
| @@ -229,6 +256,7 @@ Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
|
| 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;
|
| @@ -303,16 +331,19 @@ int ScopeInfo::StackSlotCount() {
|
| 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 || function_name_context_slot ||
|
| + bool has_context = context_locals > 0 || context_globals > 0 ||
|
| + function_name_context_slot ||
|
| scope_type() == WITH_SCOPE ||
|
| (scope_type() == ARROW_SCOPE && CallsSloppyEval()) ||
|
| (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
|
| scope_type() == MODULE_SCOPE;
|
| +
|
| if (has_context) {
|
| - return Context::MIN_CONTEXT_SLOTS + context_locals +
|
| - (function_name_context_slot ? 1 : 0);
|
| + return Context::MIN_CONTEXT_SLOTS + context_locals + 2 * context_globals +
|
| + (function_name_context_slot ? 1 : 0);
|
| }
|
| }
|
| return 0;
|
| @@ -398,14 +429,14 @@ int ScopeInfo::StackLocalIndex(int var) {
|
|
|
|
|
| String* ScopeInfo::ContextLocalName(int var) {
|
| - DCHECK(0 <= var && var < ContextLocalCount());
|
| + 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());
|
| + DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
|
| int info_index = ContextLocalInfoEntriesIndex() + var;
|
| int value = Smi::cast(get(info_index))->value();
|
| return ContextLocalMode::decode(value);
|
| @@ -413,7 +444,7 @@ VariableMode ScopeInfo::ContextLocalMode(int var) {
|
|
|
|
|
| InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
|
| - DCHECK(0 <= var && var < ContextLocalCount());
|
| + DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
|
| int info_index = ContextLocalInfoEntriesIndex() + var;
|
| int value = Smi::cast(get(info_index))->value();
|
| return ContextLocalInitFlag::decode(value);
|
| @@ -421,7 +452,7 @@ InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
|
|
|
|
|
| MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
|
| - DCHECK(0 <= var && var < ContextLocalCount());
|
| + DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
|
| int info_index = ContextLocalInfoEntriesIndex() + var;
|
| int value = Smi::cast(get(info_index))->value();
|
| return ContextLocalMaybeAssignedFlag::decode(value);
|
| @@ -487,40 +518,57 @@ int ScopeInfo::StackSlotIndex(String* name) {
|
|
|
| int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
|
| Handle<String> name, VariableMode* mode,
|
| + ContextSlotKindFlag* context_slot_kind,
|
| InitializationFlag* init_flag,
|
| MaybeAssignedFlag* maybe_assigned_flag) {
|
| DCHECK(name->IsInternalizedString());
|
| DCHECK(mode != NULL);
|
| + DCHECK(context_slot_kind != 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);
|
| + int result =
|
| + context_slot_cache->Lookup(*scope_info, *name, mode, context_slot_kind,
|
| + init_flag, maybe_assigned_flag);
|
| if (result != ContextSlotCache::kNotFound) {
|
| DCHECK(result < scope_info->ContextLength());
|
| return result;
|
| }
|
|
|
| + DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(),
|
| + scope_info->ContextLocalNameEntriesIndex() +
|
| + scope_info->ContextLocalCount());
|
| int start = scope_info->ContextLocalNameEntriesIndex();
|
| - int end = scope_info->ContextLocalNameEntriesIndex() +
|
| - scope_info->ContextLocalCount();
|
| + int end = scope_info->ContextGlobalNameEntriesIndex() +
|
| + scope_info->ContextGlobalCount();
|
| 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);
|
| +
|
| + if (var < scope_info->ContextLocalCount()) {
|
| + *context_slot_kind = ContextSlotKindFlag::kLocal;
|
| + result = Context::MIN_CONTEXT_SLOTS + var;
|
| + } else {
|
| + var -= scope_info->ContextLocalCount();
|
| + *context_slot_kind = ContextSlotKindFlag::kGlobal;
|
| + result = Context::MIN_CONTEXT_SLOTS +
|
| + scope_info->ContextLocalCount() + 2 * var;
|
| + }
|
| +
|
| + context_slot_cache->Update(scope_info, name, *mode, *context_slot_kind,
|
| + *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, INTERNAL, kNeedsInitialization,
|
| - kNotAssigned, -1);
|
| + context_slot_cache->Update(scope_info, name, INTERNAL,
|
| + ContextSlotKindFlag::kLocal,
|
| + kNeedsInitialization, kNotAssigned, -1);
|
| }
|
| return -1;
|
| }
|
| @@ -622,16 +670,26 @@ int ScopeInfo::ContextLocalNameEntriesIndex() {
|
| }
|
|
|
|
|
| -int ScopeInfo::ContextLocalInfoEntriesIndex() {
|
| +int ScopeInfo::ContextGlobalNameEntriesIndex() {
|
| return ContextLocalNameEntriesIndex() + ContextLocalCount();
|
| }
|
|
|
|
|
| -int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() {
|
| +int ScopeInfo::ContextLocalInfoEntriesIndex() {
|
| + return ContextGlobalNameEntriesIndex() + ContextGlobalCount();
|
| +}
|
| +
|
| +
|
| +int ScopeInfo::ContextGlobalInfoEntriesIndex() {
|
| return ContextLocalInfoEntriesIndex() + ContextLocalCount();
|
| }
|
|
|
|
|
| +int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() {
|
| + return ContextGlobalInfoEntriesIndex() + ContextGlobalCount();
|
| +}
|
| +
|
| +
|
| int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() {
|
| return StrongModeFreeVariableNameEntriesIndex() +
|
| StrongModeFreeVariableCount();
|
| @@ -658,6 +716,7 @@ int ContextSlotCache::Hash(Object* data, String* name) {
|
|
|
|
|
| int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode,
|
| + ContextSlotKindFlag* context_slot_kind,
|
| InitializationFlag* init_flag,
|
| MaybeAssignedFlag* maybe_assigned_flag) {
|
| int index = Hash(data, name);
|
| @@ -665,6 +724,8 @@ int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode,
|
| if ((key.data == data) && key.name->Equals(name)) {
|
| Value result(values_[index]);
|
| if (mode != NULL) *mode = result.mode();
|
| + if (context_slot_kind != NULL)
|
| + *context_slot_kind = result.context_slot_kind();
|
| if (init_flag != NULL) *init_flag = result.initialization_flag();
|
| if (maybe_assigned_flag != NULL)
|
| *maybe_assigned_flag = result.maybe_assigned_flag();
|
| @@ -675,7 +736,9 @@ int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode,
|
|
|
|
|
| void ContextSlotCache::Update(Handle<Object> data, Handle<String> name,
|
| - VariableMode mode, InitializationFlag init_flag,
|
| + VariableMode mode,
|
| + ContextSlotKindFlag context_slot_kind,
|
| + InitializationFlag init_flag,
|
| MaybeAssignedFlag maybe_assigned_flag,
|
| int slot_index) {
|
| DisallowHeapAllocation no_gc;
|
| @@ -688,10 +751,11 @@ void ContextSlotCache::Update(Handle<Object> data, Handle<String> name,
|
| 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();
|
| + values_[index] = Value(mode, context_slot_kind, init_flag,
|
| + maybe_assigned_flag, slot_index - kNotFound).raw();
|
| #ifdef DEBUG
|
| - ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index);
|
| + ValidateEntry(data, name, mode, context_slot_kind, init_flag,
|
| + maybe_assigned_flag, slot_index);
|
| #endif
|
| }
|
| }
|
| @@ -706,6 +770,7 @@ void ContextSlotCache::Clear() {
|
|
|
| void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name,
|
| VariableMode mode,
|
| + ContextSlotKindFlag context_slot_kind,
|
| InitializationFlag init_flag,
|
| MaybeAssignedFlag maybe_assigned_flag,
|
| int slot_index) {
|
| @@ -719,6 +784,7 @@ void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name,
|
| DCHECK(key.name->Equals(*name));
|
| Value result(values_[index]);
|
| DCHECK(result.mode() == mode);
|
| + DCHECK(result.context_slot_kind() == context_slot_kind);
|
| DCHECK(result.initialization_flag() == init_flag);
|
| DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag);
|
| DCHECK(result.index() + kNotFound == slot_index);
|
|
|