Ejemplo n.º 1
0
 private static void FreeReg(FuncState fs, int reg)
 {
     if (!Instruction.ISK(reg) && reg >= fs.NumActVar)
     {
         fs.FreeReg--;
         Utl.Assert(reg == fs.FreeReg);
     }
 }
Ejemplo n.º 2
0
        ThreadStatus ILuaAPI.PCallK(int numArgs, int numResults, int errFunc,
                                    int context, CSharpFunctionDelegate continueFunc)
        {
            Utl.ApiCheck(continueFunc == null || !CI.IsLua,
                         "cannot use continuations inside hooks");
            Utl.ApiCheckNumElems(this, numArgs + 1);
            Utl.ApiCheck(Status == ThreadStatus.LUA_OK,
                         "cannot do calls on non-normal thread");
            CheckResults(numArgs, numResults);

            int func;

            if (errFunc == 0)
            {
                func = 0;
            }
            else
            {
                StkId addr;
                if (!Index2Addr(errFunc, out addr))
                {
                    Utl.InvalidIndex();
                }

                func = addr.Index;
            }

            ThreadStatus status;
            CallS        c = new CallS();

            c.L         = this;
            c.FuncIndex = Top.Index - (numArgs + 1);
            if (continueFunc == null || NumNonYieldable > 0) // no continuation or no yieldable?
            {
                c.NumResults = numResults;
                status       = D_PCall(DG_F_Call, ref c, c.FuncIndex, func);
            }
            else
            {
                int ciIndex = CI.Index;
                CI.ContinueFunc = continueFunc;
                CI.Context      = context;
                CI.ExtraIndex   = c.FuncIndex;
                CI.OldAllowHook = AllowHook;
                CI.OldErrFunc   = ErrFunc;
                ErrFunc         = func;
                CI.CallStatus  |= CallStatus.CIST_YPCALL;

                D_Call(Stack[c.FuncIndex], numResults, true);

                CallInfo ci = BaseCI[ciIndex];
                ci.CallStatus &= ~CallStatus.CIST_YPCALL;
                ErrFunc        = ci.OldErrFunc;
                status         = ThreadStatus.LUA_OK;
            }
            AdjustResults(numResults);
            return(status);
        }
Ejemplo n.º 3
0
        private StkId NewTableKey(ref TValue k)
        {
            if (k.TtIsNil())
            {
                L.G_RunError("table index is nil");
            }

            if (k.TtIsNumber() && System.Double.IsNaN(k.NValue))
            {
                L.G_RunError("table index is NaN");
            }

            var mp = GetHashNode(ref k);

            // if main position is taken
            if (!mp.Val.V.TtIsNil() || mp == DummyNode)
            {
                var n = GetFreePos();
                if (n == null)
                {
                    Rehash(ref k);
                    var cell = Get(ref k);
                    if (cell != TheNilValue)
                    {
                        return(cell);
                    }

                    return(NewTableKey(ref k));
                }

                Utl.Assert(n != DummyNode);
                var othern = GetHashNode(ref mp.Key.V);
                // is colliding node out of its main position?
                if (othern != mp)
                {
                    while (othern.Next != mp)
                    {
                        othern = othern.Next;
                    }

                    othern.Next = n;
                    n.CopyFrom(mp);
                    mp.Next = null;
                    mp.Val.V.SetNilValue();
                }
                // colliding node is in its own main position
                else
                {
                    n.Next  = mp.Next;
                    mp.Next = n;
                    mp      = n;
                }
            }

            mp.Key.V.SetObj(ref k);
            Utl.Assert(mp.Val.V.TtIsNil());
            return(mp.Val);
        }
Ejemplo n.º 4
0
        private static void InvertJump(FuncState fs, ExpDesc e)
        {
            InstructionPtr pc = GetJumpControl(fs, e.Info);

            Utl.Assert(TestTMode(pc.Value.GET_OPCODE()) &&
                       pc.Value.GET_OPCODE() != OpCode.OP_TESTSET &&
                       pc.Value.GET_OPCODE() != OpCode.OP_TEST);
            pc.Value = pc.Value.SETARG_A(pc.Value.GETARG_A() == 0 ? 1 : 0);
        }
