Skip to content

Commit b83b00c

Browse files
committed
ZJIT: Add dupn support
1 parent c99cb62 commit b83b00c

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

test/ruby/test_zjit.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,16 @@ def test = X
699699
end
700700
end
701701

702+
def test_dupn
703+
assert_compiles '[[1], [1, 1], :rhs, [nil, :rhs]]', <<~RUBY, insns: [:dupn]
704+
def test(array) = (array[1, 2] ||= :rhs)
705+
706+
one = [1, 1]
707+
start_empty = []
708+
[test(one), one, test(start_empty), start_empty]
709+
RUBY
710+
end
711+
702712
def test_send_backtrace
703713
backtrace = [
704714
"-e:2:in 'Object#jit_frame1'",

zjit/src/hir.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,6 +2389,14 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
23892389
}
23902390
YARVINSN_pop => { state.stack_pop()?; }
23912391
YARVINSN_dup => { state.stack_push(state.stack_top()?); }
2392+
YARVINSN_dupn => {
2393+
// Duplicate the top N element of the stack. As we push, n-1 naturally
2394+
// points higher in the original stack.
2395+
let n = get_arg(pc, 0).as_usize();
2396+
for _ in 0..n {
2397+
state.stack_push(state.stack_topn(n-1)?);
2398+
}
2399+
}
23922400
YARVINSN_swap => {
23932401
let right = state.stack_pop()?;
23942402
let left = state.stack_pop()?;
@@ -4180,6 +4188,29 @@ mod tests {
41804188
Return v10
41814189
"#]]);
41824190
}
4191+
4192+
#[test]
4193+
fn dupn() {
4194+
eval("
4195+
def test(x) = (x[0, 1] ||= 2)
4196+
");
4197+
assert_method_hir_with_opcode("test", YARVINSN_dupn, expect![[r#"
4198+
fn test:
4199+
bb0(v0:BasicObject, v1:BasicObject):
4200+
v3:NilClassExact = Const Value(nil)
4201+
v4:Fixnum[0] = Const Value(0)
4202+
v5:Fixnum[1] = Const Value(1)
4203+
v7:BasicObject = SendWithoutBlock v1, :[], v4, v5
4204+
v8:CBool = Test v7
4205+
IfTrue v8, bb1(v0, v1, v3, v1, v4, v5, v7)
4206+
v10:Fixnum[2] = Const Value(2)
4207+
v12:BasicObject = SendWithoutBlock v1, :[]=, v4, v5, v10
4208+
Return v10
4209+
bb1(v14:BasicObject, v15:BasicObject, v16:NilClassExact, v17:BasicObject, v18:Fixnum[0], v19:Fixnum[1], v20:BasicObject):
4210+
Return v20
4211+
"#]]);
4212+
4213+
}
41834214
}
41844215

41854216
#[cfg(test)]

0 commit comments

Comments
 (0)