Skip to content

Commit 8779cb6

Browse files
committed
Support all gc tests
1 parent 2bd7144 commit 8779cb6

33 files changed

+2618
-9
lines changed

include/wabt/shared-validator.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ class SharedValidator {
9292
Result OnTable(const Location&, Type elem_type, const Limits&, bool, bool);
9393
Result OnMemory(const Location&, const Limits&, uint32_t page_size);
9494
Result OnGlobalImport(const Location&, Type type, bool mutable_);
95-
Result OnGlobal(const Location&, Type type, bool mutable_);
95+
Result BeginGlobal(const Location&, Type type, bool mutable_);
96+
Result EndGlobal(const Location&);
9697
Result OnTag(const Location&, Var sig_var);
9798

9899
Result OnExport(const Location&,
@@ -383,7 +384,7 @@ class SharedValidator {
383384
std::vector<TagType> tags_; // Includes imported and defined.
384385
std::vector<ElemType> elems_;
385386
Index starts_ = 0;
386-
Index num_imported_globals_ = 0;
387+
Index last_initialized_global_ = 0;
387388
Index data_segments_ = 0;
388389
Index last_rec_type_end_ = 0;
389390
// Recursive type checks may enter to infinite loop for invalid values.

src/binary-writer-spec.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ void BinaryWriterSpec::WriteVar(const Var& var) {
161161
void BinaryWriterSpec::WriteTypeObject(Type type) {
162162
json_stream_->Writef("{");
163163
WriteKey("type");
164+
if (type.IsReferenceWithIndex()) {
165+
// This should happen only for invalid modules.
166+
type = Type::AnyRef;
167+
}
164168
WriteString(type.GetName().c_str());
165169
json_stream_->Writef("}");
166170
}

src/interp/binary-reader-interp.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ Result BinaryReaderInterp::OnGlobalCount(Index count) {
800800
}
801801

802802
Result BinaryReaderInterp::BeginGlobal(Index index, Type type, bool mutable_) {
803-
CHECK_RESULT(validator_.OnGlobal(GetLocation(), type, mutable_));
803+
CHECK_RESULT(validator_.BeginGlobal(GetLocation(), type, mutable_));
804804
GlobalType global_type{type, ToMutability(mutable_)};
805805
FuncDesc init_func{FuncType{{}, {type}}, {}, Istream::kInvalidOffset, {}};
806806
module_.globals.push_back(GlobalDesc{global_type, init_func});
@@ -833,6 +833,7 @@ Result BinaryReaderInterp::BeginInitExpr(FuncDesc* func) {
833833
}
834834

835835
Result BinaryReaderInterp::EndGlobalInitExpr(Index index) {
836+
CHECK_RESULT(validator_.EndGlobal(GetLocation()));
836837
return EndInitExpr();
837838
}
838839

src/shared-validator.cc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,19 +229,26 @@ Result SharedValidator::OnGlobalImport(const Location& loc,
229229
result |= PrintError(loc, "mutable globals cannot be imported");
230230
}
231231
globals_.push_back(GlobalType{type, mutable_});
232-
++num_imported_globals_;
232+
++last_initialized_global_;
233233
return result;
234234
}
235235

236-
Result SharedValidator::OnGlobal(const Location& loc,
237-
Type type,
238-
bool mutable_) {
236+
Result SharedValidator::BeginGlobal(const Location& loc,
237+
Type type,
238+
bool mutable_) {
239239
CHECK_RESULT(
240240
CheckReferenceType(loc, type, type_fields_.NumTypes(), "globals"));
241241
globals_.push_back(GlobalType{type, mutable_});
242242
return Result::Ok;
243243
}
244244

245+
Result SharedValidator::EndGlobal(const Location&) {
246+
if (options_.features.gc_enabled()) {
247+
last_initialized_global_++;
248+
}
249+
return Result::Ok;
250+
}
251+
245252
Result SharedValidator::CheckType(const Location& loc,
246253
Type actual,
247254
Type expected,
@@ -1299,7 +1306,7 @@ Result SharedValidator::OnGlobalGet(const Location& loc, Var global_var) {
12991306
result |= CheckGlobalIndex(global_var, &global_type);
13001307
result |= typechecker_.OnGlobalGet(global_type.type);
13011308
if (Succeeded(result) && in_init_expr_) {
1302-
if (global_var.index() >= num_imported_globals_) {
1309+
if (global_var.index() >= last_initialized_global_) {
13031310
result |= PrintError(
13041311
global_var.loc,
13051312
"initializer expression can only reference an imported global");

src/tools/spectest-interp.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,8 @@ wabt::Result JSONParser::ParseType(Type* out_type) {
629629
*out_type = Type::I8;
630630
} else if (type_str == "i16") {
631631
*out_type = Type::I16;
632+
} else if (type_str == "anyref") {
633+
*out_type = Type::AnyRef;
632634
} else if (type_str == "arrayref") {
633635
*out_type = Type::ArrayRef;
634636
} else if (type_str == "exnref") {

src/validator.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,14 +1056,15 @@ Result Validator::CheckModule() {
10561056
for (const ModuleField& field : module->fields) {
10571057
if (auto* f = dyn_cast<GlobalModuleField>(&field)) {
10581058
result_ |=
1059-
validator_.OnGlobal(field.loc, f->global.type, f->global.mutable_);
1059+
validator_.BeginGlobal(field.loc, f->global.type, f->global.mutable_);
10601060

10611061
// Init expr.
10621062
result_ |= validator_.BeginInitExpr(field.loc, f->global.type);
10631063
ExprVisitor visitor(this);
10641064
result_ |=
10651065
visitor.VisitExprList(const_cast<ExprList&>(f->global.init_expr));
10661066
result_ |= validator_.EndInitExpr();
1067+
result_ |= validator_.EndGlobal(field.loc);
10671068
}
10681069
}
10691070

test/spec/gc/array_new_data.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
;;; TOOL: run-interp-spec
2+
;;; STDIN_FILE: third_party/testsuite/proposals/gc/array_new_data.wast
3+
;;; ARGS*: --enable-gc
4+
(;; STDOUT ;;;
5+
out/test/spec/gc/array_new_data.wast:18: assert_trap passed: invalid range
6+
out/test/spec/gc/array_new_data.wast:19: assert_trap passed: invalid range
7+
out/test/spec/gc/array_new_data.wast:20: assert_trap passed: invalid range
8+
out/test/spec/gc/array_new_data.wast:21: assert_trap passed: invalid range
9+
15/15 tests passed.
10+
;;; STDOUT ;;)

test/spec/gc/array_new_elem.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
;;; TOOL: run-interp-spec
2+
;;; STDIN_FILE: third_party/testsuite/proposals/gc/array_new_elem.wast
3+
;;; ARGS*: --enable-gc
4+
(;; STDOUT ;;;
5+
out/test/spec/gc/array_new_elem.wast:24: assert_trap passed: invalid range
6+
out/test/spec/gc/array_new_elem.wast:25: assert_trap passed: invalid range
7+
out/test/spec/gc/array_new_elem.wast:26: assert_trap passed: invalid range
8+
out/test/spec/gc/array_new_elem.wast:27: assert_trap passed: invalid range
9+
out/test/spec/gc/array_new_elem.wast:72: assert_trap passed: invalid range
10+
out/test/spec/gc/array_new_elem.wast:73: assert_trap passed: invalid range
11+
out/test/spec/gc/array_new_elem.wast:74: assert_trap passed: invalid range
12+
out/test/spec/gc/array_new_elem.wast:75: assert_trap passed: invalid range
13+
22/22 tests passed.
14+
;;; STDOUT ;;)

test/spec/gc/binary-gc.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
;;; TOOL: run-interp-spec
2+
;;; STDIN_FILE: third_party/testsuite/proposals/gc/binary-gc.wast
3+
;;; ARGS*: --enable-gc
4+
(;; STDOUT ;;;
5+
out/test/spec/gc/binary-gc.wast:2: assert_malformed passed:
6+
000000e: error: field mutability must be 0 or 1
7+
1/1 tests passed.
8+
;;; STDOUT ;;)

test/spec/gc/binary.txt

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
;;; TOOL: run-interp-spec
2+
;;; STDIN_FILE: third_party/testsuite/proposals/gc/binary.wast
3+
;;; ARGS*: --enable-gc
4+
(;; STDOUT ;;;
5+
out/test/spec/gc/binary.wast:6: assert_malformed passed:
6+
0000000: error: unable to read uint32_t: magic
7+
out/test/spec/gc/binary.wast:7: assert_malformed passed:
8+
0000000: error: unable to read uint32_t: magic
9+
out/test/spec/gc/binary.wast:8: assert_malformed passed:
10+
0000000: error: unable to read uint32_t: magic
11+
out/test/spec/gc/binary.wast:9: assert_malformed passed:
12+
0000004: error: bad magic value
13+
out/test/spec/gc/binary.wast:10: assert_malformed passed:
14+
0000004: error: bad magic value
15+
out/test/spec/gc/binary.wast:11: assert_malformed passed:
16+
0000004: error: bad magic value
17+
out/test/spec/gc/binary.wast:12: assert_malformed passed:
18+
0000004: error: bad magic value
19+
out/test/spec/gc/binary.wast:13: assert_malformed passed:
20+
0000004: error: bad magic value
21+
out/test/spec/gc/binary.wast:14: assert_malformed passed:
22+
0000004: error: bad magic value
23+
out/test/spec/gc/binary.wast:15: assert_malformed passed:
24+
0000004: error: bad magic value
25+
out/test/spec/gc/binary.wast:16: assert_malformed passed:
26+
0000004: error: bad magic value
27+
out/test/spec/gc/binary.wast:17: assert_malformed passed:
28+
0000004: error: bad magic value
29+
out/test/spec/gc/binary.wast:18: assert_malformed passed:
30+
0000004: error: bad magic value
31+
out/test/spec/gc/binary.wast:21: assert_malformed passed:
32+
0000004: error: bad magic value
33+
out/test/spec/gc/binary.wast:24: assert_malformed passed:
34+
0000004: error: bad magic value
35+
out/test/spec/gc/binary.wast:25: assert_malformed passed:
36+
0000004: error: bad magic value
37+
out/test/spec/gc/binary.wast:28: assert_malformed passed:
38+
0000004: error: bad magic value
39+
out/test/spec/gc/binary.wast:31: assert_malformed passed:
40+
0000004: error: bad magic value
41+
out/test/spec/gc/binary.wast:34: assert_malformed passed:
42+
0000004: error: bad magic value
43+
out/test/spec/gc/binary.wast:37: assert_malformed passed:
44+
0000004: error: unable to read uint16_t: version
45+
out/test/spec/gc/binary.wast:38: assert_malformed passed:
46+
0000004: error: unable to read uint16_t: version
47+
out/test/spec/gc/binary.wast:39: assert_malformed passed:
48+
0000006: error: unable to read uint16_t: layer
49+
out/test/spec/gc/binary.wast:40: assert_malformed passed:
50+
0000008: error: bad wasm file version: 0 (expected 0x1)
51+
out/test/spec/gc/binary.wast:41: assert_malformed passed:
52+
0000008: error: bad wasm file version: 0xd (expected 0x1)
53+
out/test/spec/gc/binary.wast:42: assert_malformed passed:
54+
0000008: error: bad wasm file version: 0xe (expected 0x1)
55+
out/test/spec/gc/binary.wast:43: assert_malformed passed:
56+
0000008: error: bad wasm file version: 0x100 (expected 0x1)
57+
out/test/spec/gc/binary.wast:44: assert_malformed passed:
58+
0000008: error: wasm components are not yet supported in this tool
59+
out/test/spec/gc/binary.wast:45: assert_malformed passed:
60+
0000008: error: unsupported wasm layer: 0x100
61+
out/test/spec/gc/binary.wast:48: assert_malformed passed:
62+
000000a: error: invalid section code: 14
63+
out/test/spec/gc/binary.wast:49: assert_malformed passed:
64+
000000a: error: invalid section code: 127
65+
out/test/spec/gc/binary.wast:50: assert_malformed passed:
66+
000000a: error: invalid section code: 128
67+
out/test/spec/gc/binary.wast:51: assert_malformed passed:
68+
000000a: error: invalid section code: 129
69+
out/test/spec/gc/binary.wast:52: assert_malformed passed:
70+
000000a: error: invalid section code: 255
71+
out/test/spec/gc/binary.wast:56: assert_malformed passed:
72+
000001b: error: function body must end with END opcode
73+
out/test/spec/gc/binary.wast:77: assert_malformed passed:
74+
000001a: error: function body must end with END opcode
75+
out/test/spec/gc/binary.wast:93: assert_malformed passed:
76+
000001a: error: function body must end with END opcode
77+
out/test/spec/gc/binary.wast:113: assert_malformed passed:
78+
0000019: error: init expression must end with END opcode
79+
out/test/spec/gc/binary.wast:126: assert_malformed passed:
80+
0000020: error: memory.grow reserved value must be 0
81+
out/test/spec/gc/binary.wast:146: assert_malformed passed:
82+
0000020: error: memory.grow reserved value must be 0
83+
out/test/spec/gc/binary.wast:166: assert_malformed passed:
84+
0000020: error: memory.grow reserved value must be 0
85+
out/test/spec/gc/binary.wast:185: assert_malformed passed:
86+
0000020: error: memory.grow reserved value must be 0
87+
out/test/spec/gc/binary.wast:204: assert_malformed passed:
88+
0000020: error: memory.grow reserved value must be 0
89+
out/test/spec/gc/binary.wast:224: assert_malformed passed:
90+
000001e: error: memory.size reserved value must be 0
91+
out/test/spec/gc/binary.wast:243: assert_malformed passed:
92+
000001e: error: memory.size reserved value must be 0
93+
out/test/spec/gc/binary.wast:262: assert_malformed passed:
94+
000001e: error: memory.size reserved value must be 0
95+
out/test/spec/gc/binary.wast:280: assert_malformed passed:
96+
000001e: error: memory.size reserved value must be 0
97+
out/test/spec/gc/binary.wast:298: assert_malformed passed:
98+
000001e: error: memory.size reserved value must be 0
99+
out/test/spec/gc/binary.wast:317: assert_malformed passed:
100+
0000017: error: unable to read u32 leb128: local type count
101+
out/test/spec/gc/binary.wast:334: assert_malformed passed:
102+
0000017: error: unable to read u32 leb128: local type count
103+
out/test/spec/gc/binary.wast:351: assert_malformed passed:
104+
000001e: error: local count must be <= 0xffffffff
105+
out/test/spec/gc/binary.wast:367: assert_malformed passed:
106+
0000030: error: local count must be <= 0xffffffff
107+
out/test/spec/gc/binary.wast:401: assert_malformed passed:
108+
0000013: error: function signature count != function body count
109+
out/test/spec/gc/binary.wast:411: assert_malformed passed:
110+
000000b: error: function signature count != function body count
111+
out/test/spec/gc/binary.wast:420: assert_malformed passed:
112+
0000016: error: function signature count != function body count
113+
out/test/spec/gc/binary.wast:431: assert_malformed passed:
114+
0000015: error: function signature count != function body count
115+
out/test/spec/gc/binary.wast:454: assert_malformed passed:
116+
000000e: error: data segment count does not equal count in DataCount section
117+
out/test/spec/gc/binary.wast:466: assert_malformed passed:
118+
000000e: error: data segment count does not equal count in DataCount section
119+
out/test/spec/gc/binary.wast:478: assert_malformed passed:
120+
0000010: error: Data section missing but DataCount non-zero
121+
out/test/spec/gc/binary.wast:494: assert_malformed passed:
122+
0000024: error: memory.init requires data count section
123+
out/test/spec/gc/binary.wast:517: assert_malformed passed:
124+
000001e: error: data.drop requires data count section
125+
out/test/spec/gc/binary.wast:537: assert_malformed passed:
126+
0000024: error: unexpected opcode: 0xf3
127+
out/test/spec/gc/binary.wast:565: assert_malformed passed:
128+
0000022: error: table elem type must be a reference type
129+
out/test/spec/gc/binary.wast:650: assert_malformed passed:
130+
000000a: error: invalid section size: extends past end
131+
out/test/spec/gc/binary.wast:661: assert_malformed passed:
132+
000000e: error: unfinished section (expected end: 0x11)
133+
out/test/spec/gc/binary.wast:680: assert_malformed passed:
134+
000000e: error: invalid import tag kind: exceptions not allowed
135+
out/test/spec/gc/binary.wast:690: assert_malformed passed:
136+
000000e: error: invalid import tag kind: exceptions not allowed
137+
out/test/spec/gc/binary.wast:701: assert_malformed passed:
138+
000000e: error: malformed import kind: 5
139+
out/test/spec/gc/binary.wast:711: assert_malformed passed:
140+
000000e: error: malformed import kind: 5
141+
out/test/spec/gc/binary.wast:722: assert_malformed passed:
142+
000000e: error: malformed import kind: 128
143+
out/test/spec/gc/binary.wast:732: assert_malformed passed:
144+
000000e: error: malformed import kind: 128
145+
out/test/spec/gc/binary.wast:745: assert_malformed passed:
146+
0000027: error: unable to read u32 leb128: string length
147+
out/test/spec/gc/binary.wast:764: assert_malformed passed:
148+
000002b: error: unfinished section (expected end: 0x40)
149+
out/test/spec/gc/binary.wast:795: assert_malformed passed:
150+
000000b: error: invalid table count 1, only 0 bytes left in section
151+
out/test/spec/gc/binary.wast:805: assert_malformed passed:
152+
000000d: error: tables may not be shared
153+
out/test/spec/gc/binary.wast:814: assert_malformed passed:
154+
000000d: error: tables may not be shared
155+
out/test/spec/gc/binary.wast:824: assert_malformed passed:
156+
000000d: error: malformed table limits flag: 129
157+
out/test/spec/gc/binary.wast:842: assert_malformed passed:
158+
000000b: error: invalid memory count 1, only 0 bytes left in section
159+
out/test/spec/gc/binary.wast:852: assert_malformed passed:
160+
000000c: error: memory may not be shared: threads not allowed
161+
out/test/spec/gc/binary.wast:860: assert_malformed passed:
162+
000000c: error: memory may not be shared: threads not allowed
163+
out/test/spec/gc/binary.wast:869: assert_malformed passed:
164+
000000c: error: malformed memory limits flag: 129
165+
out/test/spec/gc/binary.wast:878: assert_malformed passed:
166+
000000c: error: malformed memory limits flag: 129
167+
out/test/spec/gc/binary.wast:895: assert_malformed passed:
168+
0000010: error: unable to read i32 leb128: global type
169+
out/test/spec/gc/binary.wast:906: assert_malformed passed:
170+
0000010: error: unfinished section (expected end: 0x15)
171+
out/test/spec/gc/binary.wast:929: assert_malformed passed:
172+
000001b: error: unable to read u32 leb128: string length
173+
out/test/spec/gc/binary.wast:950: assert_malformed passed:
174+
000001b: error: unfinished section (expected end: 0x20)
175+
out/test/spec/gc/binary.wast:984: assert_malformed passed:
176+
0000021: error: unable to read u32 leb128: elem segment flags
177+
out/test/spec/gc/binary.wast:1000: assert_malformed passed:
178+
0000024: error: init expression must end with END opcode
179+
out/test/spec/gc/binary.wast:1017: assert_malformed passed:
180+
0000021: error: unfinished section (expected end: 0x27)
181+
out/test/spec/gc/binary.wast:1043: assert_malformed passed:
182+
0000016: error: unable to read u32 leb128: data segment flags
183+
out/test/spec/gc/binary.wast:1056: assert_malformed passed:
184+
0000016: error: unfinished section (expected end: 0x1c)
185+
out/test/spec/gc/binary.wast:1069: assert_malformed passed:
186+
0000015: error: unable to read data: data segment data
187+
out/test/spec/gc/binary.wast:1083: assert_malformed passed:
188+
000001a: error: unfinished section (expected end: 0x1b)
189+
out/test/spec/gc/binary.wast:1114: assert_malformed passed:
190+
0000048: error: function body must end with END opcode
191+
out/test/spec/gc/binary.wast:1161: assert_malformed passed:
192+
0000017: error: multiple Start sections
193+
out/test/spec/gc/binary.wast:1178: assert_malformed passed:
194+
0000014: error: multiple Function sections
195+
out/test/spec/gc/binary.wast:1190: assert_malformed passed:
196+
0000016: error: function signature count != function body count
197+
out/test/spec/gc/binary.wast:1202: assert_malformed passed:
198+
000000d: error: multiple DataCount sections
199+
out/test/spec/gc/binary.wast:1212: assert_malformed passed:
200+
000000d: error: multiple Data sections
201+
out/test/spec/gc/binary.wast:1222: assert_malformed passed:
202+
000000d: error: multiple Global sections
203+
out/test/spec/gc/binary.wast:1232: assert_malformed passed:
204+
000000d: error: multiple Export sections
205+
out/test/spec/gc/binary.wast:1242: assert_malformed passed:
206+
000000d: error: multiple Table sections
207+
out/test/spec/gc/binary.wast:1252: assert_malformed passed:
208+
000000d: error: multiple Elem sections
209+
out/test/spec/gc/binary.wast:1262: assert_malformed passed:
210+
000000d: error: multiple Import sections
211+
out/test/spec/gc/binary.wast:1272: assert_malformed passed:
212+
000000d: error: multiple Type sections
213+
out/test/spec/gc/binary.wast:1282: assert_malformed passed:
214+
000000d: error: multiple Memory sections
215+
out/test/spec/gc/binary.wast:1292: assert_malformed passed:
216+
000000d: error: section Type out of order
217+
out/test/spec/gc/binary.wast:1302: assert_malformed passed:
218+
000000d: error: section Import out of order
219+
out/test/spec/gc/binary.wast:1312: assert_malformed passed:
220+
000000d: error: section Function out of order
221+
out/test/spec/gc/binary.wast:1322: assert_malformed passed:
222+
000000d: error: section Table out of order
223+
out/test/spec/gc/binary.wast:1332: assert_malformed passed:
224+
000000d: error: section Memory out of order
225+
out/test/spec/gc/binary.wast:1342: assert_malformed passed:
226+
000000d: error: section Global out of order
227+
out/test/spec/gc/binary.wast:1352: assert_malformed passed:
228+
0000011: error: section Export out of order
229+
out/test/spec/gc/binary.wast:1363: assert_malformed passed:
230+
0000011: error: section Start out of order
231+
out/test/spec/gc/binary.wast:1374: assert_malformed passed:
232+
000000d: error: section Elem out of order
233+
out/test/spec/gc/binary.wast:1384: assert_malformed passed:
234+
000000d: error: section DataCount out of order
235+
out/test/spec/gc/binary.wast:1394: assert_malformed passed:
236+
000000d: error: section Code out of order
237+
136/136 tests passed.
238+
;;; STDOUT ;;)

0 commit comments

Comments
 (0)