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

Unified Diff: src/scopes.cc

Issue 8508052: Static resolution of outer variables in eval code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month 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
« src/runtime.cc ('K') | « src/scopes.h ('k') | no next file » | 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 f9cebcddaafff5532c4aac23ab7af06dd9a7c220..356b578d2256ed172a3271107b34b4ed61fee08c 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -148,6 +148,8 @@ Scope::Scope(Scope* inner_scope,
SetDefaults(type, NULL, scope_info);
if (!scope_info.is_null()) {
num_heap_slots_ = scope_info_->ContextLength();
+ } else if (is_with_scope()) {
+ num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
}
AddInnerScope(inner_scope);
}
@@ -165,6 +167,7 @@ Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name)
SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
AddInnerScope(inner_scope);
++num_var_or_const_;
+ num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
Variable* variable = variables_.Declare(this,
catch_variable_name,
VAR,
@@ -201,14 +204,16 @@ void Scope::SetDefaults(ScopeType type,
scope_info_ = scope_info;
start_position_ = RelocInfo::kNoPosition;
end_position_ = RelocInfo::kNoPosition;
+ if (!scope_info.is_null()) {
+ scope_calls_eval_ = scope_info->CallsEval();
+ strict_mode_flag_ =
+ scope_info->IsStrictMode() ? kStrictMode : kNonStrictMode;
+ }
}
-Scope* Scope::DeserializeScopeChain(CompilationInfo* info,
- Scope* global_scope) {
+Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope) {
// Reconstruct the outer scope chain from a closure's context chain.
- ASSERT(!info->closure().is_null());
- Context* context = info->closure()->context();
Scope* current_scope = NULL;
Scope* innermost_scope = NULL;
bool contains_with = false;
@@ -356,10 +361,6 @@ Variable* Scope::LocalLookup(Handle<String> name) {
return result;
}
// If we have a serialized scope info, we might find the variable there.
- //
- // We should never lookup 'arguments' in this scope as it is implicitly
- // present in every scope.
- ASSERT(*name != *isolate_->factory()->arguments_symbol());
// There should be no local slot with the given name.
ASSERT(scope_info_->StackSlotIndex(*name) < 0);
@@ -372,11 +373,7 @@ Variable* Scope::LocalLookup(Handle<String> name) {
mode = VAR;
init_flag = kCreatedInitialized;
index = scope_info_->ParameterIndex(*name);
- if (index < 0) {
- // Check the function name.
- index = scope_info_->FunctionContextSlotIndex(*name, &mode);
- if (index < 0) return NULL;
- }
+ if (index < 0) return NULL;
}
Variable* var =
@@ -391,6 +388,23 @@ Variable* Scope::LocalLookup(Handle<String> name) {
}
+Variable* Scope::LookupFunctionVar(Handle<String> name) {
+ if (function_ != NULL && function_->name().is_identical_to(name)) {
+ return function_->var();
+ } else if (!scope_info_.is_null()) {
+ // If we are backed by a scope info, try to lookup the variable there.
+ VariableMode mode;
+ int index = scope_info_->FunctionContextSlotIndex(*name, &mode);
+ if (index < 0) return NULL;
+ Variable* var = DeclareFunctionVar(name, mode);
+ var->AllocateTo(Variable::CONTEXT, index);
+ return var;
+ } else {
+ return NULL;
+ }
+}
+
+
Variable* Scope::Lookup(Handle<String> name) {
for (Scope* scope = this;
scope != NULL;
@@ -559,7 +573,7 @@ void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
}
-void Scope::AllocateVariables(Handle<Context> context) {
+void Scope::AllocateVariables(Handle<Context> calling_context) {
ASSERT(outer_scope_ == NULL); // eval or global scopes only
// 1) Propagate scope information.
@@ -569,16 +583,19 @@ void Scope::AllocateVariables(Handle<Context> context) {
// this information in the ScopeInfo and then use it here (by traversing
// the call chain stack, at compile time).
- bool outer_scope_calls_non_strict_eval = false;
- if (!is_global_scope()) {
- context->ComputeEvalScopeInfo(&outer_scope_calls_non_strict_eval);
+ Scope* global_scope;
+ if (is_global_scope()) {
+ global_scope = this;
+ } else {
+ global_scope = new Scope(NULL, GLOBAL_SCOPE);
+ Scope* calling_scope =
+ DeserializeScopeChain(*calling_context, global_scope);
Kevin Millikin (Chromium) 2011/11/10 12:55:21 I don't like this. It doesn't seem consistent. F
Steven 2011/11/11 08:35:04 Done.
+ calling_scope->AddInnerScope(this);
}
- PropagateScopeInfo(outer_scope_calls_non_strict_eval);
+ global_scope->PropagateScopeInfo(false);
// 2) Resolve variables.
- Scope* global_scope = NULL;
- if (is_global_scope()) global_scope = this;
- ResolveVariablesRecursively(global_scope, context);
+ ResolveVariablesRecursively(global_scope);
// 3) Allocate variables.
AllocateVariablesRecursively();
@@ -832,7 +849,6 @@ Variable* Scope::NonLocal(Handle<String> name, VariableMode mode) {
Variable* Scope::LookupRecursive(Handle<String> name,
- Handle<Context> context,
BindingKind* binding_kind) {
ASSERT(binding_kind != NULL);
// Try to find the variable in this scope.
@@ -849,20 +865,17 @@ Variable* Scope::LookupRecursive(Handle<String> name,
// We did not find a variable locally. Check against the function variable,
// if any. We can do this for all scopes, since the function variable is
// only present - if at all - for function scopes.
- //
- // This lookup corresponds to a lookup in the "intermediate" scope sitting
- // between this scope and the outer scope. (ECMA-262, 3rd., requires that
- // the name of named function literal is kept in an intermediate scope
- // in between this scope and the next outer scope.)
*binding_kind = UNBOUND;
- if (function_ != NULL && function_->name().is_identical_to(name)) {
- var = function_->var();
+ var = LookupFunctionVar(name);
+ if (var != NULL) {
*binding_kind = BOUND;
} else if (outer_scope_ != NULL) {
- var = outer_scope_->LookupRecursive(name, context, binding_kind);
+ var = outer_scope_->LookupRecursive(name, binding_kind);
if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
var->ForceContextAllocation();
}
+ } else {
+ ASSERT(is_global_scope());
}
if (is_with_scope()) {
@@ -874,16 +887,6 @@ Variable* Scope::LookupRecursive(Handle<String> name,
// object).
*binding_kind = DYNAMIC_LOOKUP;
return NULL;
- } else if (is_eval_scope()) {
- // No local binding was found, no 'with' statements have been encountered
- // and the code is executed as part of a call to 'eval'. The calling context
- // contains scope information that we can use to determine if the variable
- // is global, i.e. the calling context chain does not contain a binding and
- // no 'with' contexts.
- ASSERT(*binding_kind == UNBOUND);
- *binding_kind = context->GlobalIfNotShadowedByEval(name)
- ? UNBOUND_EVAL_SHADOWED : DYNAMIC_LOOKUP;
- return NULL;
} else if (calls_non_strict_eval()) {
// A variable binding may have been found in an outer scope, but the current
// scope makes a non-strict 'eval' call, so the found variable may not be
@@ -900,7 +903,6 @@ Variable* Scope::LookupRecursive(Handle<String> name,
void Scope::ResolveVariable(Scope* global_scope,
- Handle<Context> context,
VariableProxy* proxy) {
ASSERT(global_scope == NULL || global_scope->is_global_scope());
@@ -910,7 +912,7 @@ void Scope::ResolveVariable(Scope* global_scope,
// Otherwise, try to resolve the variable.
BindingKind binding_kind;
- Variable* var = LookupRecursive(proxy->name(), context, &binding_kind);
+ Variable* var = LookupRecursive(proxy->name(), &binding_kind);
switch (binding_kind) {
case BOUND:
// We found a variable binding.
@@ -951,18 +953,17 @@ void Scope::ResolveVariable(Scope* global_scope,
}
-void Scope::ResolveVariablesRecursively(Scope* global_scope,
- Handle<Context> context) {
+void Scope::ResolveVariablesRecursively(Scope* global_scope) {
ASSERT(global_scope == NULL || global_scope->is_global_scope());
// Resolve unresolved variables for this scope.
for (int i = 0; i < unresolved_.length(); i++) {
- ResolveVariable(global_scope, context, unresolved_[i]);
+ ResolveVariable(global_scope, unresolved_[i]);
}
// Resolve unresolved variables for inner scopes.
for (int i = 0; i < inner_scopes_.length(); i++) {
- inner_scopes_[i]->ResolveVariablesRecursively(global_scope, context);
+ inner_scopes_[i]->ResolveVariablesRecursively(global_scope);
}
}
« src/runtime.cc ('K') | « src/scopes.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698