summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interp/interp.cc24
-rw-r--r--src/interp/interp.h5
-rw-r--r--src/tools/wasm-interp.cc26
-rw-r--r--test/help/wasm-interp.txt1
-rw-r--r--test/interp/call-dummy-import.txt20
5 files changed, 68 insertions, 8 deletions
diff --git a/src/interp/interp.cc b/src/interp/interp.cc
index ca8ff59d..3d5ee30e 100644
--- a/src/interp/interp.cc
+++ b/src/interp/interp.cc
@@ -144,11 +144,27 @@ Module* Environment::FindModule(string_view name) {
}
Module* Environment::FindRegisteredModule(string_view name) {
- auto iter = registered_module_bindings_.find(name.to_string());
- if (iter == registered_module_bindings_.end()) {
- return nullptr;
+ bool retry = false;
+ while (true) {
+ auto iter = registered_module_bindings_.find(name.to_string());
+ if (iter != registered_module_bindings_.end()) {
+ return modules_[iter->second.index].get();
+ }
+
+ if (retry) {
+ // If you return true from on_unknown_module, you must add the module
+ // using AppendHostModule().
+ assert(false);
+ break;
+ }
+
+ if (on_unknown_module && on_unknown_module(this, name)) {
+ retry = true;
+ continue;
+ }
+ break;
}
- return modules_[iter->second.index].get();
+ return nullptr;
}
Thread::Options::Options(uint32_t value_stack_size, uint32_t call_stack_size)
diff --git a/src/interp/interp.h b/src/interp/interp.h
index 1a98ccfb..1230b927 100644
--- a/src/interp/interp.h
+++ b/src/interp/interp.h
@@ -537,6 +537,11 @@ class Environment {
void Disassemble(Stream* stream, IstreamOffset from, IstreamOffset to);
void DisassembleModule(Stream* stream, Module*);
+ // Called when a module name isn't found in registered_module_bindings_. If
+ // you want to provide a module with this name, call AppendHostModule() with
+ // this name and return true.
+ std::function<bool(Environment*, string_view name)> on_unknown_module;
+
private:
friend class Thread;
diff --git a/src/tools/wasm-interp.cc b/src/tools/wasm-interp.cc
index cb5808d8..c08a4382 100644
--- a/src/tools/wasm-interp.cc
+++ b/src/tools/wasm-interp.cc
@@ -46,6 +46,7 @@ static Thread::Options s_thread_options;
static Stream* s_trace_stream;
static bool s_run_all_exports;
static bool s_host_print;
+static bool s_dummy_import_func;
static Features s_features;
static std::unique_ptr<FileStream> s_log_stream;
@@ -106,6 +107,11 @@ static void ParseOptions(int argc, char** argv) {
"Include an importable function named \"host.print\" for "
"printing to stdout",
[]() { s_host_print = true; });
+ parser.AddOption(
+ "dummy-import-func",
+ "Provide a dummy implementation of all imported functions. The function "
+ "will log the call and return an appropriate zero value.",
+ []() { s_dummy_import_func = true; });
parser.AddArgument("filename", OptionParser::ArgumentCount::One,
[](const char* argument) { s_infile = argument; });
@@ -169,7 +175,7 @@ static interp::Result PrintCallback(const HostFunc* func,
static void InitEnvironment(Environment* env) {
if (s_host_print) {
- HostModule* host_module = env->AppendHostModule("host");
+ auto* host_module = env->AppendHostModule("host");
host_module->on_unknown_func_export =
[](Environment* env, HostModule* host_module, string_view name,
Index sig_index) -> Index {
@@ -177,9 +183,21 @@ static void InitEnvironment(Environment* env) {
return kInvalidIndex;
}
- std::pair<HostFunc*, Index> pair =
- host_module->AppendFuncExport(name, sig_index, PrintCallback);
- return pair.second;
+ return host_module->AppendFuncExport(name, sig_index, PrintCallback)
+ .second;
+ };
+ }
+
+ if (s_dummy_import_func) {
+ env->on_unknown_module = [](Environment* env, string_view name) {
+ auto* host_module = env->AppendHostModule(name);
+ host_module->on_unknown_func_export =
+ [](Environment* env, HostModule* host_module, string_view name,
+ Index sig_index) -> Index {
+ return host_module->AppendFuncExport(name, sig_index, PrintCallback)
+ .second;
+ };
+ return true;
};
}
}
diff --git a/test/help/wasm-interp.txt b/test/help/wasm-interp.txt
index 05264173..9c84f15c 100644
--- a/test/help/wasm-interp.txt
+++ b/test/help/wasm-interp.txt
@@ -39,4 +39,5 @@ options:
-t, --trace Trace execution
--run-all-exports Run all the exported functions, in order. Useful for testing
--host-print Include an importable function named "host.print" for printing to stdout
+ --dummy-import-func Provide a dummy implementation of all imported functions. The function will log the call and return an appropriate zero value.
;;; STDOUT ;;)
diff --git a/test/interp/call-dummy-import.txt b/test/interp/call-dummy-import.txt
new file mode 100644
index 00000000..0ec46162
--- /dev/null
+++ b/test/interp/call-dummy-import.txt
@@ -0,0 +1,20 @@
+;;; TOOL: run-interp
+;;; ARGS: --dummy-import-func
+(module
+ (import "foo" "bar" (func $bar (param i32 f32) (result i32)))
+ (import "baz" "quux" (func $quux (param f64) (result i64)))
+
+ (func (export "f1") (result i32)
+ i32.const 1
+ f32.const 2
+ call $bar)
+
+ (func (export "f2") (result i64)
+ f64.const 3
+ call $quux))
+(;; STDOUT ;;;
+called host foo.bar(i32:1, f32:2.000000) => i32:0
+f1() => i32:0
+called host baz.quux(f64:3.000000) => i64:0
+f2() => i64:0
+;;; STDOUT ;;)