From ec4c772746d7f56ef20b94b8a8c46184f02d96b3 Mon Sep 17 00:00:00 2001 From: "vegorov@chromium.org" Date: Thu, 12 Apr 2012 19:32:29 +0000 Subject: [PATCH] Return LOOKUP variable instead of CONTEXT for non-context allocated outer scope parameters. R=kmillikin@chromium.org BUG=chromium:119609 TEST=test/mjsunit/regress/regress-119609.js Review URL: https://chromiumcodereview.appspot.com/10010046 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11298 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/scopes.cc | 17 +++++--- test/mjsunit/regress/regress-119609.js | 71 ++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 test/mjsunit/regress/regress-119609.js diff --git a/src/scopes.cc b/src/scopes.cc index 859cbd1..1e35e48 100644 --- a/src/scopes.cc +++ b/src/scopes.cc @@ -388,14 +388,17 @@ Variable* Scope::LocalLookup(Handle 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,7 +408,7 @@ Variable* Scope::LocalLookup(Handle name) { true, Variable::NORMAL, init_flag); - var->AllocateTo(Variable::CONTEXT, index); + var->AllocateTo(location, index); return var; } @@ -949,10 +952,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); diff --git a/test/mjsunit/regress/regress-119609.js b/test/mjsunit/regress/regress-119609.js new file mode 100644 index 0000000..af4335b --- /dev/null +++ b/test/mjsunit/regress/regress-119609.js @@ -0,0 +1,71 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-debug-as debug + +Debug = debug.Debug; + +var exception = false; + +function listener(event, exec_state, event_data, data) { + try { + if (event == Debug.DebugEvent.Break) { + function lookup(name) { + return exec_state.frame(0).evaluate(name).value(); + } + + assertEquals(3, lookup("e")); + assertEquals(4, lookup("f")); + assertEquals(1, lookup("a")); + + try { + assertEquals(2, lookup("b")); + } catch (e) { + assertEquals("ReferenceError: b is not defined", e.toString()); + } + } + } catch (e) { + exception = e.toString() + e.stack; + } +} + +Debug.setListener(listener); + +function f(a, b) { + var c = 3; + function d(e, f) { + var g = a; + var h = c; + debugger; + } + + return d; +} + +f(1, 2)(3, 4); + +assertFalse(exception); -- 2.7.4