From c392a0cf7ffbad07c10021b9a3e97f5239b40c55 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Fri, 4 Jun 2021 03:27:51 +0430 Subject: LibWasm: Implement the br.table instruction Unlike its name, this instruction has nothing to do with tables, it's just a very simple switch-case instruction. --- .../Libraries/LibWasm/AbstractMachine/Configuration.cpp | 3 +++ .../Libraries/LibWasm/AbstractMachine/Interpreter.cpp | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'Userland/Libraries/LibWasm') diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp index fcfd14ddee..ac93f77507 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp @@ -66,6 +66,9 @@ Result Configuration::execute(Interpreter& interpreter) if (interpreter.did_trap()) return Trap {}; + if (stack().size() <= frame().arity() + 1) + return Trap {}; + Vector results; results.ensure_capacity(frame().arity()); for (size_t i = 0; i < frame().arity(); ++i) diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp b/Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp index afebe0ef97..6e625c7aa8 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp @@ -122,6 +122,7 @@ void BytecodeInterpreter::call_address(Configuration& configuration, FunctionAdd const FunctionType* type { nullptr }; instance->visit([&](const auto& function) { type = &function.type(); }); TRAP_IF_NOT(type); + TRAP_IF_NOT(configuration.stack().entries().size() > type->parameters().size()); Vector args; args.ensure_capacity(type->parameters().size()); auto span = configuration.stack().entries().span().slice_from_end(type->parameters().size()); @@ -506,8 +507,18 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi return; return branch_to_label(configuration, instruction.arguments().get()); } - case Instructions::br_table.value(): - goto unimplemented; + case Instructions::br_table.value(): { + auto& arguments = instruction.arguments().get(); + auto entry = configuration.stack().pop(); + TRAP_IF_NOT(entry.has()); + auto maybe_i = entry.get().to(); + TRAP_IF_NOT(maybe_i.has_value()); + TRAP_IF_NOT(maybe_i.value() >= 0); + size_t i = *maybe_i; + if (i < arguments.labels.size()) + return branch_to_label(configuration, arguments.labels[i]); + return branch_to_label(configuration, arguments.default_); + } case Instructions::call.value(): { auto index = instruction.arguments().get(); TRAP_IF_NOT(index.value() < configuration.frame().module().functions().size()); -- cgit v1.2.3