Ejemplo n.º 5
0
        private static void Discharge2Reg(FuncState fs, ExpDesc e, int reg)
        {
            DischargeVars(fs, e);
            switch (e.Kind)
            {
            case ExpKind.VNIL:
            {
                CodeNil(fs, reg, 1);
                break;
            }

            case ExpKind.VFALSE:
            case ExpKind.VTRUE:
            {
                CodeABC(fs, OpCode.OP_LOADBOOL, reg,
                        (e.Kind == ExpKind.VTRUE ? 1 : 0), 0);
                break;
            }

            case ExpKind.VK:
            {
                CodeK(fs, reg, e.Info);
                break;
            }

            case ExpKind.VKNUM:
            {
                CodeK(fs, reg, NumberK(fs, e.NumberValue));
                break;
            }

            case ExpKind.VRELOCABLE:
            {
                InstructionPtr pi = fs.GetCode(e);
                pi.Value = pi.Value.SETARG_A(reg);
                break;
            }

            case ExpKind.VNONRELOC:
            {
                if (reg != e.Info)
                {
                    CodeABC(fs, OpCode.OP_MOVE, reg, e.Info, 0);
                }
                break;
            }

            default:
            {
                Utl.Assert(e.Kind == ExpKind.VVOID || e.Kind == ExpKind.VJMP);
                return;         // nothing to do...
            }
            }
            e.Info = reg;
            e.Kind = ExpKind.VNONRELOC;
        }
Ejemplo n.º 6
0
        private void V_GetTable(StkId t, StkId key, StkId val)
        {
            for (int loop = 0; loop < MAXTAGLOOP; ++loop)
            {
                StkId tmObj;
                if (t.V.TtIsTable())
                {
                    var tbl = t.V.HValue();
                    var res = tbl.Get(ref key.V);
                    if (!res.V.TtIsNil())
                    {
                        val.V.SetObj(ref res.V);
                        return;
                    }

                    tmObj = FastTM(tbl.MetaTable, TMS.TM_INDEX);
                    if (tmObj == null)
                    {
                        val.V.SetObj(ref res.V);
                        return;
                    }
                }
                else if (t.V.Tt == (int)LuaType.LUA_TLIGHTUSERDATA)
                {
                    TValue res;
                    if (Utl.GetLightUserDataPropValue(t.V, key.V, out res))
                    {
                        val.V.SetObj(ref res);
                    }
                    else
                    {
                        G_RunError(res.SValue());
                    }
                    return;

                    // else will try the tag method
                }
                else
                {
                    tmObj = T_GetTMByObj(ref t.V, TMS.TM_INDEX);
                    if (tmObj.V.TtIsNil())
                    {
                        G_SimpleTypeError(ref t.V, "index");
                    }
                }

                if (tmObj.V.TtIsFunction())
                {
                    CallTM(ref tmObj.V, ref t.V, ref key.V, val, true);
                    return;
                }

                t = tmObj;
            }
            G_RunError("loop in gettable");
        }
Ejemplo n.º 7
0
        void ILuaAPI.Copy(int fromIndex, int toIndex)
        {
            StkId fr;

            if (!Index2Addr(fromIndex, out fr))
            {
                Utl.InvalidIndex();
            }
            MoveTo(fr, toIndex);
        }
Ejemplo n.º 8
0
        public static int CodeABx(FuncState fs, OpCode op, int a, uint bc)
        {
            var mode = OpCodeInfo.GetMode(op);

            Utl.Assert(mode.OpMode == OpMode.iABx ||
                       mode.OpMode == OpMode.iAsBx);
            Utl.Assert(mode.CMode == OpArgMask.OpArgN);
            Utl.Assert(a < Instruction.MAXARG_A & bc <= Instruction.MAXARG_Bx);
            return(Code(fs, Instruction.CreateABx(op, a, bc)));
        }
