Skip to content

Commit c392a0c

Browse files
committed
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.
1 parent 9db418e commit c392a0c

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ Result Configuration::execute(Interpreter& interpreter)
6666
if (interpreter.did_trap())
6767
return Trap {};
6868

69+
if (stack().size() <= frame().arity() + 1)
70+
return Trap {};
71+
6972
Vector<Value> results;
7073
results.ensure_capacity(frame().arity());
7174
for (size_t i = 0; i < frame().arity(); ++i)

Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ void BytecodeInterpreter::call_address(Configuration& configuration, FunctionAdd
122122
const FunctionType* type { nullptr };
123123
instance->visit([&](const auto& function) { type = &function.type(); });
124124
TRAP_IF_NOT(type);
125+
TRAP_IF_NOT(configuration.stack().entries().size() > type->parameters().size());
125126
Vector<Value> args;
126127
args.ensure_capacity(type->parameters().size());
127128
auto span = configuration.stack().entries().span().slice_from_end(type->parameters().size());
@@ -506,8 +507,18 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi
506507
return;
507508
return branch_to_label(configuration, instruction.arguments().get<LabelIndex>());
508509
}
509-
case Instructions::br_table.value():
510-
goto unimplemented;
510+
case Instructions::br_table.value(): {
511+
auto& arguments = instruction.arguments().get<Instruction::TableBranchArgs>();
512+
auto entry = configuration.stack().pop();
513+
TRAP_IF_NOT(entry.has<Value>());
514+
auto maybe_i = entry.get<Value>().to<i32>();
515+
TRAP_IF_NOT(maybe_i.has_value());
516+
TRAP_IF_NOT(maybe_i.value() >= 0);
517+
size_t i = *maybe_i;
518+
if (i < arguments.labels.size())
519+
return branch_to_label(configuration, arguments.labels[i]);
520+
return branch_to_label(configuration, arguments.default_);
521+
}
511522
case Instructions::call.value(): {
512523
auto index = instruction.arguments().get<FunctionIndex>();
513524
TRAP_IF_NOT(index.value() < configuration.frame().module().functions().size());

0 commit comments

Comments
 (0)