diff --git a/Userland/Libraries/LibJS/JIT/Compiler.cpp b/Userland/Libraries/LibJS/JIT/Compiler.cpp index 0e02788381..560c0e0ab7 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.cpp +++ b/Userland/Libraries/LibJS/JIT/Compiler.cpp @@ -1685,6 +1685,45 @@ void Compiler::compile_async_iterator_close(Bytecode::Op::AsyncIteratorClose con check_exception(); } +static Value cxx_continuation(VM& vm, Value value, Value continuation, Value is_await) +{ + auto object = Object::create(*vm.current_realm(), nullptr); + object->define_direct_property("result", value.value_or(js_undefined()), JS::default_attributes); + object->define_direct_property("continuation", continuation, JS::default_attributes); + object->define_direct_property("isAwait", is_await, JS::default_attributes); + return object; +} + +void Compiler::compile_continuation(Optional continuation, bool is_await) +{ + load_accumulator(ARG1); + if (continuation.has_value()) { + // FIXME: If we get a pointer, which is not accurately representable as a double + // will cause this to explode + auto continuation_value = Value(static_cast(bit_cast(&continuation->block()))); + m_assembler.mov( + Assembler::Operand::Register(ARG2), + Assembler::Operand::Imm(continuation_value.encoded())); + } else { + m_assembler.mov( + Assembler::Operand::Register(ARG2), + Assembler::Operand::Imm(Value(0).encoded())); + } + m_assembler.mov( + Assembler::Operand::Register(ARG3), + Assembler::Operand::Imm(Value(is_await).encoded())); + native_call((void*)cxx_continuation); + store_vm_register(Bytecode::Register::return_value(), RET); + + // FIXME: This should run the finalizer if it is a return + jump_to_exit(); +} + +void Compiler::compile_yield(Bytecode::Op::Yield const& op) +{ + compile_continuation(op.continuation(), false); +} + void Compiler::jump_to_exit() { m_assembler.jump(m_exit_label); diff --git a/Userland/Libraries/LibJS/JIT/Compiler.h b/Userland/Libraries/LibJS/JIT/Compiler.h index 121fb4aa26..f306d25bea 100644 --- a/Userland/Libraries/LibJS/JIT/Compiler.h +++ b/Userland/Libraries/LibJS/JIT/Compiler.h @@ -140,7 +140,8 @@ private: O(HasPrivateId, has_private_id) \ O(PutByValueWithThis, put_by_value_with_this) \ O(CopyObjectExcludingProperties, copy_object_excluding_properties) \ - O(AsyncIteratorClose, async_iterator_close) + O(AsyncIteratorClose, async_iterator_close) \ + O(Yield, yield) # define DECLARE_COMPILE_OP(OpTitleCase, op_snake_case, ...) \ void compile_##op_snake_case(Bytecode::Op::OpTitleCase const&); @@ -160,6 +161,7 @@ private: void store_accumulator(Assembler::Reg); void compile_to_boolean(Assembler::Reg dst, Assembler::Reg src); + void compile_continuation(Optional, bool is_await); void check_exception(); void handle_exception();