Chromium Code Reviews| Index: src/ast/scopes.cc |
| diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc |
| index f7cbdd4279bcb03a94d70c6052ec70ba478bba91..425927b1a4a9cd890246d29513929f4f645ddd87 100644 |
| --- a/src/ast/scopes.cc |
| +++ b/src/ast/scopes.cc |
| @@ -209,6 +209,7 @@ void Scope::SetDefaults() { |
| asm_function_ = false; |
| scope_nonlinear_ = false; |
| is_hidden_ = false; |
| + is_debug_evaluate_scope_ = false; |
| outer_scope_calls_sloppy_eval_ = false; |
| inner_scope_calls_eval_ = false; |
| @@ -236,6 +237,11 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| // For scope analysis, debug-evaluate is equivalent to a with scope. |
| Scope* with_scope = new (zone) |
| Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); |
| + // TODO(yangguo): Remove once debug-evaluate properly keeps track of the |
| + // function scope in which we are evaluating. |
| + if (context->IsDebugEvaluateContext()) { |
| + with_scope->set_is_debug_evaluate_scope(); |
| + } |
| current_scope = with_scope; |
| // All the inner scopes are inside a with. |
| for (Scope* s = innermost_scope; s != nullptr; s = s->outer_scope()) { |
| @@ -554,7 +560,7 @@ Variable* Scope::LookupLocal(const AstRawString* name) { |
| // it's ok to get the Handle<String> here. |
| // If we have a serialized scope info, we might find the variable there. |
| // There should be no local slot with the given name. |
| - DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope()); |
|
Toon Verwaest
2016/08/12 08:50:20
I don't see how this would be valid for block scop
|
| + DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0); |
| // Check context slot lookup. |
| VariableMode mode; |
| @@ -1243,15 +1249,15 @@ void Scope::CheckZones() { |
| } |
| #endif // DEBUG |
| -Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode, |
| - Variable::Kind kind) { |
| +Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { |
| if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); |
| VariableMap* map = dynamics_->GetMap(mode); |
| Variable* var = map->Lookup(name); |
| if (var == NULL) { |
| // Declare a new non-local. |
| DCHECK(!IsLexicalVariableMode(mode)); |
| - var = map->Declare(zone(), NULL, name, mode, kind, kCreatedInitialized); |
| + var = map->Declare(zone(), NULL, name, mode, Variable::NORMAL, |
| + kCreatedInitialized); |
| // Allocate it by giving it a dynamic lookup. |
| var->AllocateTo(VariableLocation::LOOKUP, -1); |
| } |
| @@ -1265,9 +1271,14 @@ Variable* Scope::LookupRecursive(VariableProxy* proxy, |
| DCHECK_NE(outer_scope_end, this); |
| DCHECK_NOT_NULL(binding_kind); |
| DCHECK_EQ(UNBOUND, *binding_kind); |
| - if (already_resolved() && is_with_scope()) { |
| - // Short-cut: if the scope is deserialized from a scope info, variable |
| - // allocation is already fixed. We can simply return with dynamic lookup. |
| + // Short-cut: whenever we find a debug-evaluate scope, just look everything up |
| + // dynamically. Debug-evaluate doesn't properly create scope info for the |
| + // lookups it does. It may not have a valid 'this' declaration, and anything |
| + // accessed through debug-evaluate might invalidly resolve to stack-allocated |
| + // variables. |
| + // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the |
| + // scopes in which it's evaluating. |
| + if (is_debug_evaluate_scope_) { |
| *binding_kind = DYNAMIC_LOOKUP; |
| return nullptr; |
| } |
| @@ -1305,14 +1316,13 @@ Variable* Scope::LookupRecursive(VariableProxy* proxy, |
| if (var != nullptr && var->is_this()) return var; |
| if (is_with_scope()) { |
| - DCHECK(!already_resolved()); |
| // The current scope is a with scope, so the variable binding can not be |
| // statically resolved. However, note that it was necessary to do a lookup |
| // in the outer scope anyway, because if a binding exists in an outer |
| // scope, the associated variable has to be marked as potentially being |
| // accessed from inside of an inner with scope (the property may not be in |
| // the 'with' object). |
| - if (var != nullptr) { |
| + if (var != nullptr && !already_resolved()) { |
| var->set_is_used(); |
| var->ForceContextAllocation(); |
| if (proxy->is_assigned()) var->set_maybe_assigned(); |
| @@ -1381,9 +1391,6 @@ void Scope::ResolveTo(ParseInfo* info, BindingKind binding_kind, |
| } |
| #endif |
| - // TODO(verwaest): 'this' should always be declared and found. That way we can |
| - // remove this workaround. |
| - Variable::Kind kind = proxy->is_this() ? Variable::THIS : Variable::NORMAL; |
| switch (binding_kind) { |
| case BOUND: |
| break; |
| @@ -1394,29 +1401,30 @@ void Scope::ResolveTo(ParseInfo* info, BindingKind binding_kind, |
| // 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->IsGlobalObjectProperty()) { |
| - var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL, kind); |
| + var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
| } else if (var->is_dynamic()) { |
| - var = NonLocal(proxy->raw_name(), DYNAMIC, kind); |
| + var = NonLocal(proxy->raw_name(), DYNAMIC); |
| } else { |
| Variable* invalidated = var; |
| - var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL, kind); |
| + var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); |
| var->set_local_if_not_shadowed(invalidated); |
| } |
| break; |
| case UNBOUND: |
| // No binding has been found. Declare a variable on the global object. |
| - var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name(), kind); |
| + var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name(), |
| + Variable::NORMAL); |
| break; |
| case UNBOUND_EVAL_SHADOWED: |
| // No binding has been found. But some scope makes a sloppy 'eval' call. |
| - var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL, kind); |
| + var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
| break; |
| case DYNAMIC_LOOKUP: |
| // The variable could not be resolved statically. |
| - var = NonLocal(proxy->raw_name(), DYNAMIC, kind); |
| + var = NonLocal(proxy->raw_name(), DYNAMIC); |
| break; |
| } |