Skip to content

Commit 9d91344

Browse files
committed
Merge remote-tracking branch 'gc/main' into wasm-3.0
2 parents 74654a4 + 756060f commit 9d91344

File tree

7 files changed

+240
-3
lines changed

7 files changed

+240
-3
lines changed

document/core/appendix/changes.rst

+2
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,8 @@ Added more precise types for references. [#proposal-typedref]_
462462

463463
* Refined typing of :ref:`local instructions <valid-instr-variable>` and :ref:`instruction sequences <valid-instr-seq>` to track the :ref:`initialization status <syntax-init>` of :ref:`locals <syntax-local>` with non-:ref:`defaultable <valid-defaultable>` type
464464

465+
* Refined decoding of :ref:`active <syntax-elemmode>` :ref:`element segments <binary-elem>` with implicit element type and plain function indices (opcode :math:`0`) to produce :ref:`non-nullable <syntax-nullable>` :ref:`reference type <syntax-reftype>`.
466+
465467
* Extended :ref:`table definitions <syntax-table>` with optional initializer expression
466468

467469

document/core/appendix/index-instructions.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ def Instruction(name, opcode, type=None, validation=None, execution=None, operat
334334
Instruction(r'\STRUCTGETS~x~y', r'\hex{FB}~\hex{03}', r'[(\REF~\NULL~x)] \to [\I32]', r'valid-struct.get', r'exec-struct.get'),
335335
Instruction(r'\STRUCTGETU~x~y', r'\hex{FB}~\hex{04}', r'[(\REF~\NULL~x)] \to [\I32]', r'valid-struct.get', r'exec-struct.get'),
336336
Instruction(r'\STRUCTSET~x~y', r'\hex{FB}~\hex{05}', r'[(\REF~\NULL~x)~t] \to []', r'valid-struct.set', r'exec-struct.set'),
337-
Instruction(r'\ARRAYNEW~x', r'\hex{FB}~\hex{06}', r'[t] \to [(\REF~x)]', r'valid-array.new', r'exec-array.new'),
337+
Instruction(r'\ARRAYNEW~x', r'\hex{FB}~\hex{06}', r'[t~\I32] \to [(\REF~x)]', r'valid-array.new', r'exec-array.new'),
338338
Instruction(r'\ARRAYNEWDEFAULT~x', r'\hex{FB}~\hex{07}', r'[\I32] \to [(\REF~x)]', r'valid-array.new', r'exec-array.new'),
339339
Instruction(r'\ARRAYNEWFIXED~x~n', r'\hex{FB}~\hex{08}', r'[t^n] \to [(\REF~x)]', r'valid-array.new_fixed', r'exec-array.new_fixed'),
340340
Instruction(r'\ARRAYNEWDATA~x~y', r'\hex{FB}~\hex{09}', r'[\I32~\I32] \to [(\REF~x)]', r'valid-array.new_data', r'exec-array.new_data'),

document/core/exec/instructions.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -4753,7 +4753,7 @@ Control Instructions
47534753
\begin{array}[t]{@{}r@{~}l@{}}
47544754
(\iff & S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM[i] = \REFFUNCADDR~a \\
47554755
\wedge & S.\SFUNCS[a] = f \\
4756-
\wedge & S \vdashdeftypematch F.\AMODULE.\MITYPES[y] \matchesdeftype f.\FITYPE)
4756+
\wedge & S \vdashdeftypematch f.\FITYPE \matchesdeftype F.\AMODULE.\MITYPES[y])
47574757
\end{array}
47584758
\\[1ex]
47594759
\begin{array}{lcl@{\qquad}l}

test/core/gc/array_new_data.wast

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
(module
2+
(type $arr (array (mut i8)))
3+
4+
(data $d "abcd")
5+
6+
(func (export "array-new-data") (param i32 i32) (result (ref $arr))
7+
(array.new_data $arr $d (local.get 0) (local.get 1))
8+
)
9+
)
10+
11+
;; In-bounds data segment accesses.
12+
(assert_return (invoke "array-new-data" (i32.const 0) (i32.const 0)) (ref.array))
13+
(assert_return (invoke "array-new-data" (i32.const 0) (i32.const 4)) (ref.array))
14+
(assert_return (invoke "array-new-data" (i32.const 1) (i32.const 2)) (ref.array))
15+
(assert_return (invoke "array-new-data" (i32.const 4) (i32.const 0)) (ref.array))
16+
17+
;; Out-of-bounds data segment accesses.
18+
(assert_trap (invoke "array-new-data" (i32.const 0) (i32.const 5)) "out of bounds memory access")
19+
(assert_trap (invoke "array-new-data" (i32.const 5) (i32.const 0)) "out of bounds memory access")
20+
(assert_trap (invoke "array-new-data" (i32.const 1) (i32.const 4)) "out of bounds memory access")
21+
(assert_trap (invoke "array-new-data" (i32.const 4) (i32.const 1)) "out of bounds memory access")
22+
23+
24+
(module
25+
(type $arr (array (mut i8)))
26+
27+
(data $d "\aa\bb\cc\dd")
28+
29+
(func (export "array-new-data-contents") (result i32 i32)
30+
(local (ref $arr))
31+
(local.set 0 (array.new_data $arr $d (i32.const 1) (i32.const 2)))
32+
(array.get_u $arr (local.get 0) (i32.const 0))
33+
(array.get_u $arr (local.get 0) (i32.const 1))
34+
)
35+
)
36+
37+
;; Array is initialized with the correct contents.
38+
(assert_return (invoke "array-new-data-contents") (i32.const 0xbb) (i32.const 0xcc))
39+
40+
(module
41+
(type $arr (array (mut i32)))
42+
43+
(data $d "\aa\bb\cc\dd")
44+
45+
(func (export "array-new-data-little-endian") (result i32)
46+
(array.get $arr
47+
(array.new_data $arr $d (i32.const 0) (i32.const 1))
48+
(i32.const 0))
49+
)
50+
)
51+
52+
;; Data segments are interpreted as little-endian.
53+
(assert_return (invoke "array-new-data-little-endian") (i32.const 0xddccbbaa))
54+
55+
(module
56+
(type $arr (array (mut i16)))
57+
58+
(data $d "\00\11\22")
59+
60+
(func (export "array-new-data-unaligned") (result i32)
61+
(array.get_u $arr
62+
(array.new_data $arr $d (i32.const 1) (i32.const 1))
63+
(i32.const 0))
64+
)
65+
)
66+
67+
;; Data inside the segment doesn't need to be aligned to the element size.
68+
(assert_return (invoke "array-new-data-unaligned") (i32.const 0x2211))

test/core/gc/array_new_elem.wast

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
;;;; Expression-style element segments.
2+
3+
(module
4+
(type $arr (array i31ref))
5+
6+
(elem $e i31ref
7+
(ref.i31 (i32.const 0xaa))
8+
(ref.i31 (i32.const 0xbb))
9+
(ref.i31 (i32.const 0xcc))
10+
(ref.i31 (i32.const 0xdd)))
11+
12+
(func (export "array-new-elem") (param i32 i32) (result (ref $arr))
13+
(array.new_elem $arr $e (local.get 0) (local.get 1))
14+
)
15+
)
16+
17+
;; In-bounds element segment accesses.
18+
(assert_return (invoke "array-new-elem" (i32.const 0) (i32.const 0)) (ref.array))
19+
(assert_return (invoke "array-new-elem" (i32.const 0) (i32.const 4)) (ref.array))
20+
(assert_return (invoke "array-new-elem" (i32.const 1) (i32.const 2)) (ref.array))
21+
(assert_return (invoke "array-new-elem" (i32.const 4) (i32.const 0)) (ref.array))
22+
23+
;; Out-of-bounds element segment accesses.
24+
(assert_trap (invoke "array-new-elem" (i32.const 0) (i32.const 5)) "out of bounds table access")
25+
(assert_trap (invoke "array-new-elem" (i32.const 5) (i32.const 0)) "out of bounds table access")
26+
(assert_trap (invoke "array-new-elem" (i32.const 1) (i32.const 4)) "out of bounds table access")
27+
(assert_trap (invoke "array-new-elem" (i32.const 4) (i32.const 1)) "out of bounds table access")
28+
29+
(module
30+
(type $arr (array i31ref))
31+
32+
(elem $e i31ref
33+
(ref.i31 (i32.const 0xaa))
34+
(ref.i31 (i32.const 0xbb))
35+
(ref.i31 (i32.const 0xcc))
36+
(ref.i31 (i32.const 0xdd)))
37+
38+
(func (export "array-new-elem-contents") (result i32 i32)
39+
(local (ref $arr))
40+
(local.set 0 (array.new_elem $arr $e (i32.const 1) (i32.const 2)))
41+
(i31.get_u (array.get $arr (local.get 0) (i32.const 0)))
42+
(i31.get_u (array.get $arr (local.get 0) (i32.const 1)))
43+
)
44+
)
45+
46+
;; Array is initialized with the correct contents.
47+
(assert_return (invoke "array-new-elem-contents") (i32.const 0xbb) (i32.const 0xcc))
48+
49+
;;;; MVP-style function-index segments.
50+
51+
(module
52+
(type $arr (array funcref))
53+
54+
(elem $e func $aa $bb $cc $dd)
55+
(func $aa (result i32) (i32.const 0xaa))
56+
(func $bb (result i32) (i32.const 0xbb))
57+
(func $cc (result i32) (i32.const 0xcc))
58+
(func $dd (result i32) (i32.const 0xdd))
59+
60+
(func (export "array-new-elem") (param i32 i32) (result (ref $arr))
61+
(array.new_elem $arr $e (local.get 0) (local.get 1))
62+
)
63+
)
64+
65+
;; In-bounds element segment accesses.
66+
(assert_return (invoke "array-new-elem" (i32.const 0) (i32.const 0)) (ref.array))
67+
(assert_return (invoke "array-new-elem" (i32.const 0) (i32.const 4)) (ref.array))
68+
(assert_return (invoke "array-new-elem" (i32.const 1) (i32.const 2)) (ref.array))
69+
(assert_return (invoke "array-new-elem" (i32.const 4) (i32.const 0)) (ref.array))
70+
71+
;; Out-of-bounds element segment accesses.
72+
(assert_trap (invoke "array-new-elem" (i32.const 0) (i32.const 5)) "out of bounds table access")
73+
(assert_trap (invoke "array-new-elem" (i32.const 5) (i32.const 0)) "out of bounds table access")
74+
(assert_trap (invoke "array-new-elem" (i32.const 1) (i32.const 4)) "out of bounds table access")
75+
(assert_trap (invoke "array-new-elem" (i32.const 4) (i32.const 1)) "out of bounds table access")
76+
77+
(module
78+
(type $f (func (result i32)))
79+
(type $arr (array funcref))
80+
81+
(elem $e func $aa $bb $cc $dd)
82+
(func $aa (result i32) (i32.const 0xaa))
83+
(func $bb (result i32) (i32.const 0xbb))
84+
(func $cc (result i32) (i32.const 0xcc))
85+
(func $dd (result i32) (i32.const 0xdd))
86+
87+
(table $t 2 2 funcref)
88+
89+
(func (export "array-new-elem-contents") (result i32 i32)
90+
(local (ref $arr))
91+
(local.set 0 (array.new_elem $arr $e (i32.const 1) (i32.const 2)))
92+
93+
(table.set $t (i32.const 0) (array.get $arr (local.get 0) (i32.const 0)))
94+
(table.set $t (i32.const 1) (array.get $arr (local.get 0) (i32.const 1)))
95+
96+
(call_indirect (type $f) (i32.const 0))
97+
(call_indirect (type $f) (i32.const 1))
98+
99+
)
100+
)
101+
102+
;; Array is initialized with the correct contents.
103+
(assert_return (invoke "array-new-elem-contents") (i32.const 0xbb) (i32.const 0xcc))

test/core/gc/i31.wast

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
(i31.get_u (ref.null i31))
1515
)
1616
(func (export "get_s-null") (result i32)
17-
(i31.get_u (ref.null i31))
17+
(i31.get_s (ref.null i31))
1818
)
1919