Ejemplo n.º 9
0
        private void V_Concat(int total)
        {
            Utl.Assert(total >= 2);

            do
            {
                var top = Top;
                int n   = 2;
                var lhs = Stack[top.Index - 2];
                var rhs = Stack[top.Index - 1];
                if (!(lhs.V.TtIsString() || lhs.V.TtIsNumber()) || !ToString(ref rhs.V))
                {
                    if (!CallBinTM(lhs, rhs, lhs, TMS.TM_CONCAT))
                    {
                        G_ConcatError(lhs, rhs);
                    }
                }
                else if (rhs.V.SValue().Length == 0)
                {
                    ToString(ref lhs.V);
                }
                else if (lhs.V.TtIsString() && lhs.V.SValue().Length == 0)
                {
                    lhs.V.SetObj(ref rhs.V);
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    n = 0;
                    for ( ; n < total; ++n)
                    {
                        var cur = Stack[top.Index - (n + 1)];

                        if (cur.V.TtIsString())
                        {
                            sb.Insert(0, cur.V.SValue());
                        }
                        else if (cur.V.TtIsNumber())
                        {
                            sb.Insert(0, cur.V.NValue.ToString());
                        }
                        else
                        {
                            break;
                        }
                    }

                    var dest = Stack[top.Index - n];
                    dest.V.SetSValue(sb.ToString());
                }
                total -= n - 1;
                Top    = Stack[Top.Index - (n - 1)];
            } while(total > 1);
        }
Ejemplo n.º 10
0
        private void MoveTo(StkId fr, int index)
        {
            StkId to;

            if (!Index2Addr(index, out to))
            {
                Utl.InvalidIndex();
            }

            to.V.SetObj(ref fr.V);
        }
Ejemplo n.º 11
0
        private bool Index2Addr(int index, out StkId addr)
        {
            CallInfo ci = CI;

            if (index > 0)
            {
                var addrIndex = ci.FuncIndex + index;
                Utl.ApiCheck(index <= ci.TopIndex - (ci.FuncIndex + 1), "unacceptable index");
                if (addrIndex >= Top.Index)
                {
                    addr = default(StkId);
                    return(false);
                }

                addr = Stack[addrIndex];
                return(true);
            }
            else if (index > LuaDef.LUA_REGISTRYINDEX)
            {
                Utl.ApiCheck(index != 0 && -index <= Top.Index - (ci.FuncIndex + 1), "invalid index");
                addr = Stack[Top.Index + index];
                return(true);
            }
            else if (index == LuaDef.LUA_REGISTRYINDEX)
            {
                addr = G.Registry;
                return(true);
            }
            // upvalues
            else
            {
                index = LuaDef.LUA_REGISTRYINDEX - index;
                Utl.ApiCheck(index <= LuaLimits.MAXUPVAL + 1, "upvalue index too large");
                var func = Stack[ci.FuncIndex];
                Utl.Assert(func.V.TtIsFunction());

                if (func.V.ClIsLcsClosure())
                {
                    addr = default(StkId);
                    return(false);
                }

                Utl.Assert(func.V.ClIsCsClosure());
                var clcs = func.V.ClCsValue();
                if (index > clcs.Upvals.Length)
                {
                    addr = default(StkId);
                    return(false);
                }

                addr = clcs.Upvals[index - 1];
                return(true);
            }
        }
Ejemplo n.º 12
0
 public static void PatchList(FuncState fs, int list, int target)
 {
     if (target == fs.Pc)
     {
         PatchToHere(fs, list);
     }
     else
     {
         Utl.Assert(target < fs.Pc);
         PatchListAux(fs, list, target, NO_REG, target);
     }
 }
Ejemplo n.º 13
0
        private int CeilLog2(int x)
        {
            Utl.Assert(x > 0);
            int l = 0;

            x--;
            while (x >= 256)
            {
                l += 8; x >>= 8;
            }
            return(l + Log2_[x]);
        }
