private static int PrepFuncCall(FuncInfo fi, FuncCallExp node, int a) { var nArgs = node.Args?.Count ?? 0; var lastArgIsVarargsOrFuncCall = false; CgExp(fi, node.PrefixExp, a, 1); if (node.NameExp != null) { fi.IndexOfConstant(node.NameExp.Str, out var idx); var c = 0x100 + idx; fi.EmitSelf(a, a, c); } for (var i = 0; i < nArgs; i++) { var arg = node.Args[i]; var tmp = fi.AllocReg(); if (i == nArgs - 1 && IsVarargOrFuncCall(arg)) { lastArgIsVarargsOrFuncCall = true; CgExp(fi, arg, tmp, -1); } else { CgExp(fi, arg, tmp, 1); } } fi.FreeRegs(nArgs); if (node.NameExp != null) { nArgs++; } if (lastArgIsVarargsOrFuncCall) { nArgs = -1; } return(nArgs); }
private static void CgTailCallExp(FuncInfo fi, FuncCallExp node, int a) { var nArgs = PrepFuncCall(fi, node, a); fi.EmitTailCall(a, nArgs); }
private static void CgFuncCallExp(FuncInfo fi, FuncCallExp node, int a, int n) { var nArgs = PrepFuncCall(fi, node, a); fi.EmitCall(a, nArgs, n); }