summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interp/interp.cc24
-rw-r--r--src/interp/interp.h5
-rw-r--r--src/tools/wasm-interp.cc26
3 files changed, 47 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;
};
}
}