mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-01 05:39:11 +00:00
LibWasm: Make blocks that take arguments actually work
Previously we were ignoring the actual parameters and setting the arity to an incorrect value, which could cause crashes (or unexpected traps).
This commit is contained in:
parent
b5ca290605
commit
fecbf0e03a
Notes:
sideshowbarker
2024-07-17 22:32:33 +09:00
Author: https://github.com/alimpfard
Commit: fecbf0e03a
Pull-request: https://github.com/SerenityOS/serenity/pull/11215
Reviewed-by: https://github.com/ADKaster
2 changed files with 52 additions and 8 deletions
|
@ -376,25 +376,60 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi
|
|||
return;
|
||||
case Instructions::block.value(): {
|
||||
size_t arity = 0;
|
||||
size_t parameter_count = 0;
|
||||
auto& args = instruction.arguments().get<Instruction::StructuredInstructionArgs>();
|
||||
if (args.block_type.kind() != BlockType::Empty)
|
||||
switch (args.block_type.kind()) {
|
||||
case BlockType::Empty:
|
||||
break;
|
||||
case BlockType::Type:
|
||||
arity = 1;
|
||||
configuration.stack().push(Label(arity, args.end_ip));
|
||||
break;
|
||||
case BlockType::Index: {
|
||||
auto& type = configuration.frame().module().types()[args.block_type.type_index().value()];
|
||||
arity = type.results().size();
|
||||
parameter_count = type.parameters().size();
|
||||
}
|
||||
}
|
||||
|
||||
configuration.stack().entries().insert(configuration.stack().size() - parameter_count, Label(arity, args.end_ip));
|
||||
return;
|
||||
}
|
||||
case Instructions::loop.value(): {
|
||||
size_t arity = 0;
|
||||
size_t parameter_count = 0;
|
||||
auto& args = instruction.arguments().get<Instruction::StructuredInstructionArgs>();
|
||||
if (args.block_type.kind() != BlockType::Empty)
|
||||
switch (args.block_type.kind()) {
|
||||
case BlockType::Empty:
|
||||
break;
|
||||
case BlockType::Type:
|
||||
arity = 1;
|
||||
configuration.stack().push(Label(arity, ip.value() + 1));
|
||||
break;
|
||||
case BlockType::Index: {
|
||||
auto& type = configuration.frame().module().types()[args.block_type.type_index().value()];
|
||||
arity = type.results().size();
|
||||
parameter_count = type.parameters().size();
|
||||
}
|
||||
}
|
||||
|
||||
configuration.stack().entries().insert(configuration.stack().size() - parameter_count, Label(arity, ip.value() + 1));
|
||||
return;
|
||||
}
|
||||
case Instructions::if_.value(): {
|
||||
size_t arity = 0;
|
||||
size_t parameter_count = 0;
|
||||
auto& args = instruction.arguments().get<Instruction::StructuredInstructionArgs>();
|
||||
if (args.block_type.kind() != BlockType::Empty)
|
||||
switch (args.block_type.kind()) {
|
||||
case BlockType::Empty:
|
||||
break;
|
||||
case BlockType::Type:
|
||||
arity = 1;
|
||||
break;
|
||||
case BlockType::Index: {
|
||||
auto& type = configuration.frame().module().types()[args.block_type.type_index().value()];
|
||||
arity = type.results().size();
|
||||
parameter_count = type.parameters().size();
|
||||
}
|
||||
}
|
||||
|
||||
auto entry = configuration.stack().pop();
|
||||
auto value = entry.get<Value>().to<i32>();
|
||||
|
@ -402,12 +437,12 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi
|
|||
if (value.value() == 0) {
|
||||
if (args.else_ip.has_value()) {
|
||||
configuration.ip() = args.else_ip.value();
|
||||
configuration.stack().push(move(end_label));
|
||||
configuration.stack().entries().insert(configuration.stack().size() - parameter_count, end_label);
|
||||
} else {
|
||||
configuration.ip() = args.end_ip.value() + 1;
|
||||
}
|
||||
} else {
|
||||
configuration.stack().push(move(end_label));
|
||||
configuration.stack().entries().insert(configuration.stack().size() - parameter_count, end_label);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2424,11 +2424,14 @@ VALIDATE_INSTRUCTION(block)
|
|||
if (stack.size() < parameters.size())
|
||||
return Errors::invalid_stack_state();
|
||||
|
||||
for (size_t i = 0; i < parameters.size(); ++i) {
|
||||
for (size_t i = 1; i <= parameters.size(); ++i) {
|
||||
if (stack.take_last() != parameters[parameters.size() - i])
|
||||
return Errors::invalid_stack_state();
|
||||
}
|
||||
|
||||
for (auto& parameter : parameters)
|
||||
stack.append(parameter);
|
||||
|
||||
m_entered_scopes.append(ChildScopeKind::Block);
|
||||
m_block_details.empend(stack.actual_size(), Empty {});
|
||||
m_parent_contexts.append(m_context);
|
||||
|
@ -2451,6 +2454,9 @@ VALIDATE_INSTRUCTION(loop)
|
|||
return Errors::invalid_stack_state();
|
||||
}
|
||||
|
||||
for (auto& parameter : parameters)
|
||||
stack.append(parameter);
|
||||
|
||||
m_entered_scopes.append(ChildScopeKind::Block);
|
||||
m_block_details.empend(stack.actual_size(), Empty {});
|
||||
m_parent_contexts.append(m_context);
|
||||
|
@ -2476,6 +2482,9 @@ VALIDATE_INSTRUCTION(if_)
|
|||
return Errors::invalid_stack_state();
|
||||
}
|
||||
|
||||
for (auto& parameter : parameters)
|
||||
stack.append(parameter);
|
||||
|
||||
m_entered_scopes.append(args.else_ip.has_value() ? ChildScopeKind::IfWithElse : ChildScopeKind::IfWithoutElse);
|
||||
m_block_details.empend(stack.actual_size(), BlockDetails::IfDetails { stack, {} });
|
||||
m_parent_contexts.append(m_context);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue