-
Notifications
You must be signed in to change notification settings - Fork 701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wasm-interp: Add multi-module support #2009
base: main
Are you sure you want to change the base?
Changes from 10 commits
d53a1e9
b9da00b
ff68a0b
f1d7371
86eb626
daab8ed
d77a735
b2a63ba
307e91c
9be9d33
d4e4833
fbe602b
baa0e5c
523aaa4
18b09f1
ba49f14
50db7e0
ca6aa99
7f0489a
1ed7b45
f7160d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,7 @@ | |
|
||
#include "uvwasi.h" | ||
|
||
#include <cstdio> | ||
#include <cinttypes> | ||
#include <unordered_map> | ||
|
||
|
@@ -652,85 +653,90 @@ std::unordered_map<Instance*, WasiInstance*> wasiInstances; | |
namespace wabt { | ||
namespace interp { | ||
|
||
Result WasiBindImports(const Module::Ptr& module, | ||
RefVec& imports, | ||
Stream* stream, | ||
Stream* trace_stream) { | ||
Store* store = module.store(); | ||
for (auto&& import : module->desc().imports) { | ||
if (import.type.type->kind != ExternKind::Func) { | ||
stream->Writef("wasi error: invalid import type: %s\n", | ||
import.type.name.c_str()); | ||
return Result::Error; | ||
Result WasiRegisterInstance(const Instance::Ptr& instance, | ||
uvwasi_s* uvwasi, | ||
Stream* err_stream, | ||
Stream* trace_stream) { | ||
Store* store = instance.store(); | ||
auto module = store->UnsafeGet<Module>(instance->module()); | ||
auto&& module_desc = module->desc(); | ||
|
||
Memory::Ptr memory; | ||
for (auto&& export_ : module_desc.exports) { | ||
if (export_.type.name == "memory") { | ||
if (export_.type.type->kind != ExternalKind::Memory) { | ||
err_stream->Writef("wasi error: memory export has incorrect type\n"); | ||
return Result::Error; | ||
} | ||
memory = store->UnsafeGet<Memory>(instance->memories()[export_.index]); | ||
break; | ||
} | ||
} | ||
|
||
if (import.type.module != "wasi_snapshot_preview1" && | ||
import.type.module != "wasi_unstable") { | ||
stream->Writef("wasi error: unknown module import: `%s`\n", | ||
import.type.module.c_str()); | ||
return Result::Error; | ||
} | ||
if (!memory) { | ||
err_stream->Writef("wasi error: memory export not found\n"); | ||
return Result::Error; | ||
} | ||
|
||
WasiInstance* wasi = new WasiInstance(instance, uvwasi, std::move(memory).get(), trace_stream); | ||
wasiInstances[instance.get()] = std::move(wasi); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think Maybe just avoid the local and do |
||
|
||
auto func_type = *cast<FuncType>(import.type.type.get()); | ||
auto import_name = StringPrintf("%s.%s", import.type.module.c_str(), | ||
import.type.name.c_str()); | ||
HostFunc::Ptr host_func; | ||
return Result::Ok; | ||
} | ||
|
||
// TODO(sbc): Validate signatures of imports. | ||
#define WASI_FUNC(NAME) \ | ||
if (import.type.name == #NAME) { \ | ||
host_func = HostFunc::New(*store, func_type, NAME); \ | ||
goto found; \ | ||
void WasiUnregisterInstance(const Instance::Ptr& instance) { | ||
WasiInstance* wasi = wasiInstances[instance.get()]; | ||
if (wasi) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might already be deleted. The main file gets a delete before this happens, which might not be cleared, if |
||
wasiInstances.erase(instance.get()); | ||
delete wasi; | ||
} | ||
#include "wasi_api.def" | ||
#undef WASI_FUNC | ||
} | ||
|
||
stream->Writef("unknown wasi API import: `%s`\n", import.type.name.c_str()); | ||
return Result::Error; | ||
found: | ||
imports.push_back(host_func.ref()); | ||
Ref WasiGetImport(const Module::Ptr& module, const ImportDesc& import) { | ||
auto func_type = *cast<FuncType>(import.type.type.get()); | ||
HostFunc::Ptr host_func; | ||
Store* store = module.store(); | ||
|
||
// TODO(sbc): Validate signatures of imports. | ||
#define WASI_FUNC(NAME) \ | ||
if (import.type.name == #NAME) { \ | ||
return HostFunc::New(*store, func_type, NAME).ref(); \ | ||
} | ||
#include "wasi_api.def" | ||
#undef WASI_FUNC | ||
|
||
return Result::Ok; | ||
return Ref::Null; | ||
} | ||
|
||
Result WasiRunStart(const Instance::Ptr& instance, | ||
uvwasi_s* uvwasi, | ||
Stream* err_stream, | ||
Stream* trace_stream) { | ||
static Result FindWasiEntryPoint(const Instance::Ptr& instance, | ||
Stream* err_stream, | ||
Func::Ptr* entry_func) { | ||
Store* store = instance.store(); | ||
auto module = store->UnsafeGet<Module>(instance->module()); | ||
auto&& module_desc = module->desc(); | ||
|
||
Func::Ptr start; | ||
Memory::Ptr memory; | ||
for (auto&& export_ : module_desc.exports) { | ||
if (export_.type.name == "memory") { | ||
if (export_.type.type->kind != ExternalKind::Memory) { | ||
err_stream->Writef("wasi error: memory export has incorrect type\n"); | ||
return Result::Error; | ||
} | ||
memory = store->UnsafeGet<Memory>(instance->memories()[export_.index]); | ||
} | ||
if (export_.type.name == "_start") { | ||
if (export_.type.type->kind != ExternalKind::Func) { | ||
err_stream->Writef("wasi error: _start export is not a function\n"); | ||
return Result::Error; | ||
} | ||
start = store->UnsafeGet<Func>(instance->funcs()[export_.index]); | ||
*entry_func = store->UnsafeGet<Func>(instance->funcs()[export_.index]); | ||
return Result::Ok; | ||
} | ||
if (start && memory) { | ||
break; | ||
} | ||
} | ||
|
||
if (!start) { | ||
err_stream->Writef("wasi error: _start export not found\n"); | ||
return Result::Error; | ||
} | ||
return Result::Error; | ||
} | ||
|
||
if (!memory) { | ||
err_stream->Writef("wasi error: memory export not found\n"); | ||
Result WasiRunStart(const Instance::Ptr& instance, | ||
uvwasi_s* uvwasi, | ||
Stream* err_stream, | ||
Stream* trace_stream) { | ||
Func::Ptr start; | ||
Result found = FindWasiEntryPoint(instance, err_stream, &start); | ||
if (found == Result::Error) { | ||
err_stream->Writef("wasi error: " | ||
"_start export not a function or not found\n"); | ||
return Result::Error; | ||
} | ||
|
||
|
@@ -739,11 +745,8 @@ Result WasiRunStart(const Instance::Ptr& instance, | |
return Result::Error; | ||
} | ||
|
||
// Register memory | ||
WasiInstance wasi(instance, uvwasi, memory.get(), trace_stream); | ||
wasiInstances[instance.get()] = &wasi; | ||
|
||
// Call start ([] -> []) | ||
Store* store = instance.store(); | ||
Values params; | ||
Values results; | ||
Trap::Ptr trap; | ||
|
@@ -753,7 +756,7 @@ Result WasiRunStart(const Instance::Ptr& instance, | |
} | ||
|
||
// Unregister memory | ||
wasiInstances.erase(instance.get()); | ||
UnregisterWasiInstance(instance); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to be renamed I think. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this line be removed now that the registration and unregistration now all seems to be taken care in wasm-interp.cc? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, You might use it elsewhere (in spec-test for example). I did not want to monolith EDIT: also see: |
||
return res; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was for testing and finding a memory-leak culprit. is removed. Thanks for the notice ._.