1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Flags: --expose-debug-as debug
7 var Debug = debug.Debug;
8 var LiveEdit = Debug.LiveEdit;
12 var Generator = (function*(){}).constructor;
14 function assertIteratorResult(value, done, result) {
15 assertEquals({value: value, done: done}, result);
18 function MakeGenerator() {
19 // Prevents eval script caching.
21 return Generator('callback',
22 "/* " + unique_id + "*/\n" +
23 "yield callback();\n" +
27 function MakeFunction() {
28 // Prevents eval script caching.
30 return Function('callback',
31 "/* " + unique_id + "*/\n" +
36 // First, try MakeGenerator with no perturbations.
38 var generator = MakeGenerator();
39 function callback() {};
40 var iter = generator(callback);
41 assertIteratorResult(undefined, false, iter.next());
42 assertIteratorResult("Cat", true, iter.next());
45 function patch(fun, from, to) {
47 var log = new Array();
48 var script = Debug.findScript(fun);
49 var pos = script.source.indexOf(from);
51 LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
54 print("Change log: " + JSON.stringify(log) + "\n");
57 Debug.ExecuteInDebugContext(debug, false);
60 // Try to edit a MakeGenerator while it's running, then again while it's
63 var generator = MakeGenerator();
65 var gen_patch_attempted = false;
66 function attempt_gen_patch() {
67 assertFalse(gen_patch_attempted);
68 gen_patch_attempted = true;
69 assertThrows(function() { patch(generator, "'Cat'", "'Capybara'") },
72 var iter = generator(attempt_gen_patch);
73 assertIteratorResult(undefined, false, iter.next());
74 // Patch should not succeed because there is a live generator activation on
76 assertIteratorResult("Cat", true, iter.next());
77 assertTrue(gen_patch_attempted);
79 // At this point one iterator is live, but closed, so the patch will succeed.
80 patch(generator, "'Cat'", "'Capybara'");
81 iter = generator(function(){});
82 assertIteratorResult(undefined, false, iter.next());
84 assertIteratorResult("Capybara", true, iter.next());
86 // Patching will fail however when a live iterator is suspended.
87 iter = generator(function(){});
88 assertIteratorResult(undefined, false, iter.next());
89 assertThrows(function() { patch(generator, "'Capybara'", "'Tapir'") },
91 assertIteratorResult("Capybara", true, iter.next());
93 // Try to patch functions with activations inside and outside generator
94 // function activations. We should succeed in the former case, but not in the
96 var fun_outside = MakeFunction();
97 var fun_inside = MakeFunction();
98 var fun_patch_attempted = false;
99 var fun_patch_restarted = false;
100 function attempt_fun_patches() {
101 if (fun_patch_attempted) {
102 assertFalse(fun_patch_restarted);
103 fun_patch_restarted = true;
106 fun_patch_attempted = true;
107 // Patching outside a generator activation must fail.
108 assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
110 // Patching inside a generator activation may succeed.
111 patch(fun_inside, "'Cat'", "'Koala'");
113 iter = generator(function() { return fun_inside(attempt_fun_patches) });
115 fun_outside(function () {
116 assertIteratorResult('Koala', false, iter.next());
117 assertTrue(fun_patch_restarted);