Пример #1
0
        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);
        }