aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/scopes.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/scopes.cc')
-rw-r--r--deps/v8/src/scopes.cc44
1 files changed, 29 insertions, 15 deletions
diff --git a/deps/v8/src/scopes.cc b/deps/v8/src/scopes.cc
index 859cbd1ae6..6f6032a320 100644
--- a/deps/v8/src/scopes.cc
+++ b/deps/v8/src/scopes.cc
@@ -388,14 +388,17 @@ Variable* Scope::LocalLookup(Handle<String> name) {
// Check context slot lookup.
VariableMode mode;
+ Variable::Location location = Variable::CONTEXT;
InitializationFlag init_flag;
int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag);
if (index < 0) {
// Check parameters.
- mode = VAR;
- init_flag = kCreatedInitialized;
index = scope_info_->ParameterIndex(*name);
if (index < 0) return NULL;
+
+ mode = DYNAMIC;
+ location = Variable::LOOKUP;
+ init_flag = kCreatedInitialized;
}
Variable* var =
@@ -405,21 +408,27 @@ Variable* Scope::LocalLookup(Handle<String> name) {
true,
Variable::NORMAL,
init_flag);
- var->AllocateTo(Variable::CONTEXT, index);
+ var->AllocateTo(location, index);
return var;
}
Variable* Scope::LookupFunctionVar(Handle<String> name,
AstNodeFactory<AstNullVisitor>* factory) {
- if (function_ != NULL && function_->name().is_identical_to(name)) {
- return function_->var();
+ if (function_ != NULL && function_->proxy()->name().is_identical_to(name)) {
+ return function_->proxy()->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, factory);
+ Variable* var = new Variable(
+ this, name, mode, true /* is valid LHS */,
+ Variable::NORMAL, kCreatedInitialized);
+ VariableProxy* proxy = factory->NewVariableProxy(var);
+ VariableDeclaration* declaration =
+ factory->NewVariableDeclaration(proxy, mode, this);
+ DeclareFunctionVar(declaration);
var->AllocateTo(Variable::CONTEXT, index);
return var;
} else {
@@ -791,7 +800,7 @@ void Scope::Print(int n) {
// Function name, if any (named function literals, only).
if (function_ != NULL) {
Indent(n1, "// (local) function name: ");
- PrintName(function_->name());
+ PrintName(function_->proxy()->name());
PrintF("\n");
}
@@ -824,7 +833,7 @@ void Scope::Print(int n) {
// Print locals.
Indent(n1, "// function var\n");
if (function_ != NULL) {
- PrintVar(n1, function_->var());
+ PrintVar(n1, function_->proxy()->var());
}
Indent(n1, "// temporary vars\n");
@@ -949,10 +958,14 @@ bool Scope::ResolveVariable(CompilationInfo* info,
break;
case BOUND_EVAL_SHADOWED:
- // We found a variable variable binding that might be shadowed
- // by 'eval' introduced variable bindings.
+ // We either found a variable binding that might be shadowed by eval or
+ // gave up on it (e.g. by encountering a local with the same in the outer
+ // scope which was not promoted to a context, this can happen if we use
+ // debugger to evaluate arbitrary expressions at a break point).
if (var->is_global()) {
var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
+ } else if (var->is_dynamic()) {
+ var = NonLocal(proxy->name(), DYNAMIC);
} else {
Variable* invalidated = var;
var = NonLocal(proxy->name(), DYNAMIC_LOCAL);
@@ -1086,7 +1099,7 @@ bool Scope::MustAllocateInContext(Variable* var) {
// Exceptions: temporary variables are never allocated in a context;
// catch-bound variables are always allocated in a context.
if (var->mode() == TEMPORARY) return false;
- if (is_catch_scope() || is_block_scope()) return true;
+ if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
return var->has_forced_context_allocation() ||
scope_calls_eval_ ||
inner_scope_calls_eval_ ||
@@ -1204,7 +1217,7 @@ void Scope::AllocateNonParameterLocals() {
// because of the current ScopeInfo implementation (see
// ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
if (function_ != NULL) {
- AllocateNonParameterLocal(function_->var());
+ AllocateNonParameterLocal(function_->proxy()->var());
}
}
@@ -1230,7 +1243,8 @@ void Scope::AllocateVariablesRecursively() {
// 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,
// even if no local variables were statically allocated in the scope.
- bool must_have_context = is_with_scope() ||
+ // Likewise for modules.
+ bool must_have_context = is_with_scope() || is_module_scope() ||
(is_function_scope() && calls_eval());
// If we didn't allocate any locals in the local context, then we only
@@ -1246,14 +1260,14 @@ void Scope::AllocateVariablesRecursively() {
int Scope::StackLocalCount() const {
return num_stack_slots() -
- (function_ != NULL && function_->var()->IsStackLocal() ? 1 : 0);
+ (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
}
int Scope::ContextLocalCount() const {
if (num_heap_slots() == 0) return 0;
return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
- (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0);
+ (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
}
} } // namespace v8::internal