Skip to content

Commit

Permalink
Ensure super(**kw, &block) calls kw.to_hash before block.to_proc
Browse files Browse the repository at this point in the history
Similar as previous commit, but handles the super case with
explicit arguments.
  • Loading branch information
jeremyevans committed Dec 9, 2023
1 parent a950f23 commit f643575
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
3 changes: 3 additions & 0 deletions compile.c
Expand Up @@ -9229,6 +9229,9 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
VALUE vargc = setup_args(iseq, args, RNODE_SUPER(node)->nd_args, &flag, &keywords);
CHECK(!NIL_P(vargc));
argc = FIX2INT(vargc);
if ((flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT) && !(flag & VM_CALL_KW_SPLAT_MUT)) {
ADD_INSN(args, node, splatkw);
}
}
else {
/* NODE_ZSUPER */
Expand Down
20 changes: 20 additions & 0 deletions test/ruby/test_call.rb
Expand Up @@ -164,6 +164,26 @@ def self.t(...) end
assert_equal([:to_a, :to_hash, :to_proc], ary)
end

def test_kwsplat_block_order_super
def self.t(splat)
o = Object.new
ary = []
o.define_singleton_method(:to_a) {ary << :to_a; []}
o.define_singleton_method(:to_hash) {ary << :to_hash; {}}
o.define_singleton_method(:to_proc) {ary << :to_proc; lambda{}}
if splat
super(*o, **o, &o)
else
super(**o, &o)
end
ary
end
extend Module.new{def t(...) end}

assert_equal([:to_hash, :to_proc], t(false))
assert_equal([:to_a, :to_hash, :to_proc], t(true))
end

OVER_STACK_LEN = (ENV['RUBY_OVER_STACK_LEN'] || 150).to_i # Greater than VM_ARGC_STACK_MAX
OVER_STACK_ARGV = OVER_STACK_LEN.times.to_a.freeze

Expand Down

0 comments on commit f643575

Please sign in to comment.