// This is similar to the corresponding JIT exit stub test in the // wasm/import-export.js file, but it also tests BigInt cases. (function testImportJitExit() { let options = getJitCompilerOptions(); if (!options["baseline.enable"]) return; let baselineTrigger = options["baseline.warmup.trigger"]; let valueToConvert = 0; function ffi(n) { if (n == 1337n) { return BigInt(valueToConvert); } return 42n; } // This case is intended to test that the I64 to BigInt argument // filling for the JIT exit stub does not interfere with the other // argument registers. It's important that the BigInt argument comes // first (to test that it doesn't clobber the subsequent ones). function ffi2(n, x1, x2, x3, x4, x5, x6) { return ( 42n + BigInt(x1) + BigInt(x2) + BigInt(x3) + BigInt(x4) + BigInt(x5) + BigInt(x6) ); } // This case is for testing issues with potential GC. function ffi3(n1, n2, n3, n4) { return n3; } // Baseline compile ffis. for (let i = baselineTrigger + 1; i-- > 0; ) { ffi(BigInt(i)); ffi2(BigInt(i), i, i, i, i, i, i); ffi3(BigInt(i), BigInt(i), BigInt(i), BigInt(i)); } let imports = { a: { ffi, ffi2, ffi3, }, }; ex = wasmEvalText( `(module (import "a" "ffi" (func $ffi (param i64) (result i64))) (import "a" "ffi2" (func $ffi2 (param i64 i32 i32 i32 i32 i32 i32) (result i64))) (import "a" "ffi3" (func $ffi3 (param i64 i64 i64 i64) (result i64))) (func (export "callffi") (param i64) (result i64) local.get 0 call $ffi ) (func (export "callffi2") (param i32 i64) (result i64) local.get 1 local.get 0 local.get 0 local.get 0 local.get 0 local.get 0 local.get 0 call $ffi2 ) (func (export "callffi3") (param i64 i64 i64 i64) (result i64) local.get 0 local.get 1 local.get 2 local.get 3 call $ffi3 ) )`, imports ).exports; // Enable the jit exit for each JS callee. assertEq(ex.callffi(0n), 42n); assertEq(ex.callffi2(2, 0n), 54n); assertEq(ex.callffi3(0n, 1n, 2n, 3n), 2n); // Test the jit exit under normal conditions. assertEq(ex.callffi(0n), 42n); assertEq(ex.callffi(1337n), 0n); assertEq(ex.callffi2(2, 0n), 54n); assertEq(ex.callffi3(0n, 1n, 2n, 3n), 2n); // Test the jit exit with GC stress in order to ensure that // any trigger of GC in the stub do not cause errors. if (this.gczeal) { this.gczeal(2, 1); // Collect on every allocation } for (let i = 0; i < 1000; i++) { assertEq(ex.callffi3(0n, 1n, 2n, 3n), 2n); } })(); // Test JIT entry stub (function testJitEntry() { let options = getJitCompilerOptions(); if (!options["baseline.enable"]) return; let baselineTrigger = options["baseline.warmup.trigger"]; i = wasmEvalText( `(module (func (export "foo") (param i64) (result i64) local.get 0 i64.const 1 i64.add return ) )`, {} ).exports; function caller(n) { return i.foo(42n); } // Baseline compile ffis. for (let i = baselineTrigger + 1; i-- > 0; ) { caller(i); } // Enable the jit entry. assertEq(caller(0), 43n); // Test the jit exit under normal conditions. assertEq(caller(0), 43n); })();