1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:17:35 +00:00

LibJS/JIT: Compile the CopyObjectExcludingProperties instruction

This commit is contained in:
Simon Wanner 2023-10-30 02:00:53 +01:00 committed by Andreas Kling
parent 9494fbe670
commit ac59e982a9
3 changed files with 44 additions and 1 deletions

View file

@ -241,6 +241,10 @@ public:
return round_up_to_power_of_two(alignof(void*), sizeof(*this) + sizeof(Register) * excluded_names_count);
}
Register from_object() const { return m_from_object; }
size_t excluded_names_count() const { return m_excluded_names_count; }
Register const* excluded_names() const { return m_excluded_names; }
private:
Register m_from_object;
size_t m_excluded_names_count { 0 };

View file

@ -1679,6 +1679,44 @@ void Compiler::compile_put_by_value_with_this(Bytecode::Op::PutByValueWithThis c
check_exception();
}
static Value cxx_copy_object_excluding_properties(VM& vm, Value from_object, u64 excluded_names_count, Value* excluded_names)
{
auto& realm = *vm.current_realm();
auto to_object = Object::create(realm, realm.intrinsics().object_prototype());
HashTable<PropertyKey> excluded_names_table;
for (size_t i = 0; i < excluded_names_count; ++i) {
excluded_names_table.set(TRY_OR_SET_EXCEPTION(excluded_names[i].to_property_key(vm)));
}
TRY_OR_SET_EXCEPTION(to_object->copy_data_properties(vm, from_object, excluded_names_table));
return to_object;
}
void Compiler::compile_copy_object_excluding_properties(Bytecode::Op::CopyObjectExcludingProperties const& op)
{
load_vm_register(ARG1, op.from_object());
m_assembler.mov(
Assembler::Operand::Register(ARG2),
Assembler::Operand::Imm(op.excluded_names_count()));
// Build `Value arg3[op.excluded_names_count()] {...}` on the stack.
auto stack_space = align_up_to(op.excluded_names_count() * sizeof(Value), 16);
m_assembler.sub(Assembler::Operand::Register(STACK_POINTER), Assembler::Operand::Imm(stack_space));
m_assembler.mov(Assembler::Operand::Register(ARG3), Assembler::Operand::Register(STACK_POINTER));
for (size_t i = 0; i < op.excluded_names_count(); ++i) {
load_vm_register(GPR0, op.excluded_names()[i]);
m_assembler.mov(Assembler::Operand::Mem64BaseAndOffset(ARG3, i * sizeof(Value)), Assembler::Operand::Register(GPR0));
}
native_call((void*)cxx_copy_object_excluding_properties);
// Restore the stack pointer / discard array.
m_assembler.add(Assembler::Operand::Register(STACK_POINTER), Assembler::Operand::Imm(stack_space));
store_vm_register(Bytecode::Register::accumulator(), RET);
check_exception();
}
void Compiler::jump_to_exit()
{
m_assembler.jump(m_exit_label);

View file

@ -138,7 +138,8 @@ private:
O(GetMethod, get_method) \
O(GetNewTarget, get_new_target) \
O(HasPrivateId, has_private_id) \
O(PutByValueWithThis, put_by_value_with_this)
O(PutByValueWithThis, put_by_value_with_this) \
O(CopyObjectExcludingProperties, copy_object_excluding_properties)
# define DECLARE_COMPILE_OP(OpTitleCase, op_snake_case, ...) \
void compile_##op_snake_case(Bytecode::Op::OpTitleCase const&);