Ejemplo n.º 14
0
        void ILuaAPI.PushValue(int index)
        {
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            Top.V.SetObj(ref addr.V);
            ApiIncrTop();
        }
Ejemplo n.º 15
0
        void ILuaAPI.SetField(int index, string key)
        {
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            StkId.inc(ref Top).V.SetSValue(key);
            V_SetTable(addr, Stack[Top.Index - 1], Stack[Top.Index - 2]);
            Top = Stack[Top.Index - 2];
        }
Ejemplo n.º 16
0
        void ILuaAPI.GetTable(int index)
        {
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            var below = Stack[Top.Index - 1];

            V_GetTable(addr, below, below);
        }
Ejemplo n.º 17
0
 void ILuaAPI.Concat(int n)
 {
     Utl.ApiCheckNumElems(this, n);
     if (n >= 2)
     {
         V_Concat(n);
     }
     else if (n == 0)
     {
         Top.V.SetSValue("");
         ApiIncrTop();
     }
 }
Ejemplo n.º 18
0
        void ILuaAPI.Len(int index)
        {
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            V_ObjLen(Top, addr);

            ApiIncrTop();
        }
Ejemplo n.º 19
0
        private static void FixJump(FuncState fs, int pc, int dest)
        {
            Instruction jmp    = fs.Proto.Code[pc];
            int         offset = dest - (pc + 1);

            Utl.Assert(dest != NO_JUMP);
            if (Math.Abs(offset) > Instruction.MAXARG_sBx)
            {
                fs.Lexer.SyntaxError("control structure too long");
            }
            jmp.SETARG_sBx(offset);
            fs.Proto.Code[pc] = jmp;
        }
Ejemplo n.º 20
0
 public static void PatchClose(FuncState fs, int list, int level)
 {
     level++;             // argument is +1 to reserve 0 as non-op
     while (list != NO_JUMP)
     {
         int next = GetJump(fs, list);
         var pi   = new InstructionPtr(fs.Proto.Code, list);;
         Utl.Assert(pi.Value.GET_OPCODE() == OpCode.OP_JMP &&
                    (pi.Value.GETARG_A() == 0 ||
                     pi.Value.GETARG_A() >= level));
         pi.Value = pi.Value.SETARG_A(level);
         list     = next;
     }
 }
Ejemplo n.º 21
0
        bool ILuaAPI.SetMetaTable(int index)
        {
            Utl.ApiCheckNumElems(this, 1);

            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            var      below = Stack[Top.Index - 1];
            LuaTable mt;

            if (below.V.TtIsNil())
            {
                mt = null;
            }
            else
            {
                Utl.ApiCheck(below.V.TtIsTable(), "table expected");
                mt = below.V.HValue();
            }

            switch (addr.V.Tt)
            {
            case (int)LuaType.LUA_TTABLE:
            {
                var tbl = addr.V.HValue();
                tbl.MetaTable = mt;
                break;
            }

            case (int)LuaType.LUA_TUSERDATA:
            {
                var ud = addr.V.RawUValue();
                ud.MetaTable = mt;
                break;
            }

            default:
            {
                G.MetaTables[addr.V.Tt] = mt;
                break;
            }
            }
            Top = Stack[Top.Index - 1];
            return(true);
        }
