Skip to content

Commit 0f06b26

Browse files
Add type validations for function imports (#8478)
Validates that the exported function is a subtype of the import declaration. Part of #8261. Example error: ```wast (module $A (func $f (export "f") (param i32) (result i32) (local.get 0) ) ) (register "A" $A) (module $B (func (import "A" "f") (result i32)) ) ;; [trap Imported function A.f with type (func (param i32) (result i32)) isn't compatible with import declaration with type (modulo rec groups): (func (result i32))] ```
1 parent bb290e7 commit 0f06b26

2 files changed

Lines changed: 16 additions & 6 deletions

File tree

scripts/test/shared.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ def get_tests(test_dir, extensions=[], recursive=False):
423423
'if.wast', # Requires more precise unreachable validation
424424
'imports.wast', # Requires fixing handling of mutation to imported globals
425425
'proposals/threads/imports.wast', # Missing memory type validation on instantiation
426-
'linking.wast', # Missing function type validation on instantiation
426+
'linking.wast', # Missing global type validation on instantiation
427427
'proposals/threads/memory.wast', # Missing memory type validation on instantiation
428428
'annotations.wast', # String annotations IDs should be allowed
429429
'instance.wast', # Requires support for table default elements
@@ -445,8 +445,6 @@ def get_tests(test_dir, extensions=[], recursive=False):
445445
'ref_cast.wast', # Requires host references to not be externalized i31refs
446446
'ref_test.wast', # Requires host references to not be externalized i31refs
447447
'struct.wast', # Fails to roundtrip unnamed types e.g. `(ref 0)`
448-
'type-rec.wast', # Missing function type validation on instantiation
449-
'type-subtyping.wast', # ShellExternalInterface::callTable does not handle subtyping
450448
'memory64.wast', # Requires validations on the max memory size
451449
'imports3.wast', # Requires better checking of exports from the special "spectest" module
452450
'relaxed_dot_product.wast', # i16x8.relaxed_dot_i8x16_i7x16_s instruction not supported

src/wasm-interpreter.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3510,9 +3510,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
35103510
if (!MemoryUtils::isSubType(exportedMemory, **memory)) {
35113511
trap("Imported memory isn't compatible.");
35123512
}
3513-
}
3514-
3515-
if (auto** tableDecl = std::get_if<Table*>(&import)) {
3513+
} else if (auto** tableDecl = std::get_if<Table*>(&import)) {
35163514
auto* importedTable = importResolver->getTableOrNull(
35173515
importable->importNames(), **tableDecl);
35183516
if (!importedTable) {
@@ -3528,7 +3526,21 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
35283526
<< " isn't compatible with import declaration: " << **tableDecl)
35293527
.str());
35303528
}
3529+
} else if (auto** function = std::get_if<Function*>(&import)) {
3530+
auto exportedFunc = getFunction((*function)->name);
3531+
if (!Type::isSubType(exportedFunc.type, (*function)->type)) {
3532+
trap((std::stringstream()
3533+
<< "Imported function " << importable->importNames()
3534+
<< " with type "
3535+
<< exportedFunc.type.getHeapType().getSignature().toString()
3536+
<< " isn't compatible with import declaration with type "
3537+
"(modulo rec groups): "
3538+
<< (*function)->type.getHeapType().getSignature().toString())
3539+
.str());
3540+
}
35313541
}
3542+
3543+
// TODO: remaining cases e.g. globals and tags.
35323544
});
35333545
}
35343546

0 commit comments

Comments
 (0)