Revision: 4338
Author: [email protected]
Date: Fri Apr  2 04:03:49 2010
Log: Let LiveEdit accept a full new script source (rather than diff)

Review URL: http://codereview.chromium.org/1584008
http://code.google.com/p/v8/source/detail?r=4338

Added:
 /branches/bleeding_edge/test/mjsunit/debug-liveedit-newsource.js
Modified:
 /branches/bleeding_edge/src/debug-debugger.js
 /branches/bleeding_edge/src/liveedit-debugger.js

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/debug-liveedit-newsource.js Fri Apr 2 04:03:49 2010
@@ -0,0 +1,47 @@
+// Copyright 2010 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
+// Get the Debug object exposed from the debug context global object.
+
+Debug = debug.Debug
+
+eval("var something1 = 25; "
+     + " function ChooseAnimal() { return          'Cat';          } "
+     + " ChooseAnimal.Helper = function() { return 'Help!'; }");
+
+assertEquals("Cat", ChooseAnimal());
+
+var script = Debug.findScript(ChooseAnimal);
+
+var new_source = script.source.replace("Cat", "Cap' + 'yb' + 'ara");
+print("new source: " + new_source);
+
+var change_log = new Array();
+Debug.LiveEdit.SetScriptSource(script, new_source, change_log);
+
+assertEquals("Capybara", ChooseAnimal());
=======================================
--- /branches/bleeding_edge/src/debug-debugger.js       Thu Apr  1 09:25:07 2010
+++ /branches/bleeding_edge/src/debug-debugger.js       Fri Apr  2 04:03:49 2010
@@ -1966,14 +1966,7 @@
     return response.failed('Missing arguments');
   }
   var script_id = request.arguments.script_id;
-  var change_pos = parseInt(request.arguments.change_pos);
-  var change_len = parseInt(request.arguments.change_len);
-  var new_string = request.arguments.new_string;
-  if (!IS_STRING(new_string)) {
-    response.failed('Argument "new_string" is not a string value');
-    return;
-  }
-
+
   var scripts = %DebugGetLoadedScripts();

   var the_script = null;
@@ -1987,10 +1980,32 @@
     return;
   }

+  // A function that calls a proper signature of LiveEdit API.
+  var invocation;
+
   var change_log = new Array();
+
+  if (IS_STRING(request.arguments.new_source)) {
+    var new_source = request.arguments.new_source;
+    invocation = function() {
+ return Debug.LiveEdit.SetScriptSource(the_script, new_source, change_log);
+    }
+  } else {
+    var change_pos = parseInt(request.arguments.change_pos);
+    var change_len = parseInt(request.arguments.change_len);
+    var new_string = request.arguments.new_string;
+    if (!IS_STRING(new_string)) {
+      response.failed('Argument "new_string" is not a string value');
+      return;
+    }
+    invocation = function() {
+      return Debug.LiveEditChangeScript(the_script, change_pos, change_len,
+          new_string, change_log);
+    }
+  }
+
   try {
- Debug.LiveEditChangeScript(the_script, change_pos, change_len, new_string,
-                               change_log);
+    invocation();
   } catch (e) {
     if (e instanceof Debug.LiveEditChangeScript.Failure) {
       // Let's treat it as a "success" so that body with change_log will be
=======================================
--- /branches/bleeding_edge/src/liveedit-debugger.js Tue Mar 30 00:15:23 2010 +++ /branches/bleeding_edge/src/liveedit-debugger.js Fri Apr 2 04:03:49 2010
@@ -429,3 +429,86 @@
Debug.LiveEditChangeScript.GetPcFromSourcePos = function(func, source_pos) {
   return %GetFunctionCodePositionFromSource(func, source_pos);
 }
+
+// A LiveEdit namespace is declared inside a single function constructor.
+Debug.LiveEdit = new function() {
+  var LiveEdit = this;
+
+
+  // LiveEdit main entry point: changes a script text to a new string.
+  LiveEdit.SetScriptSource = function(script, new_source, change_log) {
+    var old_source = script.source;
+    var diff = FindSimpleDiff(old_source, new_source);
+    if (!diff) {
+      return;
+    }
+    Debug.LiveEditChangeScript(script, diff.change_pos, diff.old_len,
+ new_source.substring(diff.change_pos, diff.change_pos + diff.new_len),
+        change_log);
+  }
+
+
+  // Finds a difference between 2 strings in form of a single chunk.
+  // This is a temporary solution. We should calculate a read diff instead.
+  function FindSimpleDiff(old_source, new_source) {
+    var change_pos;
+    var old_len;
+    var new_len;
+
+ // A find range block. Whenever control leaves it, it should set 3 local
+    // variables declared above.
+    find_range:
+    {
+      // First look from the beginning of strings.
+      var pos1;
+      {
+        var next_pos;
+        for (pos1 = 0; true; pos1 = next_pos) {
+          if (pos1 >= old_source.length) {
+            change_pos = pos1;
+            old_len = 0;
+            new_len = new_source.length - pos1;
+            break find_range;
+          }
+          if (pos1 >= new_source.length) {
+            change_pos = pos1;
+            old_len = old_source.length - pos1;
+            new_len = 0;
+            break find_range;
+          }
+          if (old_source[pos1] != new_source[pos1]) {
+            break;
+          }
+          next_pos = pos1 + 1;
+        }
+      }
+      // Now compare strings from the ends.
+      change_pos = pos1;
+      var pos_old;
+      var pos_new;
+      {
+ for (pos_old = old_source.length - 1, pos_new = new_source.length - 1;
+            true;
+            pos_old--, pos_new--) {
+ if (pos_old - change_pos + 1 < 0 || pos_new - change_pos + 1 < 0) {
+            old_len = pos_old - change_pos + 2;
+            new_len = pos_new - change_pos + 2;
+            break find_range;
+          }
+          if (old_source[pos_old] != new_source[pos_new]) {
+            old_len = pos_old - change_pos + 1;
+            new_len = pos_new - change_pos + 1;
+            break find_range;
+          }
+        }
+      }
+    }
+
+    if (old_len == 0 && new_len == 0) {
+      // no change
+      return;
+    }
+
+ return { "change_pos": change_pos, "old_len": old_len, "new_len": new_len };
+  }
+}

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

To unsubscribe, reply using "remove me" as the subject.

Reply via email to