1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:18:11 +00:00

LibJS/Bytecode: Put arguments directly in the Call instruction

Instead of having Call refer to a range of VM registers, it now has
a trailing list of argument operands as part of the instruction.

This means we no longer have to shuffle every argument value into
a register before making a call, making bytecode smaller & faster. :^)
This commit is contained in:
Andreas Kling 2024-02-20 15:59:45 +01:00
parent da107ec9fb
commit 9a0a5a79f4
3 changed files with 70 additions and 53 deletions

View file

@ -1627,19 +1627,19 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> CallExpression::gen
auto arguments = TRY(arguments_to_array_for_call(generator, this->arguments())).value();
generator.emit<Bytecode::Op::CallWithArgumentArray>(call_type, dst, callee, this_value, arguments, expression_string_index);
} else {
Optional<Bytecode::Register> first_argument_reg {};
for (size_t i = 0; i < arguments().size(); ++i) {
auto reg = generator.allocate_register();
if (!first_argument_reg.has_value())
first_argument_reg = reg;
}
u32 register_offset = 0;
Vector<Bytecode::Operand> argument_operands;
for (auto const& argument : arguments()) {
auto value = TRY(argument.value->generate_bytecode(generator)).value();
generator.emit<Bytecode::Op::Mov>(Bytecode::Operand(Bytecode::Register(first_argument_reg.value().index() + register_offset)), value);
register_offset += 1;
argument_operands.append(TRY(argument.value->generate_bytecode(generator)).value());
}
generator.emit<Bytecode::Op::Call>(call_type, dst, callee, this_value, first_argument_reg.value_or(Bytecode::Register { 0 }), arguments().size(), expression_string_index, builtin);
generator.emit_with_extra_operand_slots<Bytecode::Op::Call>(
argument_operands.size(),
call_type,
dst,
callee,
this_value,
argument_operands,
expression_string_index,
builtin);
}
return dst;