diff options
| author | Max Bernstein <max.bernstein@shopify.com> | 2025-02-06 11:13:17 -0500 |
|---|---|---|
| committer | Takashi Kokubun <takashikkbn@gmail.com> | 2025-04-18 21:52:55 +0900 |
| commit | bb9b45a8ddb66001a75ff5aa46729f4f8d5e3f97 (patch) | |
| tree | e19d22a0233720545fe83317a1f3dd9c046c4007 | |
| parent | 8ad08f112684acf5eff590363be6f3035cb242a2 (diff) | |
Add setlocal and getlocal
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13131
| -rw-r--r-- | zjit/src/ir.rs | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/zjit/src/ir.rs b/zjit/src/ir.rs index 2bc93b4c3a..3411f5bcb6 100644 --- a/zjit/src/ir.rs +++ b/zjit/src/ir.rs @@ -7,7 +7,7 @@ pub struct InsnId(usize); pub struct BlockId(usize); /// Instruction operand -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone, Copy)] enum Opnd { Const(VALUE), Insn(InsnId), @@ -15,7 +15,7 @@ enum Opnd { #[derive(Debug, PartialEq)] enum Insn { - // SSA block parameter + // SSA block parameter. Also used for function parameters in the function's entry block. Param { idx: usize }, Return { val: Opnd }, } @@ -53,6 +53,8 @@ impl Function { enum RubyOpcode { Putnil, Putobject(VALUE), + Setlocal(usize), + Getlocal(usize), Leave, } @@ -62,11 +64,12 @@ struct FrameState { // pc: stack: Vec<Opnd>, + locals: Vec<Opnd>, } impl FrameState { fn new() -> FrameState { - FrameState { stack: vec![] } + FrameState { stack: vec![], locals: vec![] } } fn push(&mut self, opnd: Opnd) { @@ -76,6 +79,20 @@ impl FrameState { fn pop(&mut self) -> Opnd { self.stack.pop().expect("Bytecode stack mismatch") } + + fn setlocal(&mut self, idx: usize, opnd: Opnd) { + if idx >= self.locals.len() { + self.locals.resize(idx+1, Opnd::Const(Qnil)); + } + self.locals[idx] = opnd; + } + + fn getlocal(&mut self, idx: usize) -> Opnd { + if idx >= self.locals.len() { + self.locals.resize(idx+1, Opnd::Const(Qnil)); + } + self.locals[idx] + } } fn to_ssa(opcodes: &Vec<RubyOpcode>) -> Function { @@ -86,6 +103,14 @@ fn to_ssa(opcodes: &Vec<RubyOpcode>) -> Function { match opcode { RubyOpcode::Putnil => { state.push(Opnd::Const(Qnil)); }, RubyOpcode::Putobject(val) => { state.push(Opnd::Const(*val)); }, + RubyOpcode::Setlocal(idx) => { + let val = state.pop(); + state.setlocal(*idx, val); + } + RubyOpcode::Getlocal(idx) => { + let val = state.getlocal(*idx); + state.push(val); + } RubyOpcode::Leave => { result.push_insn(block, Insn::Return { val: state.pop() }); }, |
