mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:47:44 +00:00
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.
This commit is contained in:
parent
9db418e1fb
commit
c392a0cf7f
2 changed files with 16 additions and 2 deletions
|
@ -66,6 +66,9 @@ Result Configuration::execute(Interpreter& interpreter)
|
||||||
if (interpreter.did_trap())
|
if (interpreter.did_trap())
|
||||||
return Trap {};
|
return Trap {};
|
||||||
|
|
||||||
|
if (stack().size() <= frame().arity() + 1)
|
||||||
|
return Trap {};
|
||||||
|
|
||||||
Vector<Value> results;
|
Vector<Value> results;
|
||||||
results.ensure_capacity(frame().arity());
|
results.ensure_capacity(frame().arity());
|
||||||
for (size_t i = 0; i < frame().arity(); ++i)
|
for (size_t i = 0; i < frame().arity(); ++i)
|
||||||
|
|
|
@ -122,6 +122,7 @@ void BytecodeInterpreter::call_address(Configuration& configuration, FunctionAdd
|
||||||
const FunctionType* type { nullptr };
|
const FunctionType* type { nullptr };
|
||||||
instance->visit([&](const auto& function) { type = &function.type(); });
|
instance->visit([&](const auto& function) { type = &function.type(); });
|
||||||
TRAP_IF_NOT(type);
|
TRAP_IF_NOT(type);
|
||||||
|
TRAP_IF_NOT(configuration.stack().entries().size() > type->parameters().size());
|
||||||
Vector<Value> args;
|
Vector<Value> args;
|
||||||
args.ensure_capacity(type->parameters().size());
|
args.ensure_capacity(type->parameters().size());
|
||||||
auto span = configuration.stack().entries().span().slice_from_end(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;
|
||||||
return branch_to_label(configuration, instruction.arguments().get<LabelIndex>());
|
return branch_to_label(configuration, instruction.arguments().get<LabelIndex>());
|
||||||
}
|
}
|
||||||
case Instructions::br_table.value():
|
case Instructions::br_table.value(): {
|
||||||
goto unimplemented;
|
auto& arguments = instruction.arguments().get<Instruction::TableBranchArgs>();
|
||||||
|
auto entry = configuration.stack().pop();
|
||||||
|
TRAP_IF_NOT(entry.has<Value>());
|
||||||
|
auto maybe_i = entry.get<Value>().to<i32>();
|
||||||
|
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(): {
|
case Instructions::call.value(): {
|
||||||
auto index = instruction.arguments().get<FunctionIndex>();
|
auto index = instruction.arguments().get<FunctionIndex>();
|
||||||
TRAP_IF_NOT(index.value() < configuration.frame().module().functions().size());
|
TRAP_IF_NOT(index.value() < configuration.frame().module().functions().size());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue