summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bernstein <max.bernstein@shopify.com>2025-02-06 11:29:23 -0500
committerTakashi Kokubun <takashikkbn@gmail.com>2025-04-18 21:52:56 +0900
commit26d1aa40292b33c3dc35f4ce8ccca10f1efbd5a1 (patch)
tree0155f1f9ccbb9b4c98d96ffe09b2927479faa246
parent139102b24adb4fcd431785a3b5b38c4edbf3a515 (diff)
Add Intern opcode
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13131
-rw-r--r--zjit/src/ir.rs32
1 files changed, 30 insertions, 2 deletions
diff --git a/zjit/src/ir.rs b/zjit/src/ir.rs
index e39ca8bfcc..20f2f17663 100644
--- a/zjit/src/ir.rs
+++ b/zjit/src/ir.rs
@@ -18,6 +18,7 @@ enum Insn {
// SSA block parameter. Also used for function parameters in the function's entry block.
Param { idx: usize },
StringCopy { val: Opnd },
+ StringIntern { val: Opnd },
// Control flow instructions
Return { val: Opnd },
@@ -68,6 +69,7 @@ enum RubyOpcode {
Putnil,
Putobject(VALUE),
Putstring(VALUE),
+ Intern,
Setlocal(usize),
Getlocal(usize),
Leave,
@@ -119,8 +121,13 @@ fn to_ssa(opcodes: &Vec<RubyOpcode>) -> Function {
RubyOpcode::Putnil => { state.push(Opnd::Const(Qnil)); },
RubyOpcode::Putobject(val) => { state.push(Opnd::Const(*val)); },
RubyOpcode::Putstring(val) => {
- let insn_id = Opnd::Insn(result.push_insn(block, Insn::StringCopy { val: Opnd::Const(*val) }));
- state.push(insn_id);
+ let insn_id = result.push_insn(block, Insn::StringCopy { val: Opnd::Const(*val) });
+ state.push(Opnd::Insn(insn_id));
+ }
+ RubyOpcode::Intern => {
+ let val = state.pop();
+ let insn_id = result.push_insn(block, Insn::StringIntern { val });
+ state.push(Opnd::Insn(insn_id));
}
RubyOpcode::Setlocal(idx) => {
let val = state.pop();
@@ -159,4 +166,25 @@ mod tests {
],
});
}
+
+ #[test]
+ fn test_intern() {
+ let opcodes = vec![
+ RubyOpcode::Putstring(Qnil),
+ RubyOpcode::Intern,
+ RubyOpcode::Leave,
+ ];
+ let function = to_ssa(&opcodes);
+ assert_eq!(function, Function {
+ entry_block: BlockId(0),
+ insns: vec![
+ Insn::StringCopy { val: Opnd::Const(Qnil) },
+ Insn::StringIntern { val: Opnd::Insn(InsnId(0)) },
+ Insn::Return { val: Opnd::Insn(InsnId(1)) }
+ ],
+ blocks: vec![
+ Block { params: vec![], insns: vec![InsnId(0), InsnId(1), InsnId(2)] }
+ ],
+ });
+ }
}