mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibWasm: Fix nested structured instruction parsing
Previously, the ip would not be propagated correctly, and we would produce invalid jumps when more than one level of nesting was involved. This makes loops work :P
This commit is contained in:
parent
29b193d25d
commit
207379165f
Notes:
sideshowbarker
2024-07-18 17:39:30 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/207379165f2 Pull-request: https://github.com/SerenityOS/serenity/pull/7239 Reviewed-by: https://github.com/linusg
2 changed files with 12 additions and 8 deletions
|
@ -28,10 +28,12 @@ void Interpreter::interpret(Configuration& configuration)
|
|||
|
||||
while (current_ip_value < max_ip_value) {
|
||||
auto& instruction = instructions[current_ip_value.value()];
|
||||
auto old_ip = current_ip_value;
|
||||
interpret(configuration, current_ip_value, instruction);
|
||||
if (m_do_trap)
|
||||
return;
|
||||
++current_ip_value;
|
||||
if (current_ip_value == old_ip) // If no jump occurred
|
||||
++current_ip_value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,18 +48,19 @@ void Interpreter::branch_to_label(Configuration& configuration, LabelIndex index
|
|||
size_t drop_count = index.value() + 1;
|
||||
|
||||
for (; !configuration.stack().is_empty();) {
|
||||
auto entry = configuration.stack().pop();
|
||||
auto& entry = configuration.stack().peek();
|
||||
if (entry.has<NonnullOwnPtr<Label>>()) {
|
||||
if (drop_count-- == 0)
|
||||
break;
|
||||
}
|
||||
configuration.stack().pop();
|
||||
}
|
||||
|
||||
// Push results in reverse
|
||||
for (size_t i = results.size(); i > 0; --i)
|
||||
configuration.stack().push(move(static_cast<Vector<NonnullOwnPtr<Value>>&>(results)[i - 1]));
|
||||
|
||||
configuration.ip() = label->continuation() + 1;
|
||||
configuration.ip() = label->continuation();
|
||||
}
|
||||
|
||||
ReadonlyBytes Interpreter::load_from_memory(Configuration& configuration, const Instruction& instruction, size_t size)
|
||||
|
@ -321,7 +324,7 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip
|
|||
auto& args = instruction.arguments().get<Instruction::StructuredInstructionArgs>();
|
||||
if (args.block_type.kind() != BlockType::Empty)
|
||||
arity = 1;
|
||||
configuration.stack().push(make<Label>(arity, ip.value() + 1));
|
||||
configuration.stack().push(make<Label>(arity, ip.value()));
|
||||
return;
|
||||
}
|
||||
case Instructions::if_.value(): {
|
||||
|
|
|
@ -82,7 +82,7 @@ struct ParseUntilAnyOfResult {
|
|||
Vector<T> values;
|
||||
};
|
||||
template<typename T, u8... terminators, typename... Args>
|
||||
static ParseResult<ParseUntilAnyOfResult<T>> parse_until_any_of(InputStream& stream, Args... args) requires(requires(InputStream& stream, Args... args) { T::parse(stream, args...); })
|
||||
static ParseResult<ParseUntilAnyOfResult<T>> parse_until_any_of(InputStream& stream, Args&... args) requires(requires(InputStream& stream, Args... args) { T::parse(stream, args...); })
|
||||
{
|
||||
ScopeLogger<WASM_BINPARSER_DEBUG> logger;
|
||||
ReconsumableStream new_stream { stream };
|
||||
|
@ -305,7 +305,8 @@ ParseResult<Vector<Instruction>> Instruction::parse(InputStream& stream, Instruc
|
|||
result.value().values.append(Instruction { Instructions::structured_end });
|
||||
|
||||
// Transform op(..., instr*) -> op(...) instr* op(end(ip))
|
||||
result.value().values.prepend(Instruction { opcode, StructuredInstructionArgs { BlockType { block_type.release_value() }, ++ip, {} } });
|
||||
result.value().values.prepend(Instruction { opcode, StructuredInstructionArgs { BlockType { block_type.release_value() }, ip.value(), {} } });
|
||||
++ip;
|
||||
return result.release_value().values;
|
||||
}
|
||||
|
||||
|
@ -314,7 +315,7 @@ ParseResult<Vector<Instruction>> Instruction::parse(InputStream& stream, Instruc
|
|||
instructions.append(result.release_value().values);
|
||||
instructions.append(Instruction { Instructions::structured_else });
|
||||
++ip;
|
||||
else_ip = ip;
|
||||
else_ip = ip.value();
|
||||
}
|
||||
// if with else
|
||||
{
|
||||
|
@ -324,7 +325,7 @@ ParseResult<Vector<Instruction>> Instruction::parse(InputStream& stream, Instruc
|
|||
instructions.append(result.release_value().values);
|
||||
instructions.append(Instruction { Instructions::structured_end });
|
||||
++ip;
|
||||
end_ip = ip;
|
||||
end_ip = ip.value();
|
||||
}
|
||||
|
||||
instructions.prepend(Instruction { opcode, StructuredInstructionArgs { BlockType { block_type.release_value() }, end_ip, else_ip } });
|
||||
|
|
Loading…
Reference in a new issue