Skip to content

Commit

Permalink
Showing 2 changed files with 51 additions and 62 deletions.
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ir/operands/Nil.java
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ public Nil() {

@Override
public OperandType getOperandType() {
return OperandType.LOCAL_VARIABLE;
return OperandType.NIL;
}

@Override
111 changes: 50 additions & 61 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Original file line number Diff line number Diff line change
@@ -1516,44 +1516,34 @@ private static IRubyObject[] prepareProcArgs(ThreadContext context, Block b, IRu
}

private static IRubyObject[] prepareBlockArgsInternal(ThreadContext context, Block block, IRubyObject[] args) {
// This is the placeholder for scenarios
// not handled by specialized instructions.
if (args == null) {
args = IRubyObject.NULL_ARRAY;
}

boolean isLambda = block.type == Block.Type.LAMBDA;
boolean isProcCall = context.getCurrentBlockType() == Block.Type.PROC;
if (isProcCall) {
if (isLambda) {
block.getBody().getSignature().checkArity(context.runtime, args);
return args;
} else {
return prepareProcArgs(context, block, args);
org.jruby.runtime.Signature sig = block.getBody().getSignature();
if (block.type == Block.Type.LAMBDA) {
if (!isProcCall && sig.arityValue() != -1 && sig.required() != 1) {
args = toAry(context, args);
}
sig.checkArity(context.runtime, args);
return args;
}

if (isProcCall) {
return prepareProcArgs(context, block, args);
}

BlockBody body = block.getBody();
org.jruby.runtime.Signature sig = body.getSignature();
int arityValue = sig.arityValue();
if (isLambda && (arityValue == -1 || sig.required() == 1)) {
block.getBody().getSignature().checkArity(context.runtime, args);
return args;
} else if (!isLambda && arityValue >= -1 && arityValue <= 1) {
if (arityValue >= -1 && arityValue <= 1) {
return args;
}

// We get here only when we have both required and optional/rest args
// We get here only when we need both required and optional/rest args
// (keyword or non-keyword in either case).
// So, convert a single value to an array if possible.
args = toAry(context, args);

// Nothing more to do for lambdas
if (isLambda) {
block.getBody().getSignature().checkArity(context.runtime, args);
return args;
}

// Deal with keyword args that needs special handling
int needsKwargs = sig.hasKwargs() ? 1 - sig.getRequiredKeywordForArityCount() : 0;
int required = sig.required();
@@ -1593,78 +1583,77 @@ private static IRubyObject[] prepareBlockArgsInternal(ThreadContext context, Blo
*/
@Interp @JIT
public static IRubyObject[] prepareNoBlockArgs(ThreadContext context, Block block, IRubyObject[] args) {
if (args == null) {
args = IRubyObject.NULL_ARRAY;
}

if (block.type == Block.Type.LAMBDA) {
block.getSignature().checkArity(context.runtime, args);
}
return args;
}

@Interp @JIT
public static IRubyObject[] prepareBlockArgs(ThreadContext context, Block block, IRubyObject[] args, boolean usesKwArgs) {
args = prepareBlockArgsInternal(context, block, args);
if (usesKwArgs) {
frobnicateKwargsArgument(context, block.getBody().getSignature().required(), args);
}
return args;
}

@Interp @JIT
public static IRubyObject[] prepareFixedBlockArgs(ThreadContext context, Block block, IRubyObject[] args) {
public static IRubyObject[] prepareSingleBlockArgs(ThreadContext context, Block block, IRubyObject[] args) {
if (args == null) {
args = IRubyObject.NULL_ARRAY;
}

boolean isLambda = block.type == Block.Type.LAMBDA;
if (block.type == Block.Type.LAMBDA) {
block.getBody().getSignature().checkArity(context.runtime, args);
return args;
}

boolean isProcCall = context.getCurrentBlockType() == Block.Type.PROC;
if (isProcCall) {
if (isLambda) {
block.getBody().getSignature().checkArity(context.runtime, args);
return args;
if (args.length == 0) {
args = context.runtime.getSingleNilArray();
} else if (args.length == 1) {
args = prepareProcArgs(context, block, args);
} else {
return prepareProcArgs(context, block, args);
args = new IRubyObject[] { args[0] };
}
}

// SSS FIXME: This check here is not required as long as
// the single-instruction cases always uses PrepareSingleBlockArgInstr
// But, including this here for robustness for now.
if (block.getBody().getSignature().arityValue() == 1) {
if (isLambda) block.getBody().getSignature().checkArity(context.runtime, args);
return args;
}

// Since we have more than 1 required arg,
// convert a single value to an array if possible.
args = IRRuntimeHelpers.toAry(context, args);

if (isLambda) block.getBody().getSignature().checkArity(context.runtime, args);

// If there are insufficient args, ReceivePreReqdInstr will return nil
return args;
}

@Interp @JIT
public static IRubyObject[] prepareSingleBlockArgs(ThreadContext context, Block block, IRubyObject[] args) {
public static IRubyObject[] prepareFixedBlockArgs(ThreadContext context, Block block, IRubyObject[] args) {
if (args == null) {
args = IRubyObject.NULL_ARRAY;
}

boolean isProcCall = context.getCurrentBlockType() == Block.Type.PROC;
org.jruby.runtime.Signature sig = block.getBody().getSignature();
if (block.type == Block.Type.LAMBDA) {
block.getBody().getSignature().checkArity(context.runtime, args);
} else if (context.getCurrentBlockType() == Block.Type.PROC) {
// Deal with proc calls
if (args.length == 0) {
args = context.runtime.getSingleNilArray();
} else if (args.length == 1) {
args = prepareProcArgs(context, block, args);
} else {
args = new IRubyObject[] { args[0] };
// We don't need to check for the 1 required arg case here
// since that goes down the prepareSingleBlockArgs route
if (!isProcCall && sig.arityValue() != 1) {
args = toAry(context, args);
}
sig.checkArity(context.runtime, args);
return args;
}

if (isProcCall) {
return prepareProcArgs(context, block, args);
}

// Nothing more to do! Hurray!
// If we need more than 1 reqd arg, convert a single value to an array if possible.
// If there are insufficient args, ReceivePreReqdInstr will return nil
return toAry(context, args);
}

// This is the placeholder for scenarios not handled by specialized instructions.
@Interp @JIT
public static IRubyObject[] prepareBlockArgs(ThreadContext context, Block block, IRubyObject[] args, boolean usesKwArgs) {
args = prepareBlockArgsInternal(context, block, args);
if (usesKwArgs) {
frobnicateKwargsArgument(context, block.getBody().getSignature().required(), args);
}
return args;
}

0 comments on commit dd8f220

Please sign in to comment.