Ejemplo n.º 22
0
        private static bool ConstFolding(OpCode op, ExpDesc e1, ExpDesc e2)
        {
            if (!IsNumeral(e1) || !IsNumeral(e2))
            {
                return(false);
            }

            if ((op == OpCode.OP_DIV || op == OpCode.OP_MOD) &&
                e2.NumberValue == 0.0)
            {
                return(false);                // do not attempt to divide by 0
            }

            switch (op)
            {
            case OpCode.OP_ADD:
                e1.NumberValue = e1.NumberValue + e2.NumberValue;
                break;

            case OpCode.OP_SUB:
                e1.NumberValue = e1.NumberValue - e2.NumberValue;
                break;

            case OpCode.OP_MUL:
                e1.NumberValue = e1.NumberValue * e2.NumberValue;
                break;

            case OpCode.OP_DIV:
                e1.NumberValue = e1.NumberValue / e2.NumberValue;
                break;

            case OpCode.OP_MOD:
                e1.NumberValue = Utl.LuaMod(e1.NumberValue, e2.NumberValue);
                break;

            case OpCode.OP_POW:
                e1.NumberValue = Math.Pow(e1.NumberValue, e2.NumberValue);
                break;

            case OpCode.OP_UNM:
                e1.NumberValue = -e1.NumberValue;
                break;

            default:
                throw new Exception("ConstFolding unknown op" + op);
            }

            return(true);
        }
Ejemplo n.º 23
0
        void ILuaAPI.RawSet(int index)
        {
            Utl.ApiCheckNumElems(this, 2);
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }
            Utl.ApiCheck(addr.V.TtIsTable(), "table expected");
            var tbl = addr.V.HValue();

            tbl.Set(ref Stack[Top.Index - 2].V, ref Stack[Top.Index - 1].V);
            Top = Stack[Top.Index - 2];
        }
Ejemplo n.º 24
0
        public void RawSetI(int index, int n)
        {
            Utl.ApiCheckNumElems(this, 1);
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }
            Utl.ApiCheck(addr.V.TtIsTable(), "table expected");
            var tbl = addr.V.HValue();

            tbl.SetInt(n, ref Stack[Top.Index - 1].V);
            Top = Stack[Top.Index - 1];
        }
Ejemplo n.º 25
0
        void ILuaAPI.GetField(int index, string key)
        {
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            Top.V.SetSValue(key);
            var below = Top;

            ApiIncrTop();
            V_GetTable(addr, below, below);
        }
Ejemplo n.º 26
0
        private double _ReadNumber()
        {
            var expo = new char[] { 'E', 'e' };

            Utl.Assert(_CurrentIsDigit());
            var first = Current;

            _SaveAndNext();
            if (first == '0' && (Current == 'X' || Current == 'x'))
            {
                expo = new char[] { 'P', 'p' };
                _SaveAndNext();
            }

            for (;;)
            {
                if (Current == expo[0] || Current == expo[1])
                {
                    _SaveAndNext();
                    if (Current == '+' || Current == '-')
                    {
                        _SaveAndNext();
                    }
                }

                if (_CurrentIsXDigit() || Current == '.')
                {
                    _SaveAndNext();
                }
                else
                {
                    break;
                }
            }

            double ret;
            var    str = _GetSavedString();

            if (LuaState.O_Str2Decimal(str, out ret))
            {
                return(ret);
            }
            else
            {
                _Error("malformed number: " + str);
                return(0.0);
            }
        }
Ejemplo n.º 27
0
        // 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);
        }
Ejemplo n.º 28
0
        void ILuaAPI.RawGetI(int index, int n)
        {
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.ApiCheck(false, "table expected");
            }

            var tbl = addr.V.HValue();

            Utl.ApiCheck(tbl != null, "table expected");

            Top.V.SetObj(ref tbl.GetInt(n).V);
            ApiIncrTop();
        }
Ejemplo n.º 29
0
        void ILuaAPI.SetTable(int index)
        {
            StkId addr;

            Utl.ApiCheckNumElems(this, 2);
            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            var key = Stack[Top.Index - 2];
            var val = Stack[Top.Index - 1];

            V_SetTable(addr, key, val);
            Top = Stack[Top.Index - 2];
        }
Ejemplo n.º 30
0
        void ILuaAPI.Remove(int index)
        {
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            for (int i = addr.Index + 1; i < Top.Index; ++i)
            {
                Stack[i - 1].V.SetObj(ref Stack[i].V);
            }

            Top = Stack[Top.Index - 1];
        }