mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 09:04:59 +00:00
Utilities: Add support for loading the WASI module to wasm
This commit is contained in:
parent
7e4e9fdb8f
commit
6d48719069
1 changed files with 66 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <AK/MemoryStream.h>
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/DeprecatedFile.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/MappedFile.h>
|
||||
#include <LibLine/Editor.h>
|
||||
|
@ -15,6 +16,7 @@
|
|||
#include <LibWasm/AbstractMachine/BytecodeInterpreter.h>
|
||||
#include <LibWasm/Printer/Printer.h>
|
||||
#include <LibWasm/Types.h>
|
||||
#include <LibWasm/Wasi.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -278,9 +280,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
bool debug = false;
|
||||
bool export_all_imports = false;
|
||||
bool shell_mode = false;
|
||||
bool wasi = false;
|
||||
DeprecatedString exported_function_to_execute;
|
||||
Vector<u64> values_to_push;
|
||||
Vector<DeprecatedString> modules_to_link_in;
|
||||
Vector<StringView> args_if_wasi;
|
||||
Vector<StringView> wasi_preopened_mappings;
|
||||
|
||||
Core::ArgsParser parser;
|
||||
parser.add_positional_argument(filename, "File name to parse", "file");
|
||||
|
@ -290,6 +295,21 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
parser.add_option(exported_function_to_execute, "Attempt to execute the named exported function from the module (implies -i)", "execute", 'e', "name");
|
||||
parser.add_option(export_all_imports, "Export noop functions corresponding to imports", "export-noop", 0);
|
||||
parser.add_option(shell_mode, "Launch a REPL in the module's context (implies -i)", "shell", 's');
|
||||
parser.add_option(wasi, "Enable WASI", "wasi", 'w');
|
||||
parser.add_option(Core::ArgsParser::Option {
|
||||
.argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
|
||||
.help_string = "Directory mappings to expose via WASI",
|
||||
.long_name = "wasi-map-dir",
|
||||
.short_name = 0,
|
||||
.value_name = "path[:path]",
|
||||
.accept_value = [&](StringView str) {
|
||||
if (!str.is_empty()) {
|
||||
wasi_preopened_mappings.append(str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
});
|
||||
parser.add_option(Core::ArgsParser::Option {
|
||||
.argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
|
||||
.help_string = "Extra modules to link with, use to resolve imports",
|
||||
|
@ -318,6 +338,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
return false;
|
||||
},
|
||||
});
|
||||
parser.add_positional_argument(args_if_wasi, "Arguments to pass to the WASI module", "args", Core::ArgsParser::Required::No);
|
||||
parser.parse(arguments);
|
||||
|
||||
if (shell_mode) {
|
||||
|
@ -351,6 +372,34 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
if (attempt_instantiate) {
|
||||
Wasm::AbstractMachine machine;
|
||||
Optional<Wasm::Wasi::Implementation> wasi_impl;
|
||||
|
||||
if (wasi) {
|
||||
wasi_impl.emplace(Wasm::Wasi::Implementation::Details {
|
||||
.provide_arguments = [&] {
|
||||
Vector<String> strings;
|
||||
for (auto& string : args_if_wasi)
|
||||
strings.append(String::from_utf8(string).release_value_but_fixme_should_propagate_errors());
|
||||
return strings; },
|
||||
.provide_environment = {},
|
||||
.provide_preopened_directories = [&] {
|
||||
Vector<Wasm::Wasi::Implementation::MappedPath> paths;
|
||||
for (auto& string : wasi_preopened_mappings) {
|
||||
auto split_index = string.find(':');
|
||||
if (split_index.has_value()) {
|
||||
LexicalPath host_path { Core::DeprecatedFile::real_path_for(string.substring_view(0, *split_index)) };
|
||||
LexicalPath mapped_path { string.substring_view(*split_index + 1) };
|
||||
paths.append({move(host_path), move(mapped_path)});
|
||||
} else {
|
||||
LexicalPath host_path { Core::DeprecatedFile::real_path_for(string) };
|
||||
LexicalPath mapped_path { string };
|
||||
paths.append({move(host_path), move(mapped_path)});
|
||||
}
|
||||
}
|
||||
return paths; },
|
||||
});
|
||||
}
|
||||
|
||||
Core::EventLoop main_loop;
|
||||
if (debug) {
|
||||
g_line_editor = Line::Editor::construct();
|
||||
|
@ -389,6 +438,23 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
for (auto& instance : linked_instances)
|
||||
linker.link(*instance);
|
||||
|
||||
if (wasi) {
|
||||
HashMap<Wasm::Linker::Name, Wasm::ExternValue> wasi_exports;
|
||||
for (auto& entry : linker.unresolved_imports()) {
|
||||
if (entry.module != "wasi_snapshot_preview1"sv)
|
||||
continue;
|
||||
auto function = wasi_impl->function_by_name(entry.name);
|
||||
if (function.is_error()) {
|
||||
dbgln("wasi function {} not implemented :(", entry.name);
|
||||
continue;
|
||||
}
|
||||
auto address = machine.store().allocate(function.release_value());
|
||||
wasi_exports.set(entry, *address);
|
||||
}
|
||||
|
||||
linker.link(wasi_exports);
|
||||
}
|
||||
|
||||
if (export_all_imports) {
|
||||
HashMap<Wasm::Linker::Name, Wasm::ExternValue> exports;
|
||||
for (auto& entry : linker.unresolved_imports()) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue