Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add keyword arguments support for zsuper #3589

Merged
merged 2 commits into from
Apr 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions spec/jit/method_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,29 @@ def m(a=1, **kw) [a, kw] end
end
end
end

context "to m(a:, b: 'b', **) super end" do
before :each do
parent = Class.new do
def m(**args) args end
end

child = Class.new(parent) do
def m(a:, b: 'b', **) super end
end

@o = child.new

jit(@o, :m) { @o.m(a: "a", c: "c") }
end

it "compiles" do
@o.method(:m).executable.jitted?.should be_true
end

it "returns all keyword arguments passed including default ones" do
@o.m(a: "a", c: "c").should == {a: "a", b: "b", c: "c"}
end
end
end
end
1 change: 1 addition & 0 deletions spec/tags/jit/method_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
fails:JIT compiling a method call to m(a: 0) compiles
fails:JIT compiling a method call to m(a=1, **kw) compiles
fails:JIT compiling a method call to m(a:, b: 'b', **) super end compiles
2 changes: 0 additions & 2 deletions spec/tags/ruby/language/super_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:The super keyword raises a RuntimeError when called with implicit arguments from a method defined with define_method
fails:The super keyword invokes methods from a chain of anonymous modules
fails:The super keyword when using keyword arguments does not pass any keyword arguments to the parent when none are given
fails:The super keyword when using keyword arguments passes any given keyword arguments including optional and required ones to the parent
18 changes: 18 additions & 0 deletions vm/instructions.def
Original file line number Diff line number Diff line change
Expand Up @@ -2204,6 +2204,12 @@ instruction zsuper(literal) [ block -- value ]
}
}

native_int keywords_position, placeholder_position;
if(mc->keywords) {
placeholder_position = splat_obj ? mc->total_args : mc->total_args - 1;
keywords_position = placeholder_position + 1;
}

Tuple* tup = Tuple::create_dirty(state, arg_count);
for(int i = 0; i < mc->total_args; i++) {
tup->put(state, i, scope->get_local(state, i));
Expand All @@ -2217,6 +2223,18 @@ instruction zsuper(literal) [ block -- value ]
tup->put(state, mc->total_args, splat_obj);
}

if(mc->keywords) {
Object* placeholder = scope->get_local(state, placeholder_position);
Array* ary = Array::create(state, 2);

for(native_int i = keywords_position; i <= mc->keywords_count; i++) {
ary->set(state, 0, as<Symbol>(call_frame->compiled_code->local_names()->at(state, i)));
ary->set(state, 1, scope->get_local(state, i));

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

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

Arguments new_args(call_site->name(), recv, block, arg_count, 0);
Expand Down
4 changes: 4 additions & 0 deletions vm/machine_code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ namespace rubinius {
run = MachineCode::tooling_interpreter;
}

if(keywords) {
keywords_count = meth->keywords()->num_fields() / 2;
}

opcodes = new opcode[total];

fill_opcodes(state, meth);
Expand Down
1 change: 1 addition & 0 deletions vm/machine_code.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace rubinius {
native_int required_args;
native_int post_args;
native_int splat_position;
native_int keywords_count;

native_int stack_size;
native_int number_of_locals;
Expand Down