Skip to content

Commit bbc0e70

Browse files
committed
Add pushtoarray insn to fix segfault with forwarding + splat
Example insns diff for `def x = [3]; def a(...) = b(*x, 2, 3, ...)` == disasm: #<ISeq:a@-e:1 (1,13)-(1,42)> local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] "..."@0 0000 putself ( 1)[Ca] 0000 putself 0000 opt_send_without_block <calldata!mid:x, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0000 splatarray true 0000 putobject 2 0000 putobject 3 +0000 pushtoarray 2 0000 getlocal_WC_0 "..."@0 0000 sendforward <calldata!mid:b, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL|FORWARDING>, nil 0000 leave [Re] This matches the insns produced by parse.y
1 parent c04363c commit bbc0e70

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

bootstraptest/test_method.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,3 +1419,18 @@ def internal_foo = foo
14191419
"ok"
14201420
end
14211421
}
1422+
1423+
assert_equal '[1, 2, 3]', %q{
1424+
def target(*args) = args
1425+
def x = [1]
1426+
def forwarder(...) = target(*x, 2, ...)
1427+
forwarder(3).inspect
1428+
}, '[Bug #21832] post-splat args before forwarding'
1429+
1430+
assert_equal 'ok', <<~RUBY
1431+
def test(*, kw: false)
1432+
"ok"
1433+
end
1434+
1435+
test
1436+
RUBY

prism_compile.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,10 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
18111811
// foo(*a, b, c: :d)
18121812
// foo(*a, b, **c)
18131813
//
1814+
// If the next node is a forwarding argument:
1815+
//
1816+
// foo(*a, b, ...)
1817+
//
18141818
// If the next node is NULL (we have hit the end):
18151819
//
18161820
// foo(*a, b)
@@ -1833,6 +1837,10 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
18331837
PUSH_INSN(ret, location, concatarray);
18341838
break;
18351839
}
1840+
case PM_FORWARDING_ARGUMENTS_NODE: {
1841+
PUSH_INSN1(ret, location, pushtoarray, INT2FIX(post_splat_counter));
1842+
break;
1843+
}
18361844
default:
18371845
break;
18381846
}

0 commit comments

Comments
 (0)