diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-06-09 16:43:47 +0430 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-06-09 23:05:32 +0430 |
commit | ccc79149d48f42e8090bffc5aad24f7cbf3fff81 (patch) | |
tree | f36e90f5dde9606679f030cc2e0f897cee215958 /Userland/Utilities | |
parent | 2b789adc16e5d9a5d4e73ff7f78fbf73fbc4ba11 (diff) | |
download | serenity-ccc79149d48f42e8090bffc5aad24f7cbf3fff81.zip |
wasm: Add a help command to the shell mode and start it on --shell
Diffstat (limited to 'Userland/Utilities')
-rw-r--r-- | Userland/Utilities/wasm.cpp | 71 |
1 files changed, 56 insertions, 15 deletions
diff --git a/Userland/Utilities/wasm.cpp b/Userland/Utilities/wasm.cpp index 1e7ef92fa9..d8179ee0eb 100644 --- a/Userland/Utilities/wasm.cpp +++ b/Userland/Utilities/wasm.cpp @@ -91,6 +91,30 @@ static bool pre_interpret_hook(Wasm::Configuration& config, Wasm::InstructionPoi if (args.is_empty()) continue; auto& cmd = args[0]; + if (cmd.is_one_of("h", "help")) { + warnln("Wasm shell commands"); + warnln("Toplevel:"); + warnln("- [s]tep Run one instruction"); + warnln("- next Alias for step"); + warnln("- [c]ontinue Execute until a trap or the program exit point"); + warnln("- [p]rint <args...> Print various things (see section on print)"); + warnln("- call <fn> <args...> Call the function <fn> with the given arguments"); + warnln("- set <args...> Set shell option (see section on settings)"); + warnln("- unset <args...> Unset shell option (see section on settings)"); + warnln("- [h]elp Print this help"); + warnln(); + warnln("Print:"); + warnln("- print [s]tack Print the contents of the stack, including frames and labels"); + warnln("- print [[m]em]ory <index> Print the contents of the memory identified by <index>"); + warnln("- print [[i]nstr]uction Print the current instruction"); + warnln("- print [[f]unc]tion <index> Print the function identified by <index>"); + warnln(); + warnln("Settings:"); + warnln("- set print stack Make the shell print the stack on every instruction executed"); + warnln("- set print [instr]uction Make the shell print the instruction that will be executed next"); + warnln(); + continue; + } if (cmd.is_one_of("s", "step", "next")) { return true; } @@ -266,6 +290,7 @@ int main(int argc, char* argv[]) bool attempt_instantiate = false; bool debug = false; bool export_all_imports = false; + bool shell_mode = false; String exported_function_to_execute; Vector<u64> values_to_push; Vector<String> modules_to_link_in; @@ -277,6 +302,7 @@ int main(int argc, char* argv[]) parser.add_option(attempt_instantiate, "Attempt to instantiate the module", "instantiate", 'i'); 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(Core::ArgsParser::Option { .requires_argument = true, .help_string = "Extra modules to link with, use to resolve imports", @@ -307,12 +333,17 @@ int main(int argc, char* argv[]) }); parser.parse(argc, argv); - if (debug && exported_function_to_execute.is_empty()) { + if (shell_mode) { + debug = true; + attempt_instantiate = true; + } + + if (!shell_mode && debug && exported_function_to_execute.is_empty()) { warnln("Debug what? (pass -e fn)"); return 1; } - if (debug) { + if (debug || shell_mode) { old_signal = signal(SIGINT, sigint_handler); } @@ -337,6 +368,7 @@ int main(int argc, char* argv[]) g_interpreter.pre_interpret_hook = pre_interpret_hook; g_interpreter.post_interpret_hook = post_interpret_hook; } + // First, resolve the linked modules NonnullOwnPtrVector<Wasm::ModuleInstance> linked_instances; Vector<Wasm::Module> linked_modules; @@ -414,6 +446,21 @@ int main(int argc, char* argv[]) } auto module_instance = result.release_value(); + auto launch_repl = [&] { + Wasm::Configuration config { machine.store() }; + Wasm::Expression expression { {} }; + config.set_frame(Wasm::Frame { + *module_instance, + Vector<Wasm::Value> {}, + expression, + 0, + }); + Wasm::Instruction instr { Wasm::Instructions::nop }; + Wasm::InstructionPointer ip { 0 }; + g_continue = false; + pre_interpret_hook(config, ip, instr); + }; + auto stream = Core::OutputFileStream::standard_output(); auto print_func = [&](auto const& address) { Wasm::FunctionInstance* fn = machine.store().get(address); @@ -438,6 +485,11 @@ int main(int argc, char* argv[]) } } + if (shell_mode) { + launch_repl(); + return 0; + } + if (!exported_function_to_execute.is_empty()) { Optional<Wasm::FunctionAddress> run_address; Vector<Wasm::Value> values; @@ -475,19 +527,8 @@ int main(int argc, char* argv[]) auto result = machine.invoke(g_interpreter, run_address.value(), move(values)); - if (debug) { - Wasm::Configuration config { machine.store() }; - config.set_frame(Wasm::Frame { - *module_instance, - Vector<Wasm::Value> {}, - instance->get<Wasm::WasmFunction>().code().body(), - 1, - }); - Wasm::Instruction instr { Wasm::Instructions::nop }; - Wasm::InstructionPointer ip { 0 }; - g_continue = false; - pre_interpret_hook(config, ip, instr); - } + if (debug) + launch_repl(); if (result.is_trap()) warnln("Execution trapped!"); |