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

Unified Diff: src/scopes.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/scopes.h ('k') | src/typing.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/scopes.cc
diff --git a/src/scopes.cc b/src/scopes.cc
index 64f9584d59dcb5974952981386f3ff9a0ba50cd3..f9eef9ab21d990c191df5aee894803c8682700e1 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -14,6 +14,9 @@
namespace v8 {
namespace internal {
+// TODO(ishell): remove this once compiler support is landed.
+bool enable_context_globals = false;
+
// ----------------------------------------------------------------------------
// Implementation of LocalsMap
//
@@ -178,6 +181,7 @@ void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope,
num_var_or_const_ = 0;
num_stack_slots_ = 0;
num_heap_slots_ = 0;
+ num_global_slots_ = 0;
num_modules_ = 0;
module_var_ = NULL,
rest_parameter_ = NULL;
@@ -388,27 +392,32 @@ Variable* Scope::LookupLocal(const AstRawString* name) {
// Check context slot lookup.
VariableMode mode;
- Variable::Location location = Variable::CONTEXT;
+ VariableLocation location;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
- int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
- &init_flag, &maybe_assigned_flag);
+ int index =
+ ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, &location,
+ &init_flag, &maybe_assigned_flag);
if (index < 0) {
// Check parameters.
index = scope_info_->ParameterIndex(*name_handle);
if (index < 0) return NULL;
mode = DYNAMIC;
- location = Variable::LOOKUP;
+ location = VariableLocation::LOOKUP;
init_flag = kCreatedInitialized;
// Be conservative and flag parameters as maybe assigned. Better information
// would require ScopeInfo to serialize the maybe_assigned bit also for
// parameters.
maybe_assigned_flag = kMaybeAssigned;
+ } else {
+ DCHECK(location != VariableLocation::GLOBAL ||
+ (is_script_scope() && IsDeclaredVariableMode(mode) &&
+ !IsLexicalVariableMode(mode)));
}
Variable::Kind kind = Variable::NORMAL;
- if (location == Variable::CONTEXT &&
+ if (location == VariableLocation::CONTEXT &&
index == scope_info_->ReceiverContextSlotIndex()) {
kind = Variable::THIS;
}
@@ -437,7 +446,7 @@ Variable* Scope::LookupFunctionVar(const AstRawString* name,
VariableDeclaration* declaration = factory->NewVariableDeclaration(
proxy, mode, this, RelocInfo::kNoPosition);
DeclareFunctionVar(declaration);
- var->AllocateTo(Variable::CONTEXT, index);
+ var->AllocateTo(VariableLocation::CONTEXT, index);
return var;
} else {
return NULL;
@@ -603,9 +612,11 @@ class VarAndOrder {
void Scope::CollectStackAndContextLocals(
ZoneList<Variable*>* stack_locals, ZoneList<Variable*>* context_locals,
+ ZoneList<Variable*>* context_globals,
ZoneList<Variable*>* strong_mode_free_variables) {
DCHECK(stack_locals != NULL);
DCHECK(context_locals != NULL);
+ DCHECK(context_globals != NULL);
// Collect internals which are always allocated on the heap.
for (int i = 0; i < internals_.length(); i++) {
@@ -654,6 +665,8 @@ void Scope::CollectStackAndContextLocals(
stack_locals->Add(var, zone());
} else if (var->IsContextSlot()) {
context_locals->Add(var, zone());
+ } else if (var->IsGlobalSlot()) {
+ context_globals->Add(var, zone());
}
}
}
@@ -693,7 +706,7 @@ bool Scope::HasTrivialContext() const {
for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) {
if (scope->is_eval_scope()) return false;
if (scope->scope_inside_with_) return false;
- if (scope->num_heap_slots_ > 0) return false;
+ if (scope->ContextLocalCount() > 0) return false;
}
return true;
}
@@ -828,18 +841,21 @@ static void PrintName(const AstRawString* name) {
static void PrintLocation(Variable* var) {
switch (var->location()) {
- case Variable::UNALLOCATED:
+ case VariableLocation::UNALLOCATED:
break;
- case Variable::PARAMETER:
+ case VariableLocation::PARAMETER:
PrintF("parameter[%d]", var->index());
break;
- case Variable::LOCAL:
+ case VariableLocation::LOCAL:
PrintF("local[%d]", var->index());
break;
- case Variable::CONTEXT:
+ case VariableLocation::CONTEXT:
PrintF("context[%d]", var->index());
break;
- case Variable::LOOKUP:
+ case VariableLocation::GLOBAL:
+ PrintF("global[%d]", var->index());
+ break;
+ case VariableLocation::LOOKUP:
PrintF("lookup");
break;
}
@@ -871,7 +887,11 @@ static void PrintVar(int indent, Variable* var) {
static void PrintMap(int indent, VariableMap* map) {
for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
Variable* var = reinterpret_cast<Variable*>(p->value);
- PrintVar(indent, var);
+ if (var == NULL) {
+ Indent(indent, "<?>\n");
+ } else {
+ PrintVar(indent, var);
+ }
}
}
@@ -928,10 +948,15 @@ void Scope::Print(int n) {
Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
}
if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
- if (num_stack_slots_ > 0) { Indent(n1, "// ");
- PrintF("%d stack slots\n", num_stack_slots_); }
- if (num_heap_slots_ > 0) { Indent(n1, "// ");
- PrintF("%d heap slots\n", num_heap_slots_); }
+ if (num_stack_slots_ > 0) {
+ Indent(n1, "// ");
+ PrintF("%d stack slots\n", num_stack_slots_);
+ }
+ if (num_heap_slots_ > 0) {
+ Indent(n1, "// ");
+ PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_,
+ num_global_slots_);
+ }
// Print locals.
if (function_ != NULL) {
@@ -992,7 +1017,7 @@ Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
Variable::NORMAL,
init_flag);
// Allocate it by giving it a dynamic lookup.
- var->AllocateTo(Variable::LOOKUP, -1);
+ var->AllocateTo(VariableLocation::LOOKUP, -1);
}
return var;
}
@@ -1343,13 +1368,13 @@ void Scope::AllocateStackSlot(Variable* var) {
if (is_block_scope()) {
DeclarationScope()->AllocateStackSlot(var);
} else {
- var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
+ var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
}
}
void Scope::AllocateHeapSlot(Variable* var) {
- var->AllocateTo(Variable::CONTEXT, num_heap_slots_++);
+ var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
}
@@ -1414,9 +1439,11 @@ void Scope::AllocateParameter(Variable* var, int index) {
} else {
DCHECK(var->IsUnallocated() || var->IsParameter());
if (var->IsUnallocated()) {
- var->AllocateTo(Variable::PARAMETER, index);
+ var->AllocateTo(VariableLocation::PARAMETER, index);
}
}
+ } else {
+ DCHECK(!var->IsGlobalSlot());
}
}
@@ -1447,7 +1474,23 @@ void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) {
}
-void Scope::AllocateNonParameterLocals(Isolate* isolate) {
+void Scope::AllocateDeclaredGlobal(Isolate* isolate, Variable* var) {
+ DCHECK(var->scope() == this);
+ DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) ||
+ !var->IsStackLocal());
+ if (var->IsUnallocated() && var->IsStaticGlobalObjectProperty()) {
+ DCHECK_EQ(-1, var->index());
+ DCHECK(var->name()->IsString());
+ var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_);
+ num_global_slots_++;
+ // Each global variable occupies two slots in the context: for reads
+ // and writes.
+ num_heap_slots_ += 2;
+ }
+}
+
+
+void Scope::AllocateNonParameterLocalsAndDeclaredGlobals(Isolate* isolate) {
// All variables that have no rewrite yet are non-parameter locals.
for (int i = 0; i < temps_.length(); i++) {
AllocateNonParameterLocal(isolate, temps_[i]);
@@ -1470,6 +1513,12 @@ void Scope::AllocateNonParameterLocals(Isolate* isolate) {
AllocateNonParameterLocal(isolate, vars[i].var());
}
+ if (enable_context_globals) {
+ for (int i = 0; i < var_count; i++) {
+ AllocateDeclaredGlobal(isolate, vars[i].var());
+ }
+ }
+
// For now, function_ must be allocated at the very end. If it gets
// allocated in the context, it must be the last slot in the context,
// because of the current ScopeInfo implementation (see
@@ -1515,7 +1564,7 @@ void Scope::AllocateVariablesRecursively(Isolate* isolate) {
// Parameters must be allocated first, if any.
if (is_function_scope()) AllocateParameterLocals(isolate);
if (has_this_declaration()) AllocateReceiver();
- AllocateNonParameterLocals(isolate);
+ AllocateNonParameterLocalsAndDeclaredGlobals(isolate);
// Force allocation of a context for this scope if necessary. For a 'with'
// scope and for a function scope that makes an 'eval' call we need a context,
@@ -1559,8 +1608,13 @@ int Scope::StackLocalCount() const {
int Scope::ContextLocalCount() const {
if (num_heap_slots() == 0) return 0;
+ bool is_function_var_in_context =
+ function_ != NULL && function_->proxy()->var()->IsContextSlot();
return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
- (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
+ 2 * num_global_slots() - (is_function_var_in_context ? 1 : 0);
}
+
+
+int Scope::ContextGlobalCount() const { return num_global_slots(); }
} // namespace internal
} // namespace v8
« no previous file with comments | « src/scopes.h ('k') | src/typing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698