Index: src/ast/scopeinfo.cc |
diff --git a/src/ast/scopeinfo.cc b/src/ast/scopeinfo.cc |
index 92de295288cfbeb61e7911331426383e1cd07aa6..5725ee3e09df4751b53bc17291d75c490f53cb09 100644 |
--- a/src/ast/scopeinfo.cc |
+++ b/src/ast/scopeinfo.cc |
@@ -15,16 +15,26 @@ namespace internal { |
Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
Scope* scope) { |
// Collect variables. |
- ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); |
- ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); |
- ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone); |
- scope->CollectVariables(&stack_locals, &context_locals, &context_globals); |
- const int stack_local_count = stack_locals.length(); |
- const int context_local_count = context_locals.length(); |
- const int context_global_count = context_globals.length(); |
+ ZoneList<Variable*>* locals = scope->locals(); |
+ int stack_local_count = 0; |
+ int context_local_count = 0; |
+ // Stack allocated block scope variables are allocated in the parent |
+ // declaration scope, but are recorded in the block scope's scope info. First |
+ // slot index indicates at which offset a particular scope starts in the |
+ // parent declaration scope. |
+ int first_slot_index = 0; |
+ for (int i = 0; i < locals->length(); i++) { |
+ Variable* var = locals->at(i); |
+ if (var->IsStackLocal()) { |
+ if (stack_local_count == 0) first_slot_index = var->index(); |
+ stack_local_count++; |
+ } else if (var->IsContextSlot()) { |
+ context_local_count++; |
+ } |
+ } |
+ |
// 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; |
@@ -66,14 +76,12 @@ 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 + |
(has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); |
Factory* factory = isolate->factory(); |
@@ -108,7 +116,6 @@ 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); |
int index = kVariablePartIndex; |
// Add parameters. |
@@ -120,59 +127,44 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
} |
} |
- // 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; |
- } |
+ // Add stack locals' names, context locals' names and info. We are assuming |
+ // that the stack locals' slots are allocated in increasing order, so we can |
+ // simply add them to the ScopeInfo object. Context locals are added using |
+ // their index. |
DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex()); |
scope_info->set(index++, Smi::FromInt(first_slot_index)); |
DCHECK_EQ(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()); |
- } |
- // Add context locals' names and info. Info lies beyond context globals' |
- // names. |
- // Make sure to store them in the order that they appear in the context. |
- DCHECK_EQ(index, scope_info->ContextLocalNameEntriesIndex()); |
- int info_index = index + context_local_count + context_global_count; |
- DCHECK_EQ(info_index, scope_info->ContextLocalInfoEntriesIndex()); |
- for (int i = 0; i < context_local_count; ++i) { |
- Variable* var = context_locals[i]; |
- int context_index = var->index() - Context::MIN_CONTEXT_SLOTS; |
- uint32_t info = VariableModeField::encode(var->mode()) | |
- InitFlagField::encode(var->initialization_flag()) | |
- MaybeAssignedFlagField::encode(var->maybe_assigned()); |
- scope_info->set(index + context_index, *var->name()); |
- scope_info->set(info_index + context_index, Smi::FromInt(info)); |
- } |
- |
- index += context_local_count; |
- |
- // Add context globals' names and info. Info lies beyond context locals' info. |
- DCHECK_EQ(index, scope_info->ContextGlobalNameEntriesIndex()); |
- info_index = index + context_global_count + context_local_count; |
- DCHECK_EQ(info_index, scope_info->ContextGlobalInfoEntriesIndex()); |
- for (int i = 0; i < context_global_count; ++i) { |
- Variable* var = context_globals[i]; |
- scope_info->set(index + i, *var->name()); |
- // TODO(ishell): do we need this kind of info for globals here? |
- uint32_t info = VariableModeField::encode(var->mode()) | |
- InitFlagField::encode(var->initialization_flag()) | |
- MaybeAssignedFlagField::encode(var->maybe_assigned()); |
- scope_info->set(info_index + i, Smi::FromInt(info)); |
+ int stack_local_base = index; |
+ int context_local_base = stack_local_base + stack_local_count; |
+ int context_local_info_base = context_local_base + context_local_count; |
+ |
+ for (int i = 0; i < locals->length(); ++i) { |
+ Variable* var = locals->at(i); |
+ if (var->IsStackLocal()) { |
+ int local_index = var->index() - first_slot_index; |
+ DCHECK_LE(0, local_index); |
+ DCHECK_LT(local_index, stack_local_count); |
+ scope_info->set(stack_local_base + local_index, *var->name()); |
+ } else if (var->IsContextSlot()) { |
+ // Due to duplicate parameters, context locals aren't guaranteed to come |
+ // in order. |
+ int local_index = var->index() - Context::MIN_CONTEXT_SLOTS; |
+ DCHECK_LE(0, local_index); |
+ DCHECK_LT(local_index, context_local_count); |
+ uint32_t info = VariableModeField::encode(var->mode()) | |
+ InitFlagField::encode(var->initialization_flag()) | |
+ MaybeAssignedFlagField::encode(var->maybe_assigned()); |
+ scope_info->set(context_local_base + local_index, *var->name()); |
+ scope_info->set(context_local_info_base + local_index, |
+ Smi::FromInt(info)); |
+ } |
} |
- index += context_local_count + 2 * context_global_count; |
+ index += stack_local_count + 2 * context_local_count; |
// If the receiver is allocated, add its index. |
- DCHECK(index == scope_info->ReceiverEntryIndex()); |
+ DCHECK_EQ(index, scope_info->ReceiverEntryIndex()); |
if (has_receiver) { |
int var_index = scope->AsDeclarationScope()->receiver()->index(); |
scope_info->set(index++, Smi::FromInt(var_index)); |
@@ -181,7 +173,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
} |
// If present, add the function variable name and its index. |
- DCHECK(index == scope_info->FunctionNameEntryIndex()); |
+ DCHECK_EQ(index, scope_info->FunctionNameEntryIndex()); |
if (has_function_name) { |
int var_index = scope->AsDeclarationScope()->function_var()->index(); |
scope_info->set(index++, |
@@ -191,9 +183,9 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
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()); |
+ DCHECK_EQ(index, scope_info->length()); |
+ DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount()); |
+ DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength()); |
return scope_info; |
} |
@@ -203,7 +195,6 @@ 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 bool has_simple_parameters = true; |
const VariableAllocationInfo receiver_info = CONTEXT; |
const VariableAllocationInfo function_name_info = NONE; |
@@ -213,7 +204,6 @@ 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 + |
(has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); |
Factory* factory = isolate->factory(); |
@@ -234,29 +224,28 @@ 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); |
int index = kVariablePartIndex; |
const int first_slot_index = 0; |
- DCHECK(index == scope_info->StackLocalFirstSlotIndex()); |
+ DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex()); |
scope_info->set(index++, Smi::FromInt(first_slot_index)); |
- DCHECK(index == scope_info->StackLocalEntriesIndex()); |
+ DCHECK_EQ(index, scope_info->StackLocalEntriesIndex()); |
// Here we add info for context-allocated "this". |
- DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); |
+ DCHECK_EQ(index, scope_info->ContextLocalNameEntriesIndex()); |
scope_info->set(index++, *isolate->factory()->this_string()); |
- DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); |
+ DCHECK_EQ(index, scope_info->ContextLocalInfoEntriesIndex()); |
const uint32_t value = VariableModeField::encode(CONST) | |
InitFlagField::encode(kCreatedInitialized) | |
MaybeAssignedFlagField::encode(kNotAssigned); |
scope_info->set(index++, Smi::FromInt(value)); |
// And here we record that this scopeinfo binds a receiver. |
- DCHECK(index == scope_info->ReceiverEntryIndex()); |
+ DCHECK_EQ(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->FunctionNameEntryIndex()); |
DCHECK_EQ(index, scope_info->length()); |
DCHECK_EQ(scope_info->ParameterCount(), 0); |
@@ -272,7 +261,7 @@ ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { |
ScopeType ScopeInfo::scope_type() { |
- DCHECK(length() > 0); |
+ DCHECK_LT(0, length()); |
return ScopeTypeField::decode(Flags()); |
} |
@@ -310,19 +299,17 @@ 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 || context_globals > 0 || |
- function_name_context_slot || |
+ bool has_context = context_locals > 0 || function_name_context_slot || |
scope_type() == WITH_SCOPE || |
(scope_type() == BLOCK_SCOPE && CallsSloppyEval() && |
- is_declaration_scope()) || |
+ is_declaration_scope()) || |
(scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || |
scope_type() == MODULE_SCOPE; |
if (has_context) { |
- return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals + |
+ return Context::MIN_CONTEXT_SLOTS + context_locals + |
(function_name_context_slot ? 1 : 0); |
} |
} |
@@ -382,14 +369,16 @@ String* ScopeInfo::FunctionName() { |
String* ScopeInfo::ParameterName(int var) { |
- DCHECK(0 <= var && var < ParameterCount()); |
+ DCHECK_LE(0, var); |
+ DCHECK_LT(var, ParameterCount()); |
int info_index = ParameterEntriesIndex() + var; |
return String::cast(get(info_index)); |
} |
String* ScopeInfo::LocalName(int var) { |
- DCHECK(0 <= var && var < LocalCount()); |
+ DCHECK_LE(0, var); |
+ DCHECK_LT(var, LocalCount()); |
DCHECK(StackLocalEntriesIndex() + StackLocalCount() == |
ContextLocalNameEntriesIndex()); |
int info_index = StackLocalEntriesIndex() + var; |
@@ -398,28 +387,32 @@ String* ScopeInfo::LocalName(int var) { |
String* ScopeInfo::StackLocalName(int var) { |
- DCHECK(0 <= var && var < StackLocalCount()); |
+ DCHECK_LE(0, var); |
+ DCHECK_LT(var, StackLocalCount()); |
int info_index = StackLocalEntriesIndex() + var; |
return String::cast(get(info_index)); |
} |
int ScopeInfo::StackLocalIndex(int var) { |
- DCHECK(0 <= var && var < StackLocalCount()); |
+ DCHECK_LE(0, var); |
+ DCHECK_LT(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()); |
+ DCHECK_LE(0, var); |
+ DCHECK_LT(var, ContextLocalCount()); |
int info_index = ContextLocalNameEntriesIndex() + var; |
return String::cast(get(info_index)); |
} |
VariableMode ScopeInfo::ContextLocalMode(int var) { |
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
+ DCHECK_LE(0, var); |
+ DCHECK_LT(var, ContextLocalCount()); |
int info_index = ContextLocalInfoEntriesIndex() + var; |
int value = Smi::cast(get(info_index))->value(); |
return VariableModeField::decode(value); |
@@ -427,7 +420,8 @@ VariableMode ScopeInfo::ContextLocalMode(int var) { |
InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) { |
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
+ DCHECK_LE(0, var); |
+ DCHECK_LT(var, ContextLocalCount()); |
int info_index = ContextLocalInfoEntriesIndex() + var; |
int value = Smi::cast(get(info_index))->value(); |
return InitFlagField::decode(value); |
@@ -435,7 +429,8 @@ InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) { |
MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) { |
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
+ DCHECK_LE(0, var); |
+ DCHECK_LT(var, ContextLocalCount()); |
int info_index = ContextLocalInfoEntriesIndex() + var; |
int value = Smi::cast(get(info_index))->value(); |
return MaybeAssignedFlagField::decode(value); |
@@ -482,7 +477,7 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, |
int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag, |
maybe_assigned_flag); |
if (result != ContextSlotCache::kNotFound) { |
- DCHECK(result < scope_info->ContextLength()); |
+ DCHECK_LT(result, scope_info->ContextLength()); |
return result; |
} |
@@ -498,7 +493,7 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, |
context_slot_cache->Update(scope_info, name, *mode, *init_flag, |
*maybe_assigned_flag, result); |
- DCHECK(result < scope_info->ContextLength()); |
+ DCHECK_LT(result, scope_info->ContextLength()); |
return result; |
} |
} |
@@ -510,42 +505,10 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, |
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_NOT_NULL(mode); |
- DCHECK_NOT_NULL(init_flag); |
- DCHECK_NOT_NULL(maybe_assigned_flag); |
- 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 = start + 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()); |
+ DCHECK_LT(var, ContextLocalCount()); |
return ContextLocalName(var); |
} |
@@ -579,7 +542,7 @@ int ScopeInfo::ReceiverContextSlotIndex() { |
int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) { |
DCHECK(name->IsInternalizedString()); |
- DCHECK(mode != NULL); |
+ DCHECK_NOT_NULL(mode); |
if (length() > 0) { |
if (FunctionVariableField::decode(Flags()) == CONTEXT && |
FunctionName() == name) { |
@@ -597,7 +560,7 @@ FunctionKind ScopeInfo::function_kind() { |
int ScopeInfo::ParameterEntriesIndex() { |
- DCHECK(length() > 0); |
+ DCHECK_LT(0, length()); |
return kVariablePartIndex; |
} |
@@ -617,23 +580,13 @@ int ScopeInfo::ContextLocalNameEntriesIndex() { |
} |
-int ScopeInfo::ContextGlobalNameEntriesIndex() { |
- return ContextLocalNameEntriesIndex() + ContextLocalCount(); |
-} |
- |
- |
int ScopeInfo::ContextLocalInfoEntriesIndex() { |
- return ContextGlobalNameEntriesIndex() + ContextGlobalCount(); |
-} |
- |
- |
-int ScopeInfo::ContextGlobalInfoEntriesIndex() { |
- return ContextLocalInfoEntriesIndex() + ContextLocalCount(); |
+ return ContextLocalNameEntriesIndex() + ContextLocalCount(); |
} |
int ScopeInfo::ReceiverEntryIndex() { |
- return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); |
+ return ContextLocalInfoEntriesIndex() + ContextLocalCount(); |
} |