OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 // Flags: --expose-debug-as debug --harmony-generators |
| 6 |
| 7 var Debug = debug.Debug; |
| 8 var LiveEdit = Debug.LiveEdit; |
| 9 |
| 10 unique_id = 0; |
| 11 |
| 12 var Generator = (function*(){}).constructor; |
| 13 |
| 14 function assertIteratorResult(value, done, result) { |
| 15 assertEquals({value: value, done: done}, result); |
| 16 } |
| 17 |
| 18 function 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 |
| 27 function 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 |
| 45 function 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 } |
| 57 Debug.ExecuteInDebugContext(debug, false); |
| 58 } |
| 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 })(); |
OLD | NEW |