tor-browser

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

debug.js (2266B)


      1 // Tests stepping through the wasm code with JS PI suspendable stack.
      2 
      3 const g = newGlobal({ newCompartment: true });
      4 const dbg = new Debugger(g);
      5 
      6 // Estimate internal SP range.
      7 var base = stackPointerInfo();
      8 var estimatedLimit = base - 300000;
      9 var checkFailed = false;
     10 var checksPerformed = {};
     11 
     12 // Checks current SP being in the estimated range --
     13 // the debugger callbacks must be executed on the main stack.
     14 function checkStack(s) {
     15  var sp = stackPointerInfo();
     16  checksPerformed[s] = true;
     17  if (sp < estimatedLimit || sp > base) {
     18    print(`Check failed: ${sp} not in [${estimatedLimit}, ${base}], at ${s}`);
     19    checkFailed = true;
     20  }
     21 }
     22 checkStack();
     23 assertEq(checkFailed, false);
     24 
     25 dbg.onEnterFrame = function(frame) {
     26  if (frame.type != "wasmcall") {
     27    return;
     28  }
     29  checkStack("enter");
     30  frame.onStep = () => {
     31    checkStack("step");
     32    frame.offset; // check if frame is valid
     33  };
     34  frame.onPop = () => {
     35    checkStack("pop");
     36  }
     37 };
     38 dbg.onExceptionUnwind = function (f, e) {
     39  checkStack("exception");
     40 };
     41 
     42 // Run typical JS PI program: create suspendable stack, suspend execution,
     43 // throw on suspendable stack.
     44 g.eval(`
     45 function wasmEvalText(t, imp) {
     46  var wasm = wasmTextToBinary(t)
     47  var mod = new WebAssembly.Module(wasm);
     48  var ins = new WebAssembly.Instance(mod, imp);
     49  return ins;
     50 }
     51 
     52 try{throw"";}catch(_){} // init onExceptionUnwind
     53 
     54 var compute_delta = (i) => {
     55  return Promise.resolve(i/100 || 1);
     56 };
     57 
     58 var suspending_compute_delta = new WebAssembly.Suspending(compute_delta);
     59 var ins = wasmEvalText(\`(module
     60    (import "js" "compute_delta"
     61      (func $compute_delta (param i32) (result f64)))
     62    (tag $t)
     63    (func (export "update_state_export") (param i32) (result f64)
     64      local.get 0
     65      call $compute_delta
     66      i32.const 4
     67      i32.const 2
     68      i32.add
     69      drop
     70      throw $t
     71    )
     72 )\`, {
     73  js: {
     74    compute_delta: suspending_compute_delta,
     75  },
     76 });
     77 
     78 var update_state = WebAssembly.promising(ins.exports.update_state_export);
     79 
     80 var res = update_state(4);
     81 res.then((r) => {
     82  print("RES:" + r);
     83 }).catch(e => {
     84  print("ERR: " + e);
     85 });
     86 
     87 drainJobQueue();
     88 `);
     89 
     90 assertEq(checkFailed, false);
     91 for (let i of ['enter', 'step', 'pop', 'exception']) {
     92  assertEq(i in checksPerformed, true, `${i} check performed`);
     93 }