Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Unified Diff: src/scopeinfo.cc

Issue 1218783005: Support for global var shortcuts in script contexts. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixing builds Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/scopeinfo.h ('k') | src/scopes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/scopeinfo.cc
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index f77ef96ebac4cd8da6bd33f1bd58936a021f354f..4ed22b19dcd9a37b60f07aacd92b09c923079ca2 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);
@@ -94,6 +100,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;
@@ -134,6 +141,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) {
@@ -145,6 +158,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());
@@ -197,6 +222,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;
@@ -207,6 +233,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);
@@ -227,6 +254,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;
@@ -301,16 +329,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;
@@ -396,14 +427,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);
@@ -411,7 +442,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);
@@ -419,7 +450,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);
@@ -485,39 +516,56 @@ int ScopeInfo::StackSlotIndex(String* name) {
int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
Handle<String> name, VariableMode* mode,
+ VariableLocation* location,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag) {
DCHECK(name->IsInternalizedString());
DCHECK(mode != NULL);
+ DCHECK(location != 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, location,
+ 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()) {
+ *location = VariableLocation::CONTEXT;
+ result = Context::MIN_CONTEXT_SLOTS + var;
+ } else {
+ var -= scope_info->ContextLocalCount();
+ *location = VariableLocation::GLOBAL;
+ result = Context::MIN_CONTEXT_SLOTS +
+ scope_info->ContextLocalCount() + 2 * var;
+ }
+
+ context_slot_cache->Update(scope_info, name, *mode, *location,
+ *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,
+ // Cache as not found. Mode, location, init flag and maybe assigned flag
+ // don't matter.
+ context_slot_cache->Update(scope_info, name, INTERNAL,
+ VariableLocation::CONTEXT, kNeedsInitialization,
kNotAssigned, -1);
}
return -1;
@@ -615,16 +663,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();
@@ -651,6 +709,7 @@ int ContextSlotCache::Hash(Object* data, String* name) {
int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode,
+ VariableLocation* location,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag) {
int index = Hash(data, name);
@@ -658,6 +717,7 @@ 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 (location != NULL) *location = result.location();
if (init_flag != NULL) *init_flag = result.initialization_flag();
if (maybe_assigned_flag != NULL)
*maybe_assigned_flag = result.maybe_assigned_flag();
@@ -668,7 +728,8 @@ 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, VariableLocation location,
+ InitializationFlag init_flag,
MaybeAssignedFlag maybe_assigned_flag,
int slot_index) {
DisallowHeapAllocation no_gc;
@@ -681,10 +742,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,
+ values_[index] = Value(mode, location, 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, location, init_flag, maybe_assigned_flag,
+ slot_index);
#endif
}
}
@@ -699,6 +761,7 @@ void ContextSlotCache::Clear() {
void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name,
VariableMode mode,
+ VariableLocation location,
InitializationFlag init_flag,
MaybeAssignedFlag maybe_assigned_flag,
int slot_index) {
@@ -712,6 +775,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.location() == location);
DCHECK(result.initialization_flag() == init_flag);
DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag);
DCHECK(result.index() + kNotFound == slot_index);
« no previous file with comments | « src/scopeinfo.h ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698