tor-browser

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

onEnterFrame-generator-01.js (2496B)


      1 // Frame properties and methods work in generator-resuming onEnterFrame events.
      2 // Also tests onPop events, for good measure.
      3 
      4 let g = newGlobal({newCompartment: true});
      5 g.eval(`\
      6    function* gen(lo, hi) {
      7        var a = 1/2;
      8        yield a;
      9        yield a * a;
     10    }
     11 `);
     12 let dbg = new Debugger;
     13 let gw = dbg.addDebuggee(g);
     14 
     15 let hits = 0;
     16 let savedScript = null;
     17 let savedEnv = null;
     18 let savedOffsets = new Set;
     19 
     20 function check(frame) {
     21    assertEq(frame.type, "call");
     22    assertEq(frame.constructing, false);
     23    assertEq(frame.callee, gw.makeDebuggeeValue(g.gen));
     24 
     25    // `arguments` elements don't work in resumed generator frames,
     26    // because generators don't keep the arguments around.
     27    // However, some of this is initialized when the frame.arguments object is
     28    // created, so if they are created during the first onEnterFrame or onPop
     29    // event, the properties exist, and those events can also see the values.
     30    assertEq(frame.arguments.length, args.length);
     31    for (var i = 0; i < args.length; i++) {
     32        assertEq(frame.arguments.hasOwnProperty(i), true);
     33 
     34        if (hits < 2)
     35            assertEq(frame.arguments[i], gw.makeDebuggeeValue(args[i]), `arguments[${i}]`);
     36        else
     37            assertEq(frame.arguments[i], undefined);
     38    }
     39 
     40    if (savedEnv === null) {
     41        savedEnv = frame.environment;
     42        assertEq(savedScript, null);
     43        savedScript = frame.script;
     44    } else {
     45        assertEq(frame.environment, savedEnv);
     46        assertEq(frame.script, savedScript);
     47    }
     48    let a_expected = hits < 3 ? undefined : 1/2;
     49    assertEq(savedEnv.getVariable("a"), a_expected);
     50 
     51    assertEq(frame.onStack, true);
     52 
     53    let pc = frame.offset;
     54    assertEq(savedOffsets.has(pc), false);
     55    savedOffsets.add(pc);
     56 
     57    assertEq(frame.older, null);
     58    assertEq(frame.this, gw.makeDebuggeeValue(g));
     59    assertEq(typeof frame.implementation, "string");
     60 
     61    // And the moment of truth:
     62    assertEq(frame.eval("2 + 2").return, 4);
     63    assertEq(frame.eval("a").return, a_expected);
     64    assertEq(frame.eval("if (a !== undefined) { assertEq(a < (lo + hi) / 2, true); } 7;").return, 7);
     65 }
     66 
     67 dbg.onEnterFrame = frame => {
     68    if (frame.type === "eval")
     69        return;
     70    check(frame);
     71    hits++;
     72    frame.onPop = completion => {
     73        check(frame);
     74        hits++;
     75    };
     76 };
     77 
     78 // g.gen ignores the arguments passed to it, but we use them to test
     79 // frame.arguments.
     80 let args = [0, 10, g, dbg];
     81 for (let v of g.gen(...args)) {}
     82 assertEq(hits, 8);