Add setlocal and getlocal
This commit is contained in:
parent
8ad08f1126
commit
bb9b45a8dd
Notes:
git
2025-04-18 13:49:52 +00:00
@ -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() });
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user