mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 03:27:45 +00:00
LibJS/JIT: Compile the Yield instruction
This commit is contained in:
parent
e400682fb1
commit
4671520c0a
2 changed files with 42 additions and 1 deletions
|
@ -1685,6 +1685,45 @@ void Compiler::compile_async_iterator_close(Bytecode::Op::AsyncIteratorClose con
|
||||||
check_exception();
|
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<Bytecode::Label> 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<double>(bit_cast<u64>(&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()
|
void Compiler::jump_to_exit()
|
||||||
{
|
{
|
||||||
m_assembler.jump(m_exit_label);
|
m_assembler.jump(m_exit_label);
|
||||||
|
|
|
@ -140,7 +140,8 @@ private:
|
||||||
O(HasPrivateId, has_private_id) \
|
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) \
|
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, ...) \
|
# define DECLARE_COMPILE_OP(OpTitleCase, op_snake_case, ...) \
|
||||||
void compile_##op_snake_case(Bytecode::Op::OpTitleCase const&);
|
void compile_##op_snake_case(Bytecode::Op::OpTitleCase const&);
|
||||||
|
@ -160,6 +161,7 @@ private:
|
||||||
void store_accumulator(Assembler::Reg);
|
void store_accumulator(Assembler::Reg);
|
||||||
|
|
||||||
void compile_to_boolean(Assembler::Reg dst, Assembler::Reg src);
|
void compile_to_boolean(Assembler::Reg dst, Assembler::Reg src);
|
||||||
|
void compile_continuation(Optional<Bytecode::Label>, bool is_await);
|
||||||
|
|
||||||
void check_exception();
|
void check_exception();
|
||||||
void handle_exception();
|
void handle_exception();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue