diff options
author | Alon Zakai <azakai@google.com> | 2023-10-24 13:45:09 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-24 13:45:09 -0700 |
commit | ba04e395508fc3414b952287d7e918d20361087e (patch) | |
tree | 2ea9258dbcf6340cc92a3cb342c63652c85beec3 | |
parent | 92c8a4682367170485295da6744b3a59fbb8d3ac (diff) | |
download | binaryen-ba04e395508fc3414b952287d7e918d20361087e.tar.gz binaryen-ba04e395508fc3414b952287d7e918d20361087e.tar.bz2 binaryen-ba04e395508fc3414b952287d7e918d20361087e.zip |
Fix handling of exported imported functions (#6044)
Two trivial places did not handle that case, and assumed an exported function
was actually defined (and not imported).
Also add some const stuff to fix compilation after this change.
This was discovered by #6026
-rw-r--r-- | src/shell-interface.h | 2 | ||||
-rw-r--r-- | src/tools/execution-results.h | 2 | ||||
-rw-r--r-- | src/tools/wasm-ctor-eval.cpp | 11 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 8 | ||||
-rw-r--r-- | test/lit/ctor-eval/exported-import.wast | 14 | ||||
-rw-r--r-- | test/lit/exec/exported-import.wast | 14 |
6 files changed, 47 insertions, 4 deletions
diff --git a/src/shell-interface.h b/src/shell-interface.h index e27f5c690..1efa31f79 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -133,7 +133,7 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { }); } - Literals callImport(Function* import, Literals& arguments) override { + Literals callImport(Function* import, const Literals& arguments) override { if (import->module == SPECTEST && import->base.startsWith(PRINT)) { for (auto argument : arguments) { std::cout << argument << " : " << argument.type << '\n'; diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h index 4ef087cec..0cd40959e 100644 --- a/src/tools/execution-results.h +++ b/src/tools/execution-results.h @@ -39,7 +39,7 @@ struct LoggingExternalInterface : public ShellExternalInterface { LoggingExternalInterface(Loggings& loggings) : loggings(loggings) {} - Literals callImport(Function* import, Literals& arguments) override { + Literals callImport(Function* import, const Literals& arguments) override { if (import->module == "fuzzing-support") { std::cout << "[LoggingExternalInterface logging"; loggings.push_back(Literal()); // buffer with a None between calls diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 1b60a9222..eb2a4eb5d 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -227,7 +227,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { }); } - Literals callImport(Function* import, Literals& arguments) override { + Literals callImport(Function* import, const Literals& arguments) override { Name WASI("wasi_snapshot_preview1"); if (ignoreExternalInput) { @@ -1022,6 +1022,15 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance, Name exportName) { auto& wasm = instance.wasm; auto* func = wasm.getFunction(funcName); + if (func->imported()) { + // We cannot evaluate an import. + if (!quiet) { + std::cout << " ...stopping since could not eval: call import: " + << func->module.toString() << "." << func->base.toString() + << '\n'; + } + return EvalCtorOutcome(); + } // We don't know the values of parameters, so give up if there are any, unless // we are ignoring them. diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 3b451a787..8eb52e634 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -2382,7 +2382,8 @@ public: virtual ~ExternalInterface() = default; virtual void init(Module& wasm, SubType& instance) {} virtual void importGlobals(GlobalValueSet& globals, Module& wasm) = 0; - virtual Literals callImport(Function* import, Literals& arguments) = 0; + virtual Literals callImport(Function* import, + const Literals& arguments) = 0; virtual Literals callTable(Name tableName, Index index, HeapType sig, @@ -3907,6 +3908,11 @@ public: // Call a function, starting an invocation. Literals callFunction(Name name, const Literals& arguments) { + auto* func = wasm.getFunction(name); + if (func->imported()) { + return externalInterface->callImport(func, arguments); + } + // if the last call ended in a jump up the stack, it might have left stuff // for us to clean up here callDepth = 0; diff --git a/test/lit/ctor-eval/exported-import.wast b/test/lit/ctor-eval/exported-import.wast new file mode 100644 index 000000000..3ec2780bc --- /dev/null +++ b/test/lit/ctor-eval/exported-import.wast @@ -0,0 +1,14 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-ctor-eval %s --ctors=export --kept-exports=export --quiet -all -S -o - | filecheck %s + +;; We cannot eval an exported import, and should exit with a message about +;; that rather than an error. + +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (import "spectest" "print" (func $import (type $0))) + (import "spectest" "print" (func $import)) + ;; CHECK: (export "export" (func $import)) + (export "export" (func $import)) +) diff --git a/test/lit/exec/exported-import.wast b/test/lit/exec/exported-import.wast new file mode 100644 index 000000000..5264e9e00 --- /dev/null +++ b/test/lit/exec/exported-import.wast @@ -0,0 +1,14 @@ +;; RUN: wasm-opt %s --fuzz-exec-before -q -o /dev/null 2>&1 | filecheck %s + +;; Execute an import that is immediately exported. We should not error here, but +;; no other output is expected (as the import does nothing and is ignored). + +(module + (import "spectest" "nothing" (func $import)) + (export "__wasm_call_ctors" (func $import)) +) + +;; Note this file does not use automatic updating as that only works for +;; defined functions at the moment, and this module has none of those. + +;; CHECK: [fuzz-exec] calling __wasm_call_ctors |