tor-browser

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

1438121-generator.js (4150B)


      1 const mainGlobal = this;
      2 const debuggerGlobal = newGlobal({newCompartment: true});
      3 
      4 function Memory({global}) {
      5  this.dbg = new (debuggerGlobal.Debugger);
      6  this.gDO = this.dbg.addDebuggee(global);
      7 }
      8 
      9 Memory.prototype = {
     10  constructor: Memory,
     11  attach() { return Promise.resolve('fake attach result'); },
     12  detach() { return Promise.resolve('fake detach result'); },
     13  startRecordingAllocations() {
     14    this.dbg.memory.trackingAllocationSites = true;
     15    return Promise.resolve('fake startRecordingAllocations result');
     16  },
     17  stopRecordingAllocations() {
     18    this.dbg.memory.trackingAllocationSites = false;
     19    return Promise.resolve('fake stopRecordingAllocations result');
     20  },
     21  getAllocations() {
     22    return Promise.resolve({ allocations: this.dbg.memory.drainAllocationsLog() });
     23  }
     24 };
     25 
     26 function ok(cond, msg) {
     27  assertEq(!!cond, true, `ok(${JSON.stringify(cond)}, ${JSON.stringify(msg)})`);
     28 }
     29 
     30 const is = assertEq;
     31 
     32 function startServerAndGetSelectedTabMemory() {
     33  let memory = new Memory({ global: mainGlobal });
     34  return Promise.resolve({ memory, client: 'fake client' });
     35 }
     36 
     37 function destroyServerAndFinish() {
     38  return Promise.resolve('fake destroyServerAndFinish result');
     39 }
     40 
     41 function* body() {
     42  let { memory, client } = yield startServerAndGetSelectedTabMemory();
     43  yield memory.attach();
     44 
     45  yield memory.startRecordingAllocations();
     46  ok(true, "Can start recording allocations");
     47 
     48  // Allocate some objects.
     49 
     50  let alloc1, alloc2, alloc3;
     51 
     52  /* eslint-disable max-nested-callbacks */
     53  (function outer() {
     54    (function middle() {
     55      (function inner() {
     56        alloc1 = {}; alloc1.line = Error().lineNumber;
     57        alloc2 = []; alloc2.line = Error().lineNumber;
     58        // eslint-disable-next-line new-parens
     59        alloc3 = new function () {}; alloc3.line = Error().lineNumber;
     60      }());
     61    }());
     62  }());
     63  /* eslint-enable max-nested-callbacks */
     64 
     65  let response = yield memory.getAllocations();
     66 
     67  yield memory.stopRecordingAllocations();
     68  ok(true, "Can stop recording allocations");
     69 
     70  // Filter out allocations by library and test code, and get only the
     71  // allocations that occurred in our test case above.
     72 
     73  function isTestAllocation(alloc) {
     74    let frame = alloc.frame;
     75    return frame
     76      && frame.functionDisplayName === "inner"
     77      && (frame.line === alloc1.line
     78          || frame.line === alloc2.line
     79          || frame.line === alloc3.line);
     80  }
     81 
     82  let testAllocations = response.allocations.filter(isTestAllocation);
     83  ok(testAllocations.length >= 3,
     84     "Should find our 3 test allocations (plus some allocations for the error "
     85     + "objects used to get line numbers)");
     86 
     87  // For each of the test case's allocations, ensure that the parent frame
     88  // indices are correct. Also test that we did get an allocation at each
     89  // line we expected (rather than a bunch on the first line and none on the
     90  // others, etc).
     91 
     92  let expectedLines = new Set([alloc1.line, alloc2.line, alloc3.line]);
     93 
     94  for (let alloc of testAllocations) {
     95    let innerFrame = alloc.frame;
     96    ok(innerFrame, "Should get the inner frame");
     97    is(innerFrame.functionDisplayName, "inner");
     98    expectedLines.delete(innerFrame.line);
     99 
    100    let middleFrame = innerFrame.parent;
    101    ok(middleFrame, "Should get the middle frame");
    102    is(middleFrame.functionDisplayName, "middle");
    103 
    104    let outerFrame = middleFrame.parent;
    105    ok(outerFrame, "Should get the outer frame");
    106    is(outerFrame.functionDisplayName, "outer");
    107 
    108    // Not going to test the rest of the frames because they are Task.jsm
    109    // and promise frames and it gets gross. Plus, I wouldn't want this test
    110    // to start failing if they changed their implementations in a way that
    111    // added or removed stack frames here.
    112  }
    113 
    114  is(expectedLines.size, 0,
    115     "Should have found all the expected lines");
    116 
    117  yield memory.detach();
    118  destroyServerAndFinish(client);
    119 }
    120 
    121 const generator = body();
    122 loop(generator.next());
    123 
    124 function loop({ value: promise, done }) {
    125  if (done)
    126    return;
    127  promise
    128    .catch(e => loop(generator.throw(e)))
    129    .then(v => { loop(generator.next(v)); })
    130    .catch(e => { print(`Error: ${e}\nstack:\n${e.stack}`); });
    131 }