tor-browser

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

ref.js (5703B)


      1 // Parsing and resolving.
      2 
      3 var text = `(module
      4      (rec
      5        (type $cons (struct
      6                     (field $car i32)
      7                     (field $cdr (ref null $cons))))
      8 
      9        (type $odd (struct
     10                    (field $odd.x i32)
     11                    (field $to_even (ref null $even))))
     12 
     13        (type $even (struct
     14                     (field $even.x i32)
     15                     (field $to_odd (ref null $odd))))
     16      )
     17 
     18      ;; Use eqref on the API since struct types cannot be exposed outside the module yet.
     19 
     20      (import "m" "f" (func $imp (param eqref) (result eqref)))
     21 
     22      ;; The bodies do nothing since we have no operations on structs yet.
     23      ;; Note none of these functions are exported, as they use Ref types in their signatures.
     24 
     25      (func (param (ref null $cons)) (result i32)
     26       (i32.const 0))
     27 
     28      (func $cdr (param $p (ref null $cons)) (result (ref null $cons))
     29       (local $l (ref null $cons))
     30       ;; store null value of correct type
     31       (local.set $l (ref.null $cons))
     32       ;; store local of correct type
     33       (local.set $l (local.get $p))
     34       ;; store call result of correct type
     35       (local.set $l (call $cdr (local.get $p)))
     36       ;; TODO: eventually also a test with global.get
     37       ;; blocks and if with result type
     38       (block (result (ref null $cons))
     39       (if (result (ref null $cons)) (i32.eqz (i32.const 0))
     40        (then (unreachable))
     41        (else (ref.null $cons)))))
     42 
     43      (func (param (ref null $even)) (result (ref null $odd))
     44       (ref.null $odd))
     45 
     46      (func (param (ref null $odd)) (result (ref null $even))
     47       (ref.null $even))
     48 
     49      (func (param (ref null $cons))
     50       (call $cdr (local.get 0))
     51       drop
     52       (call $imp (local.get 0))
     53       drop)
     54 
     55      (func (param (ref null $cons))
     56       (drop (ref.eq (local.get 0) (ref.null $cons)))
     57       (drop (ref.eq (ref.null $cons) (local.get 0)))
     58       (drop (ref.eq (local.get 0) (ref.null $cons)))
     59       (drop (ref.eq (ref.null $cons) (local.get 0))))
     60     )`;
     61 
     62 // Validation
     63 
     64 wasmValidateText(text);
     65 
     66 // ref.is_null should work on any reference type
     67 
     68 new WebAssembly.Module(wasmTextToBinary(`
     69 (module
     70 (type $s (struct))
     71 (func $null (param (ref null $s)) (result i32)
     72   (ref.is_null (local.get 0))))
     73 `))
     74 
     75 // Automatic upcast to eqref
     76 
     77 new WebAssembly.Module(wasmTextToBinary(`
     78 (module
     79 (type $s (struct (field i32)))
     80 (func $f (param (ref null $s)) (call $g (local.get 0)))
     81 (func $g (param eqref) (unreachable)))
     82 `));
     83 
     84 // Misc failure modes
     85 
     86 assertErrorMessage(() => wasmEvalText(`
     87 (module
     88 (func (param (ref null $odd)) (unreachable)))
     89 `),
     90 SyntaxError, /failed to find name/);
     91 
     92 // Ref type mismatch in parameter is allowed through the prefix rule
     93 // but not if the structs are incompatible.
     94 
     95 wasmEvalText(`
     96 (module
     97 (type $s (struct (field i32)))
     98 (type $t (struct (field i32)))
     99 (func $f (param (ref null $s)) (unreachable))
    100 (func $g (param (ref null $t)) (call $f (local.get 0)))
    101 )`);
    102 
    103 assertErrorMessage(() => wasmEvalText(`
    104 (module
    105 (type $s (struct (field i32)))
    106 (type $t (struct (field f32))) ;; Incompatible type
    107 (func $f (param (ref null $s)) (unreachable))
    108 (func $g (param (ref null $t)) (call $f (local.get 0)))
    109 )`),
    110 WebAssembly.CompileError, /expression has type \(ref null.*\) but expected \(ref null.*\)/);
    111 
    112 assertErrorMessage(() => wasmEvalText(`
    113 (module
    114 (type $s (struct (field i32)))
    115 (type $t (struct (field (mut i32)))) ;; Incompatible mutability
    116 (func $f (param (ref null $s)) (unreachable))
    117 (func $g (param (ref null $t)) (call $f (local.get 0)))
    118 )`),
    119 WebAssembly.CompileError, /expression has type \(ref null.*\) but expected \(ref null.*\)/);
    120 
    121 // Ref type mismatch in assignment to local but the prefix rule allows
    122 // the assignment to succeed if the structs are the same.
    123 
    124 wasmEvalText(`
    125 (module
    126 (type $s (struct (field i32)))
    127 (type $t (struct (field i32)))
    128 (func $f (param (ref null $s)) (local (ref null $t)) (local.set 1 (local.get 0))))
    129 `)
    130 
    131 assertErrorMessage(() => wasmEvalText(`
    132 (module
    133 (type $s (struct (field i32)))
    134 (type $t (struct (field f32)))
    135 (func $f (param (ref null $s)) (local (ref null $t)) (local.set 1 (local.get 0))))
    136 `),
    137 WebAssembly.CompileError, /expression has type \(ref null.*\) but expected \(ref null.*\)/);
    138 
    139 assertErrorMessage(() => wasmEvalText(`
    140 (module
    141 (type $s (struct (field i32)))
    142 (type $t (struct (field (mut i32))))
    143 (func $f (param (ref null $s)) (unreachable))
    144 (func $g (param (ref null $t)) (call $f (local.get 0)))
    145 )`),
    146 WebAssembly.CompileError, /expression has type \(ref null.*\) but expected \(ref null.*\)/);
    147 
    148 // Ref type mismatch in return but the prefix rule allows the return
    149 // to succeed if the structs are the same.
    150 
    151 wasmEvalText(`
    152 (module
    153 (type $s (struct (field i32)))
    154 (type $t (struct (field i32)))
    155 (func $f (param (ref null $s)) (result (ref null $t)) (local.get 0)))
    156 `);
    157 
    158 assertErrorMessage(() => wasmEvalText(`
    159 (module
    160 (type $s (struct (field i32)))
    161 (type $t (struct (field f32)))
    162 (func $f (param (ref null $s)) (result (ref null $t)) (local.get 0)))
    163 `),
    164 WebAssembly.CompileError, /expression has type \(ref null.*\) but expected \(ref null.*\)/);
    165 
    166 assertErrorMessage(() => wasmEvalText(`
    167 (module
    168 (type $s (struct (field i32)))
    169 (type $t (struct (field (mut i32))))
    170 (func $f (param (ref null $s)) (result (ref null $t)) (local.get 0)))
    171 `),
    172 WebAssembly.CompileError, /expression has type \(ref null.*\) but expected \(ref null.*\)/);
    173 
    174 // No automatic downcast from eqref
    175 
    176 assertErrorMessage(() => wasmEvalText(`
    177 (module
    178 (type $s (struct (field i32)))
    179 (func $f (param eqref) (call $g (local.get 0)))
    180 (func $g (param (ref null $s)) (unreachable)))
    181 `),
    182 WebAssembly.CompileError, /expression has type eqref but expected \(ref null.*\)/);