public static void compileToArray(Expression[] args, Compilation comp) { CodeAttr code = comp.getCode(); if (args.length == 0) { code.emitGetStatic(Compilation.noArgsField); return; } code.emitPushInt(args.length); code.emitNewArray(Type.pointer_type); for (int i = 0; i < args.length; ++i) { Expression arg = args[i]; if (comp.usingCPStyle() && !(arg instanceof QuoteExp) && !(arg instanceof ReferenceExp)) { // If the argument involves a CPStyle function call, we will // have to save and restore anything on the JVM stack into // fields in the CallFrame. This is expensive, so defer // pushing the duplicated argument array and the index // until *after* we've calculated the argument. The downside // is that we have to do some extra stack operations. // However, these are cheap (and get compiled away when // compiling to native code). arg.compileWithPosition(comp, Target.pushObject); code.emitSwap(); code.emitDup(1, 1); code.emitSwap(); code.emitPushInt(i); code.emitSwap(); } else { code.emitDup(Compilation.objArrayType); code.emitPushInt(i); arg.compileWithPosition(comp, Target.pushObject); } code.emitArrayStore(Type.pointer_type); } }
/** Only used for inline- and tail-calls. */ private static void pushArgs( LambdaExp lexp, Expression[] args, int[] incValues, Compilation comp) { Declaration param = lexp.firstDecl(); int args_length = args.length; for (int i = 0; i < args_length; ++i) { Expression arg = args[i]; if (param.ignorable()) arg.compile(comp, Target.Ignore); else if (incValues != null && (incValues[i] = SetExp.canUseInc(arg, param)) != SetExp.BAD_SHORT) ; else arg.compileWithPosition(comp, StackTarget.getInstance(param.getType())); param = param.nextDecl(); } }