Implement 'setVariableValue' for debugger block scopes.
authorDmitry Lomov <dslomov@chromium.org>
Fri, 14 Nov 2014 13:39:06 +0000 (14:39 +0100)
committerDmitry Lomov <dslomov@chromium.org>
Fri, 14 Nov 2014 13:39:20 +0000 (13:39 +0000)
R=aandrey@chromium.org, rossberg@chromium.org, yurys@chromium.org
BUG=v8:3690
LOG=N

Review URL: https://codereview.chromium.org/732543002

Cr-Commit-Position: refs/heads/master@{#25358}

src/runtime/runtime-debug.cc
test/mjsunit/harmony/debug-evaluate-blockscopes.js

index 28657ee..d576dc7 100644 (file)
@@ -986,6 +986,17 @@ static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> context,
 }
 
 
+static bool SetBlockContextVariableValue(Handle<Context> block_context,
+                                         Handle<String> variable_name,
+                                         Handle<Object> new_value) {
+  DCHECK(block_context->IsBlockContext());
+  Handle<ScopeInfo> scope_info(ScopeInfo::cast(block_context->extension()));
+
+  return SetContextLocalValue(block_context->GetIsolate(), scope_info,
+                              block_context, variable_name, new_value);
+}
+
+
 // Create a plain JSObject which materializes the scope for the specified
 // catch context.
 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
@@ -1304,8 +1315,8 @@ class ScopeIterator {
         return SetClosureVariableValue(isolate_, CurrentContext(),
                                        variable_name, new_value);
       case ScopeIterator::ScopeTypeBlock:
-        // TODO(2399): should we implement it?
-        break;
+        return SetBlockContextVariableValue(CurrentContext(), variable_name,
+                                            new_value);
       case ScopeIterator::ScopeTypeModule:
         // TODO(2399): should we implement it?
         break;
index 16885d0..d133cc0 100644 (file)
@@ -67,3 +67,43 @@ assertEquals(1, result);
 Debug.clearBreakPoint(bp);
 // Get rid of the debug event listener.
 Debug.setListener(null);
+
+
+function f1() {
+  {
+    let i = 1;
+    debugger;
+    assertEquals(2, i);
+  }
+}
+
+function f2() {
+  {
+    let i = 1;
+    debugger;
+    assertEquals(2, i);
+    return function() { return i++; }
+  }
+}
+
+var exception;
+Debug.setListener(function (event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      var frame = exec_state.frame();
+      assertEquals(1, frame.evaluate("i").value());
+      var allScopes = frame.allScopes();
+      assertEquals(1, allScopes[0].scopeObject().value().i);
+      allScopes[0].setVariableValue("i", 2);
+    }
+  } catch (e) {
+    exception = e;
+  }
+});
+
+exception = null;
+f1();
+assertEquals(null, exception, exception);
+exception = null;
+f2();
+assertEquals(null, exception, exception);