Skip to content

Commit f7d23a8

Browse files
ggreifclaude
andcommitted
Validator: thread table limits through OnReturnCallIndirect
`SharedValidator::OnCallIndirect` passes `table_type.limits` to `TypeChecker::OnCallIndirect`, which uses `is_64` to expect i64 vs i32 for the table-index operand. `OnReturnCallIndirect` doesn't, so under table64 plain `call_indirect` with an i64 index validates while the matching `return_call_indirect` rejects it with `expected [i32] but got [i64]`. Fix: mirror the signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 77a95c8 commit f7d23a8

4 files changed

Lines changed: 24 additions & 5 deletions

File tree

include/wabt/type-checker.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ class TypeChecker {
106106
Result OnReturnCall(const TypeVector& param_types,
107107
const TypeVector& result_types);
108108
Result OnReturnCallIndirect(const TypeVector& param_types,
109-
const TypeVector& result_types);
109+
const TypeVector& result_types,
110+
const Limits& table_limits);
110111
Result OnReturnCallRef(Type type,
111112
const TypeVector& param_types,
112113
const TypeVector& result_types);

src/shared-validator.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,8 +1225,8 @@ Result SharedValidator::OnReturnCallIndirect(const Location& loc,
12251225
"type mismatch: return_call_indirect must reference "
12261226
"table of funcref type");
12271227
}
1228-
result |=
1229-
typechecker_.OnReturnCallIndirect(func_type.params, func_type.results);
1228+
result |= typechecker_.OnReturnCallIndirect(
1229+
func_type.params, func_type.results, table_type.limits);
12301230
IgnoreLocalRefs();
12311231
return result;
12321232
}

src/type-checker.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,10 @@ Result TypeChecker::OnReturnCall(const TypeVector& param_types,
722722
}
723723

724724
Result TypeChecker::OnReturnCallIndirect(const TypeVector& param_types,
725-
const TypeVector& result_types) {
726-
Result result = PopAndCheck1Type(Type::I32, "return_call_indirect");
725+
const TypeVector& result_types,
726+
const Limits& table_limits) {
727+
Result result = PopAndCheck1Type(table_limits.is_64 ? Type::I64 : Type::I32,
728+
"return_call_indirect");
727729

728730
result |= PopAndCheckSignature(param_types, "return_call_indirect");
729731
result |= PopAndCheckReturnCall(result_types, "return_call_indirect");
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
;;; TOOL: wat2wasm
2+
;;; ARGS: --enable-tail-call --enable-memory64
3+
;;; ERROR: 1
4+
(module
5+
(type $t (func))
6+
(func $f)
7+
(table i64 1 1 funcref)
8+
(elem (i64.const 0) $f)
9+
(func
10+
i32.const 0
11+
return_call_indirect (type $t)))
12+
(;; STDERR ;;;
13+
out/test/typecheck/bad-returncallindirect-table64-type-mismatch.txt:11:5: error: type mismatch in return_call_indirect, expected [i64] but got [i32]
14+
return_call_indirect (type $t)))
15+
^^^^^^^^^^^^^^^^^^^^
16+
;;; STDERR ;;)

0 commit comments

Comments
 (0)