summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zjit/src/asm/mod.rs5
-rw-r--r--zjit/src/codegen.rs23
-rw-r--r--zjit/src/lib.rs10
3 files changed, 32 insertions, 6 deletions
diff --git a/zjit/src/asm/mod.rs b/zjit/src/asm/mod.rs
index a9d4621b1e..a95569a011 100644
--- a/zjit/src/asm/mod.rs
+++ b/zjit/src/asm/mod.rs
@@ -130,6 +130,11 @@ impl CodeBlock {
// self.dropped_bytes = true; // retry emitting the Insn after next_page
//}
}
+
+ /// Make all the code in the region executable. Call this at the end of a write session.
+ pub fn mark_all_executable(&mut self) {
+ self.mem_block.borrow_mut().mark_all_executable();
+ }
}
impl crate::virtualmem::CodePtrBase for CodeBlock {
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs
new file mode 100644
index 0000000000..19b09e4456
--- /dev/null
+++ b/zjit/src/codegen.rs
@@ -0,0 +1,23 @@
+use crate::{asm::CodeBlock, backend::ir::*, cruby::*};
+
+/// Compile code that pops a frame and returns Qnil
+pub fn gen_leave(cb: &mut CodeBlock) {
+ let mut asm = Assembler::new();
+
+ // rdi: EC, rsi: CFP
+ let ec = C_ARG_OPNDS[0];
+ let cfp = C_ARG_OPNDS[1];
+
+ // Pop frame: CFP = CFP + RUBY_SIZEOF_CONTROL_FRAME
+ let incr_cfp = asm.add(cfp, RUBY_SIZEOF_CONTROL_FRAME.into());
+ asm.mov(cfp, incr_cfp);
+
+ // Set ec->cfp: *(EC + RUBY_OFFSET_EC_CFP) = CFP
+ asm.mov(Opnd::mem(64, ec, RUBY_OFFSET_EC_CFP), cfp);
+
+ // Return Qnil
+ asm.cret(Qnil.into());
+
+ asm.compile_with_regs(cb, Assembler::get_alloc_regs());
+ cb.mark_all_executable();
+}
diff --git a/zjit/src/lib.rs b/zjit/src/lib.rs
index b50eb720f5..b557602ccc 100644
--- a/zjit/src/lib.rs
+++ b/zjit/src/lib.rs
@@ -4,6 +4,7 @@
mod state;
mod cruby;
mod ir;
+mod codegen;
mod stats;
mod utils;
mod virtualmem;
@@ -12,6 +13,7 @@ mod backend;
mod disasm;
mod options;
+use codegen::gen_leave;
use state::ZJITState;
#[cfg(feature = "disasm")]
use options::get_option;
@@ -80,7 +82,7 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, _ec: EcPtr) -> *co
let cb = ZJITState::get_code_block();
let start_ptr = cb.get_write_ptr();
- //x86_emit(cb);
+ gen_leave(cb);
#[cfg(feature = "disasm")]
if get_option!(dump_disasm) {
@@ -89,9 +91,5 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, _ec: EcPtr) -> *co
println!("{}", disasm);
}
- if cfg!(target_arch = "x86_64") {
- start_ptr.raw_ptr(cb)
- } else {
- std::ptr::null()
- }
+ start_ptr.raw_ptr(cb)
}