Skip to content

Commit

Permalink
Showing 3 changed files with 54 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -48,6 +48,9 @@ protected IRubyObject[] toAry(ThreadContext context, IRubyObject[] args) {
return args;
}

// SSS FIXME: This code only works for block yields, not rubyproc calls.
// When a block is converted to a RubyProc and called, this code below
// needs to implement the logic in BlockBody:prepareArgumentsForCall.
public IRubyObject[] prepareBlockArgs(ThreadContext context, Block b, IRubyObject[] args) {
// This is the placeholder for scenarios
// not handled by specialized instructions.
18 changes: 15 additions & 3 deletions core/src/main/java/org/jruby/runtime/BlockBody.java
Original file line number Diff line number Diff line change
@@ -155,7 +155,11 @@ public IRubyObject call(ThreadContext context, Block block, IRubyObject arg0, Bl
}

public IRubyObject yieldSpecific(ThreadContext context, Block block, IRubyObject arg0) {
return yield(context, block, arg0);
if (hasCallProtocolIR()) {
return yieldDirect(context, block, new IRubyObject[] { arg0 }, null);
} else {
return yield(context, block, arg0);
}
}
public IRubyObject call(ThreadContext context, Block block, IRubyObject arg0, IRubyObject arg1) {
IRubyObject[] args = new IRubyObject[] {arg0, arg1};
@@ -168,7 +172,11 @@ public IRubyObject call(ThreadContext context, Block block, IRubyObject arg0, IR
}

public IRubyObject yieldSpecific(ThreadContext context, Block block, IRubyObject arg0, IRubyObject arg1) {
return yield(context, block, new IRubyObject[] { arg0, arg1 }, null);
if (hasCallProtocolIR()) {
return yieldDirect(context, block, new IRubyObject[] { arg0, arg1 }, null);
} else {
return yield(context, block, new IRubyObject[] { arg0, arg1 }, null);
}
}
public IRubyObject call(ThreadContext context, Block block, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) {
IRubyObject[] args = new IRubyObject[] {arg0, arg1, arg2};
@@ -181,7 +189,11 @@ public IRubyObject call(ThreadContext context, Block block, IRubyObject arg0, IR
}

public IRubyObject yieldSpecific(ThreadContext context, Block block, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) {
return yield(context, block, new IRubyObject[] { arg0, arg1, arg2 }, null);
if (hasCallProtocolIR()) {
return yieldDirect(context, block, new IRubyObject[] { arg0, arg1, arg2 }, null);
} else {
return yield(context, block, new IRubyObject[] { arg0, arg1, arg2 }, null);
}
}


52 changes: 36 additions & 16 deletions core/src/main/java/org/jruby/runtime/IRBlockBody.java
Original file line number Diff line number Diff line change
@@ -70,38 +70,58 @@ public IRubyObject call(ThreadContext context, Block block, IRubyObject[] args,

@Override
public IRubyObject yieldSpecific(ThreadContext context, Block block) {
IRubyObject[] args = IRubyObject.NULL_ARRAY;
if (block.type == Block.Type.LAMBDA) signature.checkArity(context.runtime, args);
if (hasCallProtocolIR()) {
return yieldDirect(context, block, null, null);
} else {
IRubyObject[] args = IRubyObject.NULL_ARRAY;
if (block.type == Block.Type.LAMBDA) signature.checkArity(context.runtime, args);

return commonYieldPath(context, block, args, null, Block.NULL_BLOCK);
return commonYieldPath(context, block, args, null, Block.NULL_BLOCK);
}
}

@Override
public IRubyObject yieldSpecific(ThreadContext context, Block block, IRubyObject arg0) {
if (arg0 instanceof RubyArray) {
// Unwrap the array arg
IRubyObject[] args = IRRuntimeHelpers.convertValueIntoArgArray(context, arg0, signature.arityValue(), true);
IRubyObject[] args;
if (hasCallProtocolIR()) {
if (arg0 instanceof RubyArray) {
// Unwrap the array arg
args = IRRuntimeHelpers.convertValueIntoArgArray(context, arg0, signature.arityValue(), true);
} else {
args = new IRubyObject[] { arg0 };
}
return yieldDirect(context, block, args, null);
} else {
if (arg0 instanceof RubyArray) {
// Unwrap the array arg
args = IRRuntimeHelpers.convertValueIntoArgArray(context, arg0, signature.arityValue(), true);

// FIXME: arity error is aginst new args but actual error shows arity of original args.
if (block.type == Block.Type.LAMBDA) signature.checkArity(context.runtime, args);
// FIXME: arity error is aginst new args but actual error shows arity of original args.
if (block.type == Block.Type.LAMBDA) signature.checkArity(context.runtime, args);

return commonYieldPath(context, block, args, null, Block.NULL_BLOCK);
} else {
return yield(context, block, arg0);
return commonYieldPath(context, block, args, null, Block.NULL_BLOCK);
} else {
return yield(context, block, arg0);
}
}
}

IRubyObject yieldSpecificMultiArgsCommon(ThreadContext context, Block block, IRubyObject[] args) {
int blockArity = getSignature().arityValue();
if (blockArity == 0) {
args = IRubyObject.NULL_ARRAY; // discard args
} else if (blockArity == 1) {
if (blockArity == 1) {
args = new IRubyObject[] { RubyArray.newArrayNoCopy(context.runtime, args) };
}

if (block.type == Block.Type.LAMBDA) signature.checkArity(context.runtime, args);
if (hasCallProtocolIR()) {
return yieldDirect(context, block, args, null);
} else {
if (blockArity == 0) {
args = IRubyObject.NULL_ARRAY; // discard args
}
if (block.type == Block.Type.LAMBDA) signature.checkArity(context.runtime, args);

return commonYieldPath(context, block, args, null, Block.NULL_BLOCK);
return commonYieldPath(context, block, args, null, Block.NULL_BLOCK);
}
}

@Override

0 comments on commit 9e38d83

Please sign in to comment.