Skip to content

Commit 11c9a6f

Browse files
committed
Merge pull request #3644 from rubinius/zsuper-splat-and-keywords
Refactor zsuper instruction to handle arguments correctly
2 parents 9bc96e8 + 558c7c1 commit 11c9a6f

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

machine/instructions.def

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,16 +1944,33 @@ instruction zsuper(literal) [ block -- value ]
19441944
}
19451945

19461946
Tuple* tup = Tuple::create(state, arg_count);
1947-
for(int i = 0; i < mc->total_args; i++) {
1948-
tup->put(state, i, scope->get_local(state, i));
1947+
native_int tup_index = 0;
1948+
1949+
native_int fixed_args;
1950+
if(splat) {
1951+
fixed_args = mc->splat_position;
1952+
} else if(mc->keywords) {
1953+
fixed_args = mc->total_args - 1;
1954+
} else {
1955+
fixed_args = mc->total_args;
1956+
}
1957+
for(native_int i = 0; i < fixed_args; i++) {
1958+
tup->put(state, tup_index++, scope->get_local(state, i));
19491959
}
19501960

19511961
if(splat) {
19521962
for(native_int i = 0; i < splat->size(); i++) {
1953-
tup->put(state, i + mc->total_args, splat->get(state, i));
1963+
tup->put(state, tup_index++, splat->get(state, i));
19541964
}
19551965
} else if(splat_obj) {
1956-
tup->put(state, mc->total_args, splat_obj);
1966+
tup->put(state, tup_index++, splat_obj);
1967+
}
1968+
1969+
if(mc->post_args) {
1970+
native_int post_position = mc->splat_position + 1;
1971+
for(native_int i = post_position; i < post_position + mc->post_args; i++) {
1972+
tup->put(state, tup_index++, scope->get_local(state, i));
1973+
}
19571974
}
19581975

19591976
if(mc->keywords) {
@@ -1969,6 +1986,8 @@ instruction zsuper(literal) [ block -- value ]
19691986

19701987
placeholder->send(state, state->symbol("[]="), ary);
19711988
}
1989+
1990+
tup->put(state, tup_index++, scope->get_local(state, placeholder_position));
19721991
}
19731992

19741993
CallSite* call_site = reinterpret_cast<CallSite*>(literal);

spec/ruby/language/fixtures/super.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,4 +347,18 @@ def foo(a:, b: 'b', **)
347347
end
348348
end
349349
end
350+
351+
module SplatAndKeyword
352+
class A
353+
def foo(*args, **options)
354+
[args, options]
355+
end
356+
end
357+
358+
class B < A
359+
def foo(*args, **options)
360+
super
361+
end
362+
end
363+
end
350364
end

spec/ruby/language/super_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,5 +177,13 @@ def a(arg)
177177

178178
b.foo.should == {}
179179
end
180+
181+
describe 'when using splat arguments' do
182+
it 'passes splat arguments and keyword arguments to the parent' do
183+
b = Super::SplatAndKeyword::B.new
184+
185+
b.foo('bar', baz: true).should == [['bar'], {baz: true}]
186+
end
187+
end
180188
end
181189
end

0 commit comments

Comments
 (0)