Skip to content

Commit

Permalink
Merge pull request #3644 from rubinius/zsuper-splat-and-keywords
Browse files Browse the repository at this point in the history
Refactor zsuper instruction to handle arguments correctly
  • Loading branch information
brixen committed Apr 30, 2016
2 parents 9bc96e8 + 558c7c1 commit 11c9a6f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
27 changes: 23 additions & 4 deletions machine/instructions.def
Expand Up @@ -1944,16 +1944,33 @@ instruction zsuper(literal) [ block -- value ]
}

Tuple* tup = Tuple::create(state, arg_count);
for(int i = 0; i < mc->total_args; i++) {
tup->put(state, i, scope->get_local(state, i));
native_int tup_index = 0;

native_int fixed_args;
if(splat) {
fixed_args = mc->splat_position;
} else if(mc->keywords) {
fixed_args = mc->total_args - 1;
} else {
fixed_args = mc->total_args;
}
for(native_int i = 0; i < fixed_args; i++) {
tup->put(state, tup_index++, scope->get_local(state, i));
}

if(splat) {
for(native_int i = 0; i < splat->size(); i++) {
tup->put(state, i + mc->total_args, splat->get(state, i));
tup->put(state, tup_index++, splat->get(state, i));
}
} else if(splat_obj) {
tup->put(state, mc->total_args, splat_obj);
tup->put(state, tup_index++, splat_obj);
}

if(mc->post_args) {
native_int post_position = mc->splat_position + 1;
for(native_int i = post_position; i < post_position + mc->post_args; i++) {
tup->put(state, tup_index++, scope->get_local(state, i));
}
}

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

placeholder->send(state, state->symbol("[]="), ary);
}

tup->put(state, tup_index++, scope->get_local(state, placeholder_position));
}

CallSite* call_site = reinterpret_cast<CallSite*>(literal);
Expand Down
14 changes: 14 additions & 0 deletions spec/ruby/language/fixtures/super.rb
Expand Up @@ -347,4 +347,18 @@ def foo(a:, b: 'b', **)
end
end
end

module SplatAndKeyword
class A
def foo(*args, **options)
[args, options]
end
end

class B < A
def foo(*args, **options)
super
end
end
end
end
8 changes: 8 additions & 0 deletions spec/ruby/language/super_spec.rb
Expand Up @@ -177,5 +177,13 @@ def a(arg)

b.foo.should == {}
end

describe 'when using splat arguments' do
it 'passes splat arguments and keyword arguments to the parent' do
b = Super::SplatAndKeyword::B.new

b.foo('bar', baz: true).should == [['bar'], {baz: true}]
end
end
end
end

0 comments on commit 11c9a6f

Please sign in to comment.