Skip to content

Commit 3961dfb

Browse files
committed
add global.get to as a valid elem expression
1 parent 046bebf commit 3961dfb

5 files changed

+36
-18
lines changed

src/wasm/wasm-validator.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
799799
shouldBeTrue(!!table, curr, "call-indirect table must exist");
800800
shouldBeTrue(table->type.isFunction(),
801801
curr,
802-
"call-indirect table type must be a funcref.");
802+
"call-indirect table must be of function type.");
803803
}
804804

805805
validateCallParamsAndResult(curr, curr->sig);
@@ -2861,24 +2861,30 @@ static void validateTables(Module& module, ValidationInfo& info) {
28612861
"table",
28622862
"Non-nullable reference types are not yet supported for tables");
28632863
if (!module.features.hasGC()) {
2864-
info.shouldBeTrue(
2865-
table->type.isFunction() || table->type == Type::externref,
2866-
"table",
2867-
"Only function reference types or externref are valid for table type");
2864+
info.shouldBeTrue(table->type.isFunction() ||
2865+
table->type == Type::externref,
2866+
"table",
2867+
"Only function reference types or externref are valid "
2868+
"for table type (when GC is disabled)");
28682869
}
28692870
if (!module.features.hasTypedFunctionReferences()) {
28702871
info.shouldBeTrue(table->type == Type::funcref ||
28712872
table->type == Type::externref,
28722873
"table",
2873-
"Only funcref and externref are valid for table type");
2874+
"Only funcref and externref are valid for table type "
2875+
"(when typed-function references are disabled)");
28742876
}
28752877
}
28762878

28772879
for (auto& segment : module.elementSegments) {
2878-
info.shouldBeUnequal(segment->type,
2879-
Type(Type::externref),
2880-
"elem",
2881-
"element segment type cannot be externref");
2880+
// Since element segment items need to be constant expressions, that leaves
2881+
// us with ref.null, ref.func and global.get. The GC proposal adds rtt.canon
2882+
// and rtt.sub to the list, but Binaryen doesn't consider RTTs as reference-
2883+
// types yet. As a result, the only possible type for element segments will
2884+
// be function references.
2885+
info.shouldBeTrue(segment->type.isFunction(),
2886+
"elem",
2887+
"element segment type must be of function type.");
28822888
info.shouldBeTrue(
28832889
segment->type.isNullable(),
28842890
"elem",
@@ -2922,10 +2928,17 @@ static void validateTables(Module& module, ValidationInfo& info) {
29222928
// Avoid double checking items
29232929
if (module.features.hasReferenceTypes()) {
29242930
for (auto* expr : segment->data) {
2925-
info.shouldBeTrue(
2926-
expr->is<RefFunc>() || expr->is<RefNull>(),
2927-
expr,
2928-
"element segment items must be either ref.func or ref.null func");
2931+
if (auto* globalExpr = expr->dynCast<GlobalGet>()) {
2932+
auto* global = module.getGlobal(globalExpr->name);
2933+
info.shouldBeFalse(
2934+
global->mutable_, expr, "expected a constant expression");
2935+
} else {
2936+
info.shouldBeTrue(expr->is<RefFunc>() || expr->is<RefNull>() ||
2937+
expr->is<GlobalGet>(),
2938+
expr,
2939+
"element segment items must be one of global.get, "
2940+
"ref.func, ref.null func");
2941+
}
29292942
info.shouldBeSubType(expr->type,
29302943
segment->type,
29312944
expr,

test/multi-table.wast

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
(module
22
(type $none_=>_none (func))
3+
(type $A (struct))
4+
(global $g1 (ref null $none_=>_none) (ref.func $f))
35
(import "a" "b" (table $t1 1 10 funcref))
46
(table $t2 3 3 funcref)
57
(table $t3 4 4 funcref)
@@ -17,7 +19,7 @@
1719

1820
(elem $passive-1 func $f $g)
1921
(elem $passive-2 funcref (item ref.func $f) (item (ref.func $g)) (ref.null func))
20-
(elem $passive-3 (ref null $none_=>_none) (item ref.func $f) (item (ref.func $g)) (ref.null $none_=>_none))
22+
(elem $passive-3 (ref null $none_=>_none) (item ref.func $f) (item (ref.func $g)) (ref.null $none_=>_none) (global.get $g1))
2123
(elem $empty func)
2224
(elem $declarative declare func $h)
2325

test/multi-table.wast.from-wast

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
(table $textern 0 externref)
1212
(elem $passive-1 func $f $g)
1313
(elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null func))
14-
(elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null $none_=>_none))
14+
(elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null $none_=>_none) (global.get $g1))
1515
(elem declare func $h)
16+
(global $g1 (ref null $none_=>_none) (ref.func $f))
1617
(func $f
1718
(drop
1819
(ref.func $h)

test/multi-table.wast.fromBinary

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
(table $textern 0 externref)
1212
(elem $passive-1 func $f $g)
1313
(elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null func))
14-
(elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null $none_=>_none))
14+
(elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null $none_=>_none) (global.get $g1))
1515
(elem declare func $h)
16+
(global $g1 (ref null $none_=>_none) (ref.func $f))
1617
(func $f
1718
(drop
1819
(ref.func $h)

test/multi-table.wast.fromBinary.noDebugInfo

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
(table $2 0 externref)
1212
(elem func $0 $1)
1313
(elem funcref (ref.func $0) (ref.func $1) (ref.null func))
14-
(elem (ref null $none_=>_none) (ref.func $0) (ref.func $1) (ref.null $none_=>_none))
14+
(elem (ref null $none_=>_none) (ref.func $0) (ref.func $1) (ref.null $none_=>_none) (global.get $global$0))
1515
(elem declare func $2)
16+
(global $global$0 (ref null $none_=>_none) (ref.func $0))
1617
(func $0
1718
(drop
1819
(ref.func $2)

0 commit comments

Comments
 (0)