summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2025-02-06 11:45:21 -0500
committerTakashi Kokubun <takashikkbn@gmail.com>2025-04-18 21:52:56 +0900
commit64287c95caceb2d00b49d68946e0de5df0a642bf (patch)
tree72b4f2a201aeafde464136063ebc6d882041b2ce
parent21026abbd6d15135ea98358ba864ced2569c9d41 (diff)
Add iseq_to_ssa()
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13131
-rw-r--r--zjit/src/ir.rs49
1 files changed, 48 insertions, 1 deletions
diff --git a/zjit/src/ir.rs b/zjit/src/ir.rs
index f6033517ba..43d43fe66b 100644
--- a/zjit/src/ir.rs
+++ b/zjit/src/ir.rs
@@ -1,4 +1,7 @@
-use crate::cruby::{VALUE, Qnil};
+// We use the YARV bytecode constants which have a CRuby-style name
+#![allow(non_upper_case_globals)]
+
+use crate::cruby::*;
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct InsnId(usize);
@@ -155,6 +158,50 @@ fn to_ssa(opcodes: &Vec<RubyOpcode>) -> Function {
result
}
+fn iseq_to_ssa(iseq: *const rb_iseq_t) -> Function {
+ let mut result = Function::new();
+ let mut state = FrameState::new();
+ let block = result.entry_block;
+
+ let iseq_size = unsafe { get_iseq_encoded_size(iseq) };
+ let mut insn_idx = 0;
+
+ while insn_idx < iseq_size {
+ // Get the current pc and opcode
+ let pc = unsafe { rb_iseq_pc_at_idx(iseq, insn_idx.into()) };
+ // try_into() call below is unfortunate. Maybe pick i32 instead of usize for opcodes.
+ let opcode: u32 = unsafe { rb_iseq_opcode_at_pc(iseq, pc) }
+ .try_into()
+ .unwrap();
+
+ match opcode {
+ YARVINSN_putnil => { state.push(Opnd::Const(Qnil)); },
+ YARVINSN_putobject => { state.push(Opnd::Const(get_arg(pc, 0))); },
+ YARVINSN_setlocal_WC_0 => {
+ let val = state.pop();
+ state.setlocal(0, val);
+ }
+ YARVINSN_getlocal_WC_0 => {
+ let val = state.getlocal(0);
+ state.push(val);
+ }
+ YARVINSN_leave => {
+ result.push_insn(block, Insn::Return { val: state.pop() });
+ }
+ _ => todo!(),
+ }
+
+ // Move to the next instruction to compile
+ insn_idx += insn_len(opcode as usize);
+ }
+ return result;
+
+ fn get_arg(pc: *const VALUE, arg_idx: isize) -> VALUE {
+ unsafe { *(pc.offset(arg_idx + 1)) }
+
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;