@@ -799,7 +799,7 @@ void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
799
799
shouldBeTrue (!!table, curr, " call-indirect table must exist" );
800
800
shouldBeTrue (table->type .isFunction (),
801
801
curr,
802
- " call-indirect table type must be a funcref ." );
802
+ " call-indirect table must be of function type ." );
803
803
}
804
804
805
805
validateCallParamsAndResult (curr, curr->sig );
@@ -2861,24 +2861,30 @@ static void validateTables(Module& module, ValidationInfo& info) {
2861
2861
" table" ,
2862
2862
" Non-nullable reference types are not yet supported for tables" );
2863
2863
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)" );
2868
2869
}
2869
2870
if (!module.features .hasTypedFunctionReferences ()) {
2870
2871
info.shouldBeTrue (table->type == Type::funcref ||
2871
2872
table->type == Type::externref,
2872
2873
" 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)" );
2874
2876
}
2875
2877
}
2876
2878
2877
2879
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." );
2882
2888
info.shouldBeTrue (
2883
2889
segment->type .isNullable (),
2884
2890
" elem" ,
@@ -2922,10 +2928,17 @@ static void validateTables(Module& module, ValidationInfo& info) {
2922
2928
// Avoid double checking items
2923
2929
if (module.features .hasReferenceTypes ()) {
2924
2930
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
+ }
2929
2942
info.shouldBeSubType (expr->type ,
2930
2943
segment->type ,
2931
2944
expr,
0 commit comments