Example #1
0
        // Resets [fiber] back to an initial state where it is ready to invoke [fn].
        private void ResetFiber(Obj fn)
        {
            Stack = new Obj[InitialStackSize];
            Capacity = InitialStackSize;
            Frames = new List<CallFrame>();

            // Push the stack frame for the function.
            StackTop = 0;
            NumFrames = 1;
            OpenUpvalues = null;
            Caller = null;
            Error = null;
            CallerIsTrying = false;

            CallFrame frame = new CallFrame { Fn = fn, StackStart = 0, Ip = 0 };
            Frames.Add(frame);
        }
Example #2
0
        // Captures the local variable [local] into an [Upvalue]. If that local is
        // already in an upvalue, the existing one will be used. (This is important to
        // ensure that multiple closures closing over the same variable actually see
        // the same variable.) Otherwise, it will create a new open upvalue and add it
        // the fiber's list of upvalues.
        public ObjUpvalue CaptureUpvalue(int index)
        {
            // If there are no open upvalues at all, we must need a new one.
            if (OpenUpvalues == null)
            {
                OpenUpvalues = new ObjUpvalue(Stack[index], index);
                return OpenUpvalues;
            }

            ObjUpvalue prevUpvalue = null;
            ObjUpvalue upvalue = OpenUpvalues;

            // Walk towards the bottom of the stack until we find a previously existing
            // upvalue or pass where it should be.
            while (upvalue != null && upvalue.Index > index)
            {
                prevUpvalue = upvalue;
                upvalue = upvalue.Next;
            }

            // Found an existing upvalue for this local.
            if (upvalue != null && upvalue.Index == index) return upvalue;

            // We've walked past this local on the stack, so there must not be an
            // upvalue for it already. Make a new one and link it in in the right
            // place to keep the list sorted.
            ObjUpvalue createdUpvalue = new ObjUpvalue(Stack[index], index);
            if (prevUpvalue == null)
            {
                // The new one is the first one in the list.
                OpenUpvalues = createdUpvalue;
            }
            else
            {
                prevUpvalue.Next = createdUpvalue;
            }

            createdUpvalue.Next = upvalue;
            return createdUpvalue;
        }
Example #3
0
        public void CloseUpvalue()
        {
            if (OpenUpvalues == null)
                return;

            // Push the value back into the stack
            Stack[OpenUpvalues.Index] = OpenUpvalues.Container;

            // Remove it from the open upvalue list.
            OpenUpvalues = OpenUpvalues.Next;
        }