OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 // Flags: --harmony-async-await |
5 // Flags: --expose-debug-as debug --allow-natives-syntax --ignition-generators | 6 // Flags: --expose-debug-as debug --allow-natives-syntax --ignition-generators |
6 | 7 |
7 var Debug = debug.Debug; | 8 var Debug = debug.Debug; |
8 var LiveEdit = Debug.LiveEdit; | 9 var LiveEdit = Debug.LiveEdit; |
9 | 10 |
10 unique_id = 0; | 11 unique_id = 0; |
11 | 12 |
12 var Generator = (function*(){}).constructor; | 13 var AsyncFunction = (async function(){}).constructor; |
13 | 14 |
14 function assertIteratorResult(value, done, result) { | 15 function assertPromiseValue(value, promise) { |
15 assertEquals({value: value, done: done}, result); | 16 promise.then(resolve => { |
| 17 went = true; |
| 18 if (resolve !== value) { |
| 19 print(`expected ${value} found ${resolve}`); |
| 20 quit(1); |
| 21 } |
| 22 }, reject => { |
| 23 print(`rejected ${reject}`); |
| 24 quit(1); |
| 25 }); |
16 } | 26 } |
17 | 27 |
18 function MakeGenerator() { | 28 function MakeAsyncFunction() { |
19 // Prevents eval script caching. | 29 // Prevents eval script caching. |
20 unique_id++; | 30 unique_id++; |
21 return Generator('callback', | 31 return AsyncFunction('callback', |
22 "/* " + unique_id + "*/\n" + | 32 "/* " + unique_id + "*/\n" + |
23 "yield callback();\n" + | 33 "await callback();\n" + |
24 "return 'Cat';\n"); | 34 "return 'Cat';\n"); |
25 } | 35 } |
26 | 36 |
27 function MakeFunction() { | 37 function MakeFunction() { |
28 // Prevents eval script caching. | 38 // Prevents eval script caching. |
29 unique_id++; | 39 unique_id++; |
30 return Function('callback', | 40 return Function('callback', |
31 "/* " + unique_id + "*/\n" + | 41 "/* " + unique_id + "*/\n" + |
32 "callback();\n" + | 42 "callback();\n" + |
33 "return 'Cat';\n"); | 43 "return 'Cat';\n"); |
34 } | 44 } |
35 | 45 |
36 // First, try MakeGenerator with no perturbations. | 46 // First, try MakeGenerator with no perturbations. |
37 (function(){ | 47 (function(){ |
38 var generator = MakeGenerator(); | 48 var asyncfn = MakeAsyncFunction(); |
39 function callback() {}; | 49 function callback() {}; |
40 var iter = generator(callback); | 50 var promise = asyncfn(callback); |
41 assertIteratorResult(undefined, false, iter.next()); | 51 assertPromiseValue('Cat', promise); |
42 assertIteratorResult("Cat", true, iter.next()); | |
43 })(); | 52 })(); |
44 | 53 |
45 function patch(fun, from, to) { | 54 function patch(fun, from, to) { |
46 function debug() { | 55 function debug() { |
47 var log = new Array(); | 56 var log = new Array(); |
48 var script = Debug.findScript(fun); | 57 var script = Debug.findScript(fun); |
49 var pos = script.source.indexOf(from); | 58 var pos = script.source.indexOf(from); |
| 59 print(`pos ${pos}`); |
50 try { | 60 try { |
51 LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to, | 61 LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to, |
52 log); | 62 log); |
53 } finally { | 63 } finally { |
54 print("Change log: " + JSON.stringify(log) + "\n"); | 64 print("Change log: " + JSON.stringify(log) + "\n"); |
55 } | 65 } |
56 } | 66 } |
57 %ExecuteInDebugContext(debug); | 67 %ExecuteInDebugContext(debug); |
58 } | 68 } |
59 | 69 |
60 // Try to edit a MakeGenerator while it's running, then again while it's | 70 // Try to edit a MakeAsyncFunction while it's running, then again while it's |
61 // stopped. | 71 // stopped. |
62 (function(){ | 72 (function(){ |
63 var generator = MakeGenerator(); | 73 var asyncfn = MakeAsyncFunction(); |
64 | 74 |
65 var gen_patch_attempted = false; | 75 var patch_attempted = false; |
66 function attempt_gen_patch() { | 76 function attempt_patch() { |
67 assertFalse(gen_patch_attempted); | 77 assertFalse(patch_attempted); |
68 gen_patch_attempted = true; | 78 patch_attempted = true; |
69 assertThrows(function() { patch(generator, "'Cat'", "'Capybara'") }, | 79 assertThrows(function() { patch(asyncfn, "'Cat'", "'Capybara'") }, |
70 LiveEdit.Failure); | 80 LiveEdit.Failure); |
71 }; | 81 }; |
72 var iter = generator(attempt_gen_patch); | 82 var promise = asyncfn(attempt_patch); |
73 assertIteratorResult(undefined, false, iter.next()); | 83 // Patch should not succeed because there is a live async function activation |
74 // Patch should not succeed because there is a live generator activation on | 84 // on the stack. |
75 // the stack. | 85 assertPromiseValue("Cat", promise); |
76 assertIteratorResult("Cat", true, iter.next()); | 86 assertTrue(patch_attempted); |
77 assertTrue(gen_patch_attempted); | 87 |
| 88 %RunMicrotasks(); |
78 | 89 |
79 // At this point one iterator is live, but closed, so the patch will succeed. | 90 // At this point one iterator is live, but closed, so the patch will succeed. |
80 patch(generator, "'Cat'", "'Capybara'"); | 91 patch(asyncfn, "'Cat'", "'Capybara'"); |
81 iter = generator(function(){}); | 92 promise = asyncfn(function(){}); |
82 assertIteratorResult(undefined, false, iter.next()); | |
83 // Patch successful. | 93 // Patch successful. |
84 assertIteratorResult("Capybara", true, iter.next()); | 94 assertPromiseValue("Capybara", promise); |
85 | 95 |
86 // Patching will fail however when a live iterator is suspended. | 96 // Patching will fail however when an async function is suspended. |
87 iter = generator(function(){}); | 97 var resolve; |
88 assertIteratorResult(undefined, false, iter.next()); | 98 promise = asyncfn(function(){return new Promise(function(r){resolve = r})}); |
89 assertThrows(function() { patch(generator, "'Capybara'", "'Tapir'") }, | 99 assertThrows(function() { patch(asyncfn, "'Capybara'", "'Tapir'") }, |
90 LiveEdit.Failure); | 100 LiveEdit.Failure); |
91 assertIteratorResult("Capybara", true, iter.next()); | 101 resolve(); |
| 102 assertPromiseValue("Capybara", promise); |
92 | 103 |
93 // Try to patch functions with activations inside and outside generator | 104 // Try to patch functions with activations inside and outside async |
94 // function activations. We should succeed in the former case, but not in the | 105 // function activations. We should succeed in the former case, but not in the |
95 // latter. | 106 // latter. |
96 var fun_outside = MakeFunction(); | 107 var fun_outside = MakeFunction(); |
97 var fun_inside = MakeFunction(); | 108 var fun_inside = MakeFunction(); |
98 var fun_patch_attempted = false; | 109 var fun_patch_attempted = false; |
99 var fun_patch_restarted = false; | 110 var fun_patch_restarted = false; |
100 function attempt_fun_patches() { | 111 function attempt_fun_patches() { |
101 if (fun_patch_attempted) { | 112 if (fun_patch_attempted) { |
102 assertFalse(fun_patch_restarted); | 113 assertFalse(fun_patch_restarted); |
103 fun_patch_restarted = true; | 114 fun_patch_restarted = true; |
104 return; | 115 return; |
105 } | 116 } |
106 fun_patch_attempted = true; | 117 fun_patch_attempted = true; |
107 // Patching outside a generator activation must fail. | 118 // Patching outside an async function activation must fail. |
108 assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") }, | 119 assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") }, |
109 LiveEdit.Failure); | 120 LiveEdit.Failure); |
110 // Patching inside a generator activation may succeed. | 121 // Patching inside an async function activation may succeed. |
111 patch(fun_inside, "'Cat'", "'Koala'"); | 122 patch(fun_inside, "'Cat'", "'Koala'"); |
112 } | 123 } |
113 iter = generator(function() { return fun_inside(attempt_fun_patches) }); | 124 promise = asyncfn(function() { return fun_inside(attempt_fun_patches) }); |
114 assertEquals('Cat', | 125 assertEquals('Cat', |
115 fun_outside(function () { | 126 fun_outside(function () { |
116 assertIteratorResult('Koala', false, iter.next()); | 127 assertPromiseValue('Capybara', promise); |
117 assertTrue(fun_patch_restarted); | 128 assertTrue(fun_patch_restarted); |
| 129 assertTrue(fun_inside.toString().includes("'Koala'")); |
118 })); | 130 })); |
119 })(); | 131 })(); |
| 132 |
| 133 %RunMicrotasks(); |
OLD | NEW |