summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js
blob: 2c67bbce8bc66cc3539af8b09cbd58151632a168 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// |jit-test| skip-if: !wasmGcEnabled()

// Attempt to test intercalls from ion to baseline and back.
//
// We get into this situation when the modules are compiled with different
// tiering policies, or one tiers up before the other, or (for now) one opts
// into gc and is baseline-compiled and the other does not and is ion-compiled.
// There are lots of variables here.  Generally, a small module will be
// ion-compiled unless there's reason to baseline-compile it, so we're likely
// actually testing something here.
//
// Some logging with printf confirms that refmod is baseline-compiled and
// nonrefmod is ion-compiled at present, with --setpref=wasm_gc=true enabled.

var refmod = new WebAssembly.Module(wasmTextToBinary(
    `(module
      (import "" "tbl" (table $tbl 4 funcref))
      (import "" "print" (func $print (param i32)))

      ;; Just a dummy
      (type $s (struct (field i32)))

      (type $htype (func (param externref)))
      (type $itype (func (result externref)))

      (elem (i32.const 0) $f $g)

      (func $f (param externref)
       (call $print (i32.const 1)))

      (func $g (result externref)
       (call $print (i32.const 2))
       (ref.null extern))

      (func (export "test_h")
       (call_indirect (type $htype) (ref.null extern) (i32.const 2)))

      (func (export "test_i")
       (drop (call_indirect (type $itype) (i32.const 3))))

     )`));

var nonrefmod = new WebAssembly.Module(wasmTextToBinary(
    `(module
      (import "" "tbl" (table $tbl 4 funcref))
      (import "" "print" (func $print (param i32)))

      (type $ftype (func (param i32)))
      (type $gtype (func (result i32)))

      (elem (i32.const 2) $h $i)

      ;; Should fail because of the signature mismatch: parameter
      (func (export "test_f")
       (call_indirect (type $ftype) (i32.const 37) (i32.const 0)))

      ;; Should fail because of the signature mismatch: return value
      (func (export "test_g")
       (drop (call_indirect (type $gtype) (i32.const 1))))

      (func $h (param i32)
       (call $print (i32.const 2)))

      (func $i (result i32)
       (call $print (i32.const 3))
       (i32.const 37))
     )`));

var tbl = new WebAssembly.Table({initial:4, element:"anyfunc"});
var refins = new WebAssembly.Instance(refmod, {"":{print, tbl}}).exports;
var nonrefins = new WebAssembly.Instance(nonrefmod, {"":{print, tbl}}).exports;

assertErrorMessage(() => nonrefins.test_f(),
                   WebAssembly.RuntimeError,
                   /indirect call signature mismatch/);

assertErrorMessage(() => nonrefins.test_g(),
                   WebAssembly.RuntimeError,
                   /indirect call signature mismatch/);

assertErrorMessage(() => refins.test_h(),
                   WebAssembly.RuntimeError,
                   /indirect call signature mismatch/);

assertErrorMessage(() => refins.test_i(),
                   WebAssembly.RuntimeError,
                   /indirect call signature mismatch/);