boolean fittingAdapter = adapter == invokeMethodOnCurrent ||
adapter == invokeStaticMethod;
if (fittingAdapter && controller.optimizeForInt && controller.isFastPath()) {
String methodName = getMethodName(message);
if (methodName != null) {
TupleExpression args;
if (arguments instanceof TupleExpression) {
args = (TupleExpression) arguments;
} else {
args = new TupleExpression(receiver);
}
StatementMeta meta = null;
if (origin!=null) meta = (StatementMeta) origin.getNodeMetaData(StatementMeta.class);
MethodNode mn = null;
if (meta!=null) mn = meta.target;
if (writeDirectMethodCall(mn, true, null, args)) return;
}
}
boolean containsSpreadExpression = AsmClassGenerator.containsSpreadExpression(arguments);
if (!containsSpreadExpression && origin instanceof MethodCallExpression) {
MethodCallExpression mce = (MethodCallExpression) origin;
MethodNode target = mce.getMethodTarget();
if (writeDirectMethodCall(target, implicitThis, receiver, makeArgumentList(arguments))) return;
}
// prepare call site
if ((adapter == invokeMethod || adapter == invokeMethodOnCurrent || adapter == invokeStaticMethod) && !spreadSafe) {
String methodName = getMethodName(message);
if (methodName != null) {
controller.getCallSiteWriter().makeCallSite(
receiver, methodName, arguments, safe, implicitThis,
adapter == invokeMethodOnCurrent,
adapter == invokeStaticMethod);
return;
}
}
OperandStack operandStack = controller.getOperandStack();
CompileStack compileStack = controller.getCompileStack();
AsmClassGenerator acg = controller.getAcg();
// ensure VariableArguments are read, not stored
compileStack.pushLHS(false);
// sender only for call sites
if (adapter == AsmClassGenerator.setProperty) {
ConstantExpression.NULL.visit(acg);
} else {
sender.visit(acg);
}
// receiver
compileStack.pushImplicitThis(implicitThis);
receiver.visit(acg);
operandStack.box();
compileStack.popImplicitThis();
int operandsToRemove = 2;
// message
if (message != null) {
message.visit(acg);
operandStack.box();
operandsToRemove++;
}
// arguments
int numberOfArguments = containsSpreadExpression ? -1 : AsmClassGenerator.argumentSize(arguments);
if (numberOfArguments > MethodCallerMultiAdapter.MAX_ARGS || containsSpreadExpression) {
ArgumentListExpression ae = makeArgumentList(arguments);
if (containsSpreadExpression) {
acg.despreadList(ae.getExpressions(), true);
} else {
ae.visit(acg);
}
} else if (numberOfArguments > 0) {
operandsToRemove += numberOfArguments;
TupleExpression te = (TupleExpression) arguments;
for (int i = 0; i < numberOfArguments; i++) {
Expression argument = te.getExpression(i);
argument.visit(acg);
operandStack.box();
if (argument instanceof CastExpression) acg.loadWrapper(argument);
}
}