internal void SetClCsValue(LuaCsClosureValue v) { #if DEBUG_DUMMY_TVALUE_MODIFY CheckLock(); #endif Tt = (int)LuaType.LUA_TFUNCTION; OValue = v; }
void ILuaAPI.PushCSharpClosure(CSharpFunctionDelegate f, int n) { if (n == 0) { Top.V.SetClCsValue(new LuaCsClosureValue(f)); } else { // 带 UpValue 的 C# function Utl.ApiCheckNumElems(this, n); Utl.ApiCheck(n <= LuaLimits.MAXUPVAL, "upvalue index too large"); LuaCsClosureValue cscl = new LuaCsClosureValue(f, n); int index = Top.Index - n; Top = Stack[index]; for (int i = 0; i < n; ++i) { cscl.Upvals[i].V.SetObj(ref Stack[index + i].V); } Top.V.SetClCsValue(cscl); } ApiIncrTop(); }
internal void SetClCsValue(LuaCsClosureValue v) { #if DEBUG_DUMMY_TVALUE_MODIFY CheckLock(); #endif Tt = (int)LuaType.LUA_TFUNCTION; NValue = 0.0; UInt64Value = CLOSURE_CS; OValue = v; }
void ILuaAPI.PushCSharpClosure( CSharpFunctionDelegate f, int n ) { if( n == 0 ) { Top.V.SetClCsValue( new LuaCsClosureValue( f ) ); } else { // 带 UpValue 的 C# function Utl.ApiCheckNumElems( this, n ); Utl.ApiCheck( n <= LuaLimits.MAXUPVAL, "upvalue index too large" ); LuaCsClosureValue cscl = new LuaCsClosureValue( f, n ); int index = Top.Index - n; Top = Stack[index]; for(int i=0; i<n; ++i) { cscl.Upvals[i].V.SetObj( ref Stack[index+i].V ); } Top.V.SetClCsValue( cscl ); } ApiIncrTop(); }
/// <summary> /// return true if function has been executed /// </summary> private bool D_PreCall(StkId func, int nResults) { // prepare for Lua call #if DEBUG_D_PRE_CALL ULDebug.Log("============================ D_PreCall func:" + func); #endif int funcIndex = func.Index; if (!func.V.TtIsFunction()) { // not a function // retry with `function' tag method func = tryFuncTM(func); // now it must be a function return(D_PreCall(func, nResults)); } if (func.V.ClIsLuaClosure()) { LuaLClosureValue cl = func.V.ClLValue(); Utl.Assert(cl != null); LuaProto p = cl.Proto; D_CheckStack(p.MaxStackSize + p.NumParams); func = Stack[funcIndex]; // 补全参数 int n = (Top.Index - func.Index) - 1; for ( ; n < p.NumParams; ++n) { StkId.inc(ref Top).V.SetNilValue(); } int stackBase = (!p.IsVarArg) ? (func.Index + 1) : AdjustVarargs(p, n); CI = ExtendCI(); CI.NumResults = nResults; CI.FuncIndex = func.Index; CI.BaseIndex = stackBase; CI.TopIndex = stackBase + p.MaxStackSize; Utl.Assert(CI.TopIndex <= StackLast); CI.SavedPc = new InstructionPtr(p.Code, 0); CI.CallStatus = CallStatus.CIST_LUA; Top = Stack[CI.TopIndex]; return(false); } if (func.V.ClIsCsClosure()) { LuaCsClosureValue cscl = func.V.ClCsValue(); Utl.Assert(cscl != null); D_CheckStack(LuaDef.LUA_MINSTACK); func = Stack[funcIndex]; CI = ExtendCI(); CI.NumResults = nResults; CI.FuncIndex = func.Index; CI.TopIndex = Top.Index + LuaDef.LUA_MINSTACK; CI.CallStatus = CallStatus.CIST_NONE; // do the actual call int n = cscl.F(this); // poscall D_PosCall(Top.Index - n); return(true); } throw new System.NotImplementedException(); }
private int AuxGetInfo(string what, LuaDebug ar, StkId func, CallInfo ci) { int status = 1; for (int i = 0; i < what.Length; ++i) { char c = what[i]; switch (c) { case 'S': { FuncInfo(ar, func); break; } case 'l': { ar.CurrentLine = (ci != null && ci.IsLua) ? GetCurrentLine(ci) : -1; break; } case 'u': { Utl.Assert(func.V.TtIsFunction()); if (func.V.ClIsLuaClosure()) { LuaLClosureValue lcl = func.V.ClLValue(); ar.NumUps = lcl.Upvals.Length; ar.IsVarArg = lcl.Proto.IsVarArg; ar.NumParams = lcl.Proto.NumParams; } else if (func.V.ClIsCsClosure()) { LuaCsClosureValue ccl = func.V.ClCsValue(); ar.NumUps = ccl.Upvals.Length; ar.IsVarArg = true; ar.NumParams = 0; } else { throw new System.NotImplementedException(); } break; } case 't': { ar.IsTailCall = (ci != null) ? ((ci.CallStatus & CallStatus.CIST_TAIL) != 0) : false; break; } case 'n': { CallInfo prevCI = BaseCI[ci.Index - 1]; if (ci != null && ((ci.CallStatus & CallStatus.CIST_TAIL) == 0) && prevCI.IsLua) { ar.NameWhat = GetFuncName(prevCI, out ar.Name); } else { ar.NameWhat = null; } if (ar.NameWhat == null) { ar.NameWhat = ""; // not found ar.Name = null; } break; } case 'L': case 'f': // handled by GetInfo break; default: status = 0; // invalid option break; } } return(status); }