blob: 2bbbfc2d851948ce19fea3f85679100d14793cd8 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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.
4
Ben Murdoch61f157c2016-09-16 13:49:30 +01005// Flags: --expose-debug-as debug --allow-natives-syntax --ignition-generators
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006
7var Debug = debug.Debug;
8var LiveEdit = Debug.LiveEdit;
9
10unique_id = 0;
11
12var Generator = (function*(){}).constructor;
13
14function assertIteratorResult(value, done, result) {
15 assertEquals({value: value, done: done}, result);
16}
17
18function MakeGenerator() {
19 // Prevents eval script caching.
20 unique_id++;
21 return Generator('callback',
22 "/* " + unique_id + "*/\n" +
23 "yield callback();\n" +
24 "return 'Cat';\n");
25}
26
27function MakeFunction() {
28 // Prevents eval script caching.
29 unique_id++;
30 return Function('callback',
31 "/* " + unique_id + "*/\n" +
32 "callback();\n" +
33 "return 'Cat';\n");
34}
35
36// First, try MakeGenerator with no perturbations.
37(function(){
38 var generator = MakeGenerator();
39 function callback() {};
40 var iter = generator(callback);
41 assertIteratorResult(undefined, false, iter.next());
42 assertIteratorResult("Cat", true, iter.next());
43})();
44
45function patch(fun, from, to) {
46 function debug() {
47 var log = new Array();
48 var script = Debug.findScript(fun);
49 var pos = script.source.indexOf(from);
50 try {
51 LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
52 log);
53 } finally {
54 print("Change log: " + JSON.stringify(log) + "\n");
55 }
56 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000057 %ExecuteInDebugContext(debug);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058}
59
60// Try to edit a MakeGenerator while it's running, then again while it's
61// stopped.
62(function(){
63 var generator = MakeGenerator();
64
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'") },
70 LiveEdit.Failure);
71 };
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
75 // the stack.
76 assertIteratorResult("Cat", true, iter.next());
77 assertTrue(gen_patch_attempted);
78
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());
83 // Patch successful.
84 assertIteratorResult("Capybara", true, iter.next());
85
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'") },
90 LiveEdit.Failure);
91 assertIteratorResult("Capybara", true, iter.next());
92
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
95 // latter.
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;
104 return;
105 }
106 fun_patch_attempted = true;
107 // Patching outside a generator activation must fail.
108 assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
109 LiveEdit.Failure);
110 // Patching inside a generator activation may succeed.
111 patch(fun_inside, "'Cat'", "'Koala'");
112 }
113 iter = generator(function() { return fun_inside(attempt_fun_patches) });
114 assertEquals('Cat',
115 fun_outside(function () {
116 assertIteratorResult('Koala', false, iter.next());
117 assertTrue(fun_patch_restarted);
118 }));
119})();