tor-browser

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

litmus4.js (1646B)


      1 // Mutually recursive functions implement a multi-entry loop using indirect tail
      2 // calls, with exception handling.
      3 //
      4 // The functions do not have the same signatures, so if all arguments are stack
      5 // arguments then these use different amounts of stack space.
      6 //
      7 // The "even" function will throw when the input is zero, so when an exception
      8 // bubbles out of return_call it must not be caught by the exception handler in
      9 // "odd", but must instead be delegated to the caller, which is JS code.
     10 
     11 var ins = wasmEvalText(`
     12 (module
     13  (table 2 2 funcref)
     14  (elem (i32.const 0) $even $odd)
     15  (type $even_t (func (param i32) (result i32)))
     16  (type $odd_t (func (param i32 i32) (result i32)))
     17  (tag $t)
     18 
     19  (func $odd (export "odd") (param $n i32) (param $dummy i32) (result i32)
     20    try (result i32)
     21    (if (result i32) (i32.eqz (local.get $n))
     22        (then (return (i32.const 0)))
     23        (else (return_call_indirect (type $even_t) (i32.sub (local.get $n) (i32.const 1))
     24                              (i32.const 0))))
     25    catch_all
     26      unreachable
     27    end)
     28 
     29  (func $even (export "even") (param $n i32) (result i32)
     30    (if (result i32) (i32.eqz (local.get $n))
     31        (then (throw $t))
     32        (else (return_call_indirect (type $odd_t) (i32.sub (local.get $n) (i32.const 1)) (i32.const 33)
     33                              (i32.const 1)))))
     34 )
     35 `);
     36 
     37 assertErrorMessage(() => ins.exports.even(TailCallIterations), WebAssembly.Exception, /.*/);
     38 assertEq(ins.exports.odd(TailCallIterations, 33), 0);
     39 
     40 assertEq(ins.exports.even(TailCallIterations+1), 0);
     41 assertErrorMessage(() => ins.exports.odd(TailCallIterations+1, 33), WebAssembly.Exception, /.*/);