From f1bacf8fff72d9a7c0863b21c07d11df4af5d8e2 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Mon, 24 Mar 2014 14:10:57 +0000 Subject: [PATCH] Fix DebugEvaluate for generators. R=mstarzinger@chromium.org BUG=v8:3225 LOG=N Review URL: https://codereview.chromium.org/207153004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20195 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/runtime.cc | 22 ++++++++++++++------ test/mjsunit/regress-3225.js | 48 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 test/mjsunit/regress-3225.js diff --git a/src/runtime.cc b/src/runtime.cc index 8b18e55..3e8f0b3 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -11409,6 +11409,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) { } +static bool ParameterIsShadowedByContextLocal(Handle info, + int index) { + VariableMode mode; + InitializationFlag flag; + return info->ContextSlotIndex(info->ParameterName(index), &mode, &flag) != -1; +} + + // Create a plain JSObject which materializes the local scope for the specified // frame. static Handle MaterializeStackLocalsWithFrameInspector( @@ -11421,17 +11429,16 @@ static Handle MaterializeStackLocalsWithFrameInspector( // First fill all parameters. for (int i = 0; i < scope_info->ParameterCount(); ++i) { - Handle name(scope_info->ParameterName(i)); - VariableMode mode; - InitializationFlag init_flag; // Do not materialize the parameter if it is shadowed by a context local. - if (scope_info->ContextSlotIndex(*name, &mode, &init_flag) != -1) continue; + if (ParameterIsShadowedByContextLocal(scope_info, i)) continue; + HandleScope scope(isolate); Handle value(i < frame_inspector->GetParametersCount() ? frame_inspector->GetParameter(i) : isolate->heap()->undefined_value(), isolate); ASSERT(!value->IsTheHole()); + Handle name(scope_info->ParameterName(i)); RETURN_IF_EMPTY_HANDLE_VALUE( isolate, @@ -11472,10 +11479,13 @@ static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate, // Parameters. for (int i = 0; i < scope_info->ParameterCount(); ++i) { + // Shadowed parameters were not materialized. + if (ParameterIsShadowedByContextLocal(scope_info, i)) continue; + ASSERT(!frame->GetParameter(i)->IsTheHole()); HandleScope scope(isolate); - Handle value = GetProperty( - isolate, target, Handle(scope_info->ParameterName(i))); + Handle name(scope_info->ParameterName(i)); + Handle value = GetProperty(isolate, target, name); frame->SetParameterValue(i, *value); } diff --git a/test/mjsunit/regress-3225.js b/test/mjsunit/regress-3225.js new file mode 100644 index 0000000..357f94b --- /dev/null +++ b/test/mjsunit/regress-3225.js @@ -0,0 +1,48 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --harmony-generators + +Debug = debug.Debug + +var debug_step = 0; +var failure = null; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + if (debug_step == 0) { + assertEquals(1, exec_state.frame(0).evaluate('a').value()); + assertEquals(3, exec_state.frame(0).evaluate('b').value()); + exec_state.frame(0).evaluate("a = 4").value(); + debug_step++; + } else { + assertEquals(4, exec_state.frame(0).evaluate('a').value()); + assertEquals(3, exec_state.frame(0).evaluate('b').value()); + exec_state.frame(0).evaluate("b = 5").value(); + } + } catch (e) { + failure = e; + } +} + +Debug.setListener(listener); + +function* generator(a, b) { + var b = 3; // Shadows a parameter. + debugger; + yield a; + yield b; + debugger; + return b; +} + +var foo = generator(1, 2); + +assertEquals(4, foo.next().value); +assertEquals(3, foo.next().value); +assertEquals(5, foo.next().value); +assertNull(failure); + +Debug.setListener(null); -- 2.7.4