mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:17:44 +00:00
LibJS/JIT: Compile the CopyObjectExcludingProperties instruction
This commit is contained in:
parent
9494fbe670
commit
ac59e982a9
3 changed files with 44 additions and 1 deletions
|
@ -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 };
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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&);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue