// do the work for `lua_resume' in protected mode private void Resume(int firstArg) { int numCSharpCalls = NumCSharpCalls; CallInfo ci = CI; if (numCSharpCalls >= LuaLimits.LUAI_MAXCCALLS) { ResumeError("C stack overflow", firstArg); } if (Status == ThreadStatus.LUA_OK) // may be starting a coroutine { if (ci.Index > 0) // not in base level { ResumeError("cannot resume non-suspended coroutine", firstArg); } if (!D_PreCall(Stack[firstArg - 1], LuaDef.LUA_MULTRET)) // Lua function? { V_Execute(); // call it } } else if (Status != ThreadStatus.LUA_YIELD) { ResumeError("cannot resume dead coroutine", firstArg); } else // resume from previous yield { Status = ThreadStatus.LUA_OK; ci.FuncIndex = ci.ExtraIndex; if (ci.IsLua) // yielded inside a hook? { V_Execute(); // just continue running Lua code } else // `common' yield { if (ci.ContinueFunc != null) { ci.Status = ThreadStatus.LUA_YIELD; // `default' status ci.CallStatus |= CallStatus.CIST_YIELDED; int n = ci.ContinueFunc(this); // call continuation Utl.ApiCheckNumElems(this, n); firstArg = Top.Index - n; // yield results come from continuation } D_PosCall(firstArg); } Unroll(); } Utl.Assert(numCSharpCalls == NumCSharpCalls); }
private void FinishCSharpCall() { CallInfo ci = CI; Utl.Assert(ci.ContinueFunc != null); // must have a continuation Utl.Assert(NumNonYieldable == 0); // finish `CallK' AdjustResults(ci.NumResults); // call continuation function if ((ci.CallStatus & CallStatus.CIST_STAT) == 0) // no call status? { ci.Status = ThreadStatus.LUA_YIELD; // `default' status } Utl.Assert(ci.Status != ThreadStatus.LUA_OK); ci.CallStatus = (ci.CallStatus & ~(CallStatus.CIST_YPCALL | CallStatus.CIST_STAT)) | CallStatus.CIST_YIELDED; int n = ci.ContinueFunc(this); // call Utl.ApiCheckNumElems(this, n); // finish `D_PreCall' D_PosCall(Top.Index - n); }