Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: dd7f8b74be72
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d227756e7267
Choose a head ref
  • 3 commits
  • 4 files changed
  • 1 contributor

Commits on Nov 17, 2014

  1. Copy the full SHA
    b8d6643 View commit details
  2. Copy the full SHA
    5dec2f1 View commit details
  3. Use lookup in hash bootstrap.

    headius committed Nov 17, 2014
    Copy the full SHA
    d227756 View commit details
19 changes: 18 additions & 1 deletion core/src/main/java/org/jruby/ir/targets/Bootstrap.java
Original file line number Diff line number Diff line change
@@ -85,13 +85,22 @@ public static CallSite array(Lookup lookup, String name, MethodType type) {

public static CallSite hash(Lookup lookup, String name, MethodType type) {
MethodHandle handle = Binder
.from(type)
.from(lookup, type)
.collect(1, IRubyObject[].class)
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "hash");
CallSite site = new ConstantCallSite(handle);
return site;
}

public static CallSite kwargsHash(Lookup lookup, String name, MethodType type) {
MethodHandle handle = Binder
.from(lookup, type)
.collect(2, IRubyObject[].class)
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "kwargsHash");
CallSite site = new ConstantCallSite(handle);
return site;
}

public static CallSite ivar(Lookup lookup, String name, MethodType type) throws Throwable {
String[] names = name.split(":");
String operation = names[0];
@@ -139,6 +148,10 @@ public static Handle hash() {
return new Handle(Opcodes.H_INVOKESTATIC, p(Bootstrap.class), "hash", sig(CallSite.class, Lookup.class, String.class, MethodType.class));
}

public static Handle kwargsHash() {
return new Handle(Opcodes.H_INVOKESTATIC, p(Bootstrap.class), "kwargsHash", sig(CallSite.class, Lookup.class, String.class, MethodType.class));
}

public static Handle invokeSuper() {
return SuperInvokeSite.BOOTSTRAP;
}
@@ -264,6 +277,10 @@ public static IRubyObject hash(ThreadContext context, IRubyObject[] pairs) {
return hash;
}

public static IRubyObject kwargsHash(ThreadContext context, RubyHash hash, IRubyObject[] pairs) {
return IRRuntimeHelpers.dupKwargsHashAndPopulateFromArray(context, hash, pairs);
}

static MethodHandle buildGenericHandle(InvokeSite site, DynamicMethod method, RubyClass dispatchClass) {
SmartBinder binder;

Original file line number Diff line number Diff line change
@@ -487,7 +487,7 @@ public void array(int length) {
}

public void hash(int length) {
if (length > MAX_ARGUMENTS) throw new NotCompilableException("literal hash has more than " + (MAX_ARGUMENTS / 2) + " pairs");
if (length > MAX_ARGUMENTS / 2) throw new NotCompilableException("literal hash has more than " + (MAX_ARGUMENTS / 2) + " pairs");

SkinnyMethodAdapter adapter2;
String incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, length * 2));
@@ -517,7 +517,7 @@ public void hash(int length) {
}

public void kwargsHash(int length) {
if (length > MAX_ARGUMENTS) throw new NotCompilableException("kwargs hash has more than " + (MAX_ARGUMENTS / 2) + " pairs");
if (length > MAX_ARGUMENTS / 2) throw new NotCompilableException("kwargs hash has more than " + (MAX_ARGUMENTS / 2) + " pairs");

SkinnyMethodAdapter adapter2;
String incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, RubyHash.class, IRubyObject.class, length * 2));
@@ -532,11 +532,10 @@ public void kwargsHash(int length) {
null);

adapter2.aload(0);
adapter2.getfield(p(ThreadContext.class), "runtime", ci(Ruby.class));
adapter2.aload(1);
buildArrayFromLocals(adapter2, 2, length * 2);

adapter2.invokestatic(p(IRRuntimeHelpers.class), "constructHashFromArray", sig(RubyHash.class, Ruby.class, RubyHash.class, IRubyObject[].class));
adapter2.invokestatic(p(IRRuntimeHelpers.class), "dupKwargsHashAndPopulateFromArray", sig(RubyHash.class, ThreadContext.class, RubyHash.class, IRubyObject[].class));
adapter2.areturn();
adapter2.end();

Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
import org.jruby.RubyBignum;
import org.jruby.RubyClass;
import org.jruby.RubyEncoding;
import org.jruby.RubyHash;
import org.jruby.RubyRegexp;
import org.jruby.RubyString;
import org.jruby.compiler.NotCompilableException;
@@ -248,7 +249,9 @@ public void hash(int length) {
}

public void kwargsHash(int length) {
throw new RuntimeException("kwargsHash not implemented in IRBytecodeAdapter7");
if (length > MAX_ARGUMENTS / 2) throw new NotCompilableException("kwargs hash has more than " + (MAX_ARGUMENTS / 2) + " pairs");

adapter.invokedynamic("kwargsHash", sig(JVM.OBJECT, params(ThreadContext.class, RubyHash.class, JVM.OBJECT, length * 2)), Bootstrap.kwargsHash());
}

public void checkpoint() {
25 changes: 25 additions & 0 deletions spec/compiler/general_spec.rb
Original file line number Diff line number Diff line change
@@ -937,5 +937,30 @@ def foo(a)
it "raises errors for missing required keyword arguments" do
expect {run('def foo(a:); end; foo'){}}.to raise_error(ArgumentError)
end

it "passes keyrest arguments through zsuper correctly" do
run '
class C
def foo(str: "foo", num: 42, **opts)
[str, num, opts]
end
end
class D < C
def foo(str: "bar", num: 45, **opts)
super
end
end
[C.new.foo, D.new.foo, D.new.foo(str: "d", num:75, a:1, b:2)]
' do |x|

expect(x).to eq [
["foo", 42, {}],
["bar", 45, {}],
["d", 75, {a:1,b:2}]
]
end
end
end
end