2020
(global $i (ref i31) (ref.i31 (i32.const 2)))

test/core/gc/type-subtyping.wast

+64
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,70 @@
824824
"sub type"
825825
)
826826

827+
(assert_invalid
828+
(module
829+
(type $a (sub (array (ref none))))
830+
(type $b (sub $a (array (ref any))))
831+
)
832+
"sub type 1 does not match super type"
833+
)
834+
835+
(assert_invalid
836+
(module
837+
(type $a (sub (array (mut (ref any)))))
838+
(type $b (sub $a (array (mut (ref none)))))
839+
)
840+
"sub type 1 does not match super type"
841+
)
842+
843+
(assert_invalid
844+
(module
845+
(type $a (sub (array (mut (ref any)))))
846+
(type $b (sub $a (array (ref any))))
847+
)
848+
"sub type 1 does not match super type"
849+
)
850+
851+
(assert_invalid
852+
(module
853+
(type $a (sub (array (ref any))))
854+
(type $b (sub $a (array (mut (ref any)))))
855+
)
856+
"sub type 1 does not match super type"
857+
)
858+
859+
(assert_invalid
860+
(module
861+
(type $a (sub (struct (field (ref none)))))
862+
(type $b (sub $a (struct (field (ref any)))))
863+
)
864+
"sub type 1 does not match super type"
865+
)
866+
867+
(assert_invalid
868+
(module
869+
(type $a (sub (struct (field (mut (ref any))))))
870+
(type $b (sub $a (struct (field (mut (ref none))))))
871+
)
872+
"sub type 1 does not match super type"
873+
)
874+
875+
(assert_invalid
876+
(module
877+
(type $a (sub (struct (field (mut (ref any))))))
878+
(type $b (sub $a (struct (field (ref any)))))
879+
)
880+
"sub type 1 does not match super type"
881+
)
882+
883+
(assert_invalid
884+
(module
885+
(type $a (sub (struct (field (ref any)))))
886+
(type $b (sub $a (struct (field (mut (ref any))))))
887+
)
888+
"sub type 1 does not match super type"
889+
)
890+
827891
(assert_invalid
828892
(module
829893
(type $f0 (sub (func)))

0 commit comments

Comments
 (0)