tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Frame-onStep-generator-resumption-02.js (2252B)


      1 // Like Frame-onStep-generator-resumption-01.js, but bail out by throwing.
      2 
      3 let g = newGlobal({newCompartment: true});
      4 g.eval(`
      5  function* f() {
      6    yield 1;
      7  }
      8 `);
      9 
     10 // Try force-returning from one of the instructions in `f` before the initial
     11 // yield. In detail:
     12 //
     13 // *   This test calls `g.f()` under the Debugger.
     14 // *   It uses the Debugger to step `ttl` times.
     15 //     If we reach the initial yield before stepping the `ttl`th time, we're done.
     16 // *   Otherwise, the test tries to force-return from `f`.
     17 // *   That's an error, so the uncaughtExceptionHook is called.
     18 // *   The uncaughtExceptionHook returns a `throw` completion value.
     19 //
     20 // Returns `true` if we reached the initial yield, false otherwise.
     21 //
     22 // Note that this function is called in a loop so that every possible relevant
     23 // value of `ttl` is tried once.
     24 function test(ttl) {
     25  let dbg = new Debugger(g);
     26  let exiting = false;  // we ran out of time-to-live and have forced return
     27  let done = false;  // we reached the initial yield without forced return
     28  let reported = false;  // a TypeError was reported.
     29 
     30  dbg.onEnterFrame = frame => {
     31    assertEq(frame.callee.name, "f");
     32    dbg.onEnterFrame = undefined;
     33    frame.onStep = () => {
     34      if (ttl == 0) {
     35        exiting = true;
     36        // This test case never resumes the generator after the initial
     37        // yield. Therefore the initial yield has not happened yet. So this
     38        // force-return will be an error.
     39        return {return: "ponies"};
     40      }
     41      ttl--;
     42    };
     43    frame.onPop = completion => {
     44      if (!exiting)
     45        done = true;
     46    };
     47  };
     48 
     49  dbg.uncaughtExceptionHook = (exc) => {
     50    // When onStep returns an invalid resumption value,
     51    // the error is reported here.
     52    assertEq(exc instanceof TypeError, true);
     53    reported = true;
     54    return {throw: "FAIL"};  // Bail out of the test.
     55  };
     56 
     57  let result;
     58  let caught = undefined;
     59  try {
     60    result = g.f();
     61  } catch (exc) {
     62    caught = exc;
     63  }
     64 
     65  if (done) {
     66    assertEq(reported, false);
     67    assertEq(result instanceof g.f, true);
     68    assertEq(caught, undefined);
     69  } else {
     70    assertEq(reported, true);
     71    assertEq(caught, "FAIL");
     72  }
     73 
     74  dbg.enabled = false;
     75  return done;
     76 }
     77 
     78 for (let ttl = 0; !test(ttl); ttl++) {}