Index: test/mjsunit/debug-liveedit-check-stack.js |
diff --git a/test/mjsunit/debug-liveedit-check-stack.js b/test/mjsunit/debug-liveedit-check-stack.js |
index 1d788be86e0762e162d0ea2d3002c3563e7ca79e..6b16490d7121b58aae524443475aeac9f7ce6c14 100644 |
--- a/test/mjsunit/debug-liveedit-check-stack.js |
+++ b/test/mjsunit/debug-liveedit-check-stack.js |
@@ -30,55 +30,112 @@ |
Debug = debug.Debug |
-eval( |
- "function ChooseAnimal(callback) {\n " + |
- " callback();\n" + |
- " return 'Cat';\n" + |
- "}\n" |
-); |
+unique_id = 1; |
-function Noop() {} |
-var res = ChooseAnimal(Noop); |
+function TestBase(name) { |
+ print("TestBase constructor: " + name); |
-assertEquals("Cat", res); |
+ this.ChooseAnimal = eval( |
+ "/* " + unique_id + "*/\n" + |
+ "(function ChooseAnimal(callback) {\n " + |
+ " callback();\n" + |
+ " return 'Cat';\n" + |
+ "})\n" |
+ ); |
+ // Prevents eval script caching. |
+ unique_id++; |
-var script = Debug.findScript(ChooseAnimal); |
+ var script = Debug.findScript(this.ChooseAnimal); |
-var orig_animal = "'Cat'"; |
-var patch_pos = script.source.indexOf(orig_animal); |
-var new_animal_patch = "'Capybara'"; |
+ var orig_animal = "'Cat'"; |
+ var patch_pos = script.source.indexOf(orig_animal); |
+ var new_animal_patch = "'Capybara'"; |
-var got_exception = false; |
-var successfully_changed = false; |
+ var got_exception = false; |
+ var successfully_changed = false; |
-function Changer() { |
- // Never try the same patch again. |
- assertEquals(false, successfully_changed); |
- var change_log = new Array(); |
- try { |
- Debug.LiveEditChangeScript(script, patch_pos, orig_animal.length, new_animal_patch, change_log); |
+ // Should be called from Debug context. |
+ this.ScriptChanger = function() { |
+ assertEquals(false, successfully_changed, "applying patch second time"); |
+ // Runs in debugger context. |
+ var change_log = new Array(); |
+ try { |
+ Debug.LiveEditChangeScript(script, patch_pos, orig_animal.length, new_animal_patch, change_log); |
+ } finally { |
+ print("Change log: " + JSON.stringify(change_log) + "\n"); |
+ } |
successfully_changed = true; |
- } catch (e) { |
- if (e instanceof Debug.LiveEditChangeScript.Failure) { |
- got_exception = true; |
- print(e); |
- } else { |
- throw e; |
+ }; |
+} |
+ |
+function Noop() {} |
+ |
+function WrapInCatcher(f, holder) { |
+ return function() { |
+ delete holder[0]; |
+ try { |
+ f(); |
+ } catch (e) { |
+ if (e instanceof Debug.LiveEditChangeScript.Failure) { |
+ holder[0] = e; |
+ } else { |
+ throw e; |
+ } |
+ } |
+ }; |
+} |
+ |
+function WrapInNativeCall(f) { |
+ return function() { |
+ return Debug.ExecuteInDebugContext(f, true); |
+ }; |
+} |
+ |
+function WrapInDebuggerCall(f) { |
+ return function() { |
+ return Debug.ExecuteInDebugContext(f, false); |
+ }; |
+} |
+ |
+function WrapInRestartProof(f) { |
+ var already_called = false; |
+ return function() { |
+ if (already_called) { |
+ return; |
} |
+ already_called = true; |
+ f(); |
+ } |
+} |
+ |
+function WrapInConstructor(f) { |
+ return function() { |
+ return new function() { |
+ f(); |
+ }; |
} |
- print("Change log: " + JSON.stringify(change_log) + "\n"); |
} |
-var new_res = ChooseAnimal(Changer); |
-// Function must be not pached. |
-assertEquals("Cat", new_res); |
-assertEquals(true, got_exception); |
+// A series of tests. In each test we call ChooseAnimal function that calls |
+// a callback that attempts to modify the function on the fly. |
+ |
+test = new TestBase("First test ChooseAnimal without edit"); |
+assertEquals("Cat", test.ChooseAnimal(Noop)); |
+ |
+test = new TestBase("Test without function on stack"); |
+test.ScriptChanger(); |
+assertEquals("Capybara", test.ChooseAnimal(Noop)); |
+ |
+test = new TestBase("Test with function on stack"); |
+assertEquals("Capybara", test.ChooseAnimal(WrapInDebuggerCall(WrapInRestartProof(test.ScriptChanger)))); |
+ |
-// This time it should succeed. |
-Changer(); |
+test = new TestBase("Test with function on stack and with constructor frame"); |
+assertEquals("Capybara", test.ChooseAnimal(WrapInConstructor(WrapInDebuggerCall(WrapInRestartProof(test.ScriptChanger))))); |
-new_res = ChooseAnimal(Noop); |
-// Function must be not pached. |
-assertEquals("Capybara", new_res); |
+test = new TestBase("Test with C++ frame above ChooseAnimal frame"); |
+exception_holder = {}; |
+assertEquals("Cat", test.ChooseAnimal(WrapInNativeCall(WrapInDebuggerCall(WrapInCatcher(test.ScriptChanger, exception_holder))))); |
+assertTrue(!!exception_holder[0]); |