basic.js (3274B)
1 function testPrivateGlobal(valtype, expr, result) { 2 // Immutable private globals have a single cell for wasm. 3 let { get } = wasmEvalText(`(module 4 (global $global ${valtype} ${expr}) 5 (func (export "get") (result ${valtype}) 6 global.get $global 7 ) 8 )`).exports; 9 assertEq(get(), result); 10 } 11 function testExportedGlobal(valtype, expr, result) { 12 // Immutable exported globals have a separate cell for wasm and the exported 13 // global object. 14 let { global, get } = wasmEvalText(`(module 15 (global $global (export "global") ${valtype} ${expr}) 16 (func (export "get") (result ${valtype}) 17 global.get $global 18 ) 19 )`).exports; 20 assertEq(get(), result); 21 assertEq(global.value, result); 22 } 23 function testIndirectGlobal(valtype, expr, result) { 24 // Mutable exported globals share an indirect cell for wasm and the exported 25 // global object. 26 let { global } = wasmEvalText(`(module 27 (global (export "global") (mut ${valtype}) ${expr}) 28 )`).exports; 29 assertEq(global.value, result); 30 } 31 32 // i32 tests 33 34 const I32_SQ_OVERFLOW = 0xFFFF + 1; 35 const MAX_I32 = 0xFFFF_FFFF; 36 function testI32(expr, result) { 37 testPrivateGlobal('i32', expr, result); 38 testExportedGlobal('i32', expr, result); 39 testIndirectGlobal('i32', expr, result); 40 } 41 testI32('i32.const 1', 1); 42 43 testI32('i32.const 1 i32.const 2 i32.add', 3); 44 testI32(`i32.const ${MAX_I32} i32.const 1 i32.add`, 0); 45 46 testI32('i32.const 1 i32.const 2 i32.sub', -1); 47 testI32(`i32.const 1 i32.const 0 i32.sub`, 1); 48 49 testI32('i32.const 1 i32.const 2 i32.mul', 2); 50 testI32(`i32.const ${I32_SQ_OVERFLOW} i32.const ${I32_SQ_OVERFLOW} i32.mul`, 0); 51 52 // i64 tests 53 54 const I64_SQ_OVERFLOW = 0xFFFF_FFFFn + 1n; 55 const MAX_I64 = 0xFFFF_FFFF_FFFF_FFFFn; 56 function testI64(expr, result) { 57 testPrivateGlobal('i64', expr, result); 58 testExportedGlobal('i64', expr, result); 59 testIndirectGlobal('i64', expr, result); 60 } 61 testI64('i64.const 1', 1n); 62 63 testI64('i64.const 1 i64.const 2 i64.add', 3n); 64 testI64(`i64.const ${MAX_I64} i64.const 1 i64.add`, 0n); 65 66 testI64('i64.const 1 i64.const 2 i64.sub', -1n); 67 testI64(`i64.const 1 i64.const 0 i64.sub`, 1n); 68 69 testI64('i64.const 1 i64.const 2 i64.mul', 2n); 70 testI64(`i64.const ${I64_SQ_OVERFLOW} i64.const ${I64_SQ_OVERFLOW} i64.mul`, 0n); 71 72 // test global.get 73 74 function testGlobalGet(valtype, aExpr, bExpr, cExpr, cResult) { 75 let { a, b } = wasmEvalText(`(module 76 (global (export "a") ${valtype} ${aExpr}) 77 (global (export "b") ${valtype} ${bExpr}) 78 )`).exports; 79 let { c } = wasmEvalText(`(module 80 (global $a (import "" "a") ${valtype}) 81 (global $b (import "" "b") ${valtype}) 82 (global (export "c") ${valtype} ${cExpr}) 83 )`, {"": {a, b}}).exports; 84 assertEq(c.value, cResult); 85 } 86 87 testGlobalGet('i32', 'i32.const 2', 'i32.const 3', 'global.get $a global.get $b i32.add', 5); 88 testGlobalGet('i32', 'i32.const 2', 'i32.const 3', 'global.get $a global.get $b i32.sub', -1); 89 testGlobalGet('i32', 'i32.const 2', 'i32.const 3', 'global.get $a global.get $b i32.mul', 6); 90 91 testGlobalGet('i64', 'i64.const 2', 'i64.const 3', 'global.get $a global.get $b i64.add', 5n); 92 testGlobalGet('i64', 'i64.const 2', 'i64.const 3', 'global.get $a global.get $b i64.sub', -1n); 93 testGlobalGet('i64', 'i64.const 2', 'i64.const 3', 'global.get $a global.get $b i64.mul', 6n);