internal override void Resume(LuaThread thread) { // Pop frame off the stack. Frame frame = thread.UnwoundFrames[thread.UnwoundFrames.Count - 1]; thread.UnwoundFrames.RemoveAt(thread.UnwoundFrames.Count - 1); // Recover frame information. int frameBase = frame.FrameBase; int resultCount = frame.ResultCount; int fp = frame.FramePointer; int ip = frame.InstructionPointer; // Resume the next suspended frame. try { Instruction i = prototype.Instructions[ip - 1]; switch (i.Opcode) { case Opcode.Call: { // Resume function. LuaValue function = thread.Stack[fp + i.A]; function.Resume(thread); if (thread.UnwoundFrames.Count > 0) { thread.UnwoundFrames.Add(new Frame(frameBase, resultCount, fp, ip)); return; } if (i.C != 0) { thread.StackWatermark(fp + prototype.StackSize); } else { thread.StackWatermark(Math.Max(fp + prototype.StackSize, thread.Top + 1)); } break; } default: throw new InvalidOperationException(); } } catch (Exception e) { thread.UnwoundFrames.Add(new Frame(frameBase, resultCount, fp, ip)); throw e; } // Returned normally, dispatch the rest of the function. Dispatch(thread, frameBase, resultCount, fp, ip); }