Home | History | Annotate | Download | only in es6
      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
      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 })();
    120