예제 #1
0
        public static void LuaReplace(LuaState L, int idx)
        {
            StkId o;

            LuaLock(L);
            /* explicit test for incompatible code */
            if (idx == LUA_ENVIRONINDEX && L.ci == L.base_ci[0])
            {
                LuaGRunError(L, "no calling environment");
            }
            CheckNElements(L, 1);
            o = Index2Address(L, idx);
            CheckValidIndex(L, o);
            if (idx == LUA_ENVIRONINDEX)
            {
                Closure func = CurrFunc(L);
                ApiCheck(L, TTIsTable(L.top - 1));
                func.c.env = HValue(L.top - 1);
                LuaCBarrier(L, func, L.top - 1);
            }
            else
            {
                SetObj(L, o, L.top - 1);
                if (idx < LUA_GLOBALSINDEX)          /* function upvalue? */
                {
                    LuaCBarrier(L, CurrFunc(L), L.top - 1);
                }
            }
            StkId.Dec(ref L.top);
            LuaUnlock(L);
        }
예제 #2
0
        private static Proto LoadFunction(LoadState S, TString p)
        {
            Proto f;

            if (++S.L.nCcalls > LUAI_MAXCCALLS)
            {
                error(S, "code too deep");
            }
            f = LuaFNewProto(S.L);
            SetPTValue2S(S.L, S.L.top, f); IncrTop(S.L);
            f.source = LoadString(S); if (f.source == null)
            {
                f.source = p;
            }
            f.linedefined     = LoadInt(S);
            f.lastlinedefined = LoadInt(S);
            f.nups            = LoadByte(S);
            f.numparams       = LoadByte(S);
            f.is_vararg       = LoadByte(S);
            f.maxstacksize    = LoadByte(S);
            LoadCode(S, f);
            LoadConstants(S, f);
            LoadDebug(S, f);
            IF(LuaGCheckCode(f) == 0 ? 1 : 0, "bad code");
            StkId.Dec(ref S.L.top);
            S.L.nCcalls--;
            return(f);
        }
예제 #3
0
        public static void LuaRawSetI(LuaState L, int idx, int n)
        {
            StkId o;

            LuaLock(L);
            CheckNElements(L, 1);
            o = Index2Address(L, idx);
            ApiCheck(L, TTIsTable(o));
            SetObj2T(L, luaH_setnum(L, HValue(o), n), L.top - 1);
            LuaCBarrierT(L, HValue(o), L.top - 1);
            StkId.Dec(ref L.top);
            LuaUnlock(L);
        }
예제 #4
0
        public static CharPtr LinyeeSetLocal(LinyeeState L, LinyeeDebug ar, int n)
        {
            CallInfo ci   = L.base_ci[ar.i_ci];
            CharPtr  name = FindLocal(L, ci, n);

            LinyeeLock(L);
            if (name != null)
            {
                SetObj2S(L, ci.base_[n - 1], L.top - 1);
            }
            StkId.Dec(ref L.top);        /* pop value */
            LinyeeUnlock(L);
            return(name);
        }
예제 #5
0
        public static void LuaSetField(LuaState L, int idx, CharPtr k)
        {
            StkId  t;
            TValue key = new LuaTypeValue();

            LuaLock(L);
            CheckNElements(L, 1);
            t = Index2Address(L, idx);
            CheckValidIndex(L, t);
            SetSValue(L, key, luaS_new(L, k));
            luaV_settable(L, t, key, L.top - 1);
            StkId.Dec(ref L.top);        /* pop value */
            LuaUnlock(L);
        }
예제 #6
0
        public static void LuaRemove(LuaState L, int idx)
        {
            StkId p;

            LuaLock(L);
            p = Index2Address(L, idx);
            CheckValidIndex(L, p);
            while ((p = p[1]) < L.top)
            {
                SetObj2S(L, p - 1, p);
            }
            StkId.Dec(ref L.top);
            LuaUnlock(L);
        }
예제 #7
0
        private static void callTMres(LinyeeState L, StkId res, TValue f,
                                      TValue p1, TValue p2)
        {
            ptrdiff_t result = SaveStack(L, res);

            SetObj2S(L, L.top, f);        /* push function */
            SetObj2S(L, L.top + 1, p1);   /* 1st argument */
            SetObj2S(L, L.top + 2, p2);   /* 2nd argument */
            LinyeeDCheckStack(L, 3);
            L.top += 3;
            LinyeeDCall(L, L.top - 3, 1);
            res = RestoreStack(L, result);
            StkId.Dec(ref L.top);
            SetObj2S(L, res, L.top);
        }
예제 #8
0
        public static void LuaInsert(LuaState L, int idx)
        {
            StkId p;
            StkId q;

            LuaLock(L);
            p = Index2Address(L, idx);
            CheckValidIndex(L, p);
            for (q = L.top; q > p; StkId.Dec(ref q))
            {
                SetObj2S(L, q, q - 1);
            }
            SetObj2S(L, p, L.top);
            LuaUnlock(L);
        }
예제 #9
0
        public static int LuaSetMetatable(LuaState L, int objindex)
        {
            TValue obj;
            Table  mt;

            LuaLock(L);
            CheckNElements(L, 1);
            obj = Index2Address(L, objindex);
            CheckValidIndex(L, obj);
            if (TTIsNil(L.top - 1))
            {
                mt = null;
            }
            else
            {
                ApiCheck(L, TTIsTable(L.top - 1));
                mt = HValue(L.top - 1);
            }
            switch (TType(obj))
            {
            case LUA_TTABLE: {
                HValue(obj).metatable = mt;
                if (mt != null)
                {
                    LuaCObjBarrierT(L, HValue(obj), mt);
                }
                break;
            }

            case LUA_TUSERDATA: {
                UValue(obj).metatable = mt;
                if (mt != null)
                {
                    LuaCObjBarrier(L, RawUValue(obj), mt);
                }
                break;
            }

            default: {
                G(L).mt[TType(obj)] = mt;
                break;
            }
            }
            StkId.Dec(ref L.top);
            LuaUnlock(L);
            return(1);
        }
예제 #10
0
        public static CharPtr LuaSetUpValue(LuaState L, int funcindex, int n)
        {
            CharPtr name;
            TValue  val = new LuaTypeValue();
            StkId   fi;

            LuaLock(L);
            fi = Index2Address(L, funcindex);
            CheckNElements(L, 1);
            name = AuxUpValue(fi, n, ref val);
            if (name != null)
            {
                StkId.Dec(ref L.top);
                SetObj(L, val, L.top);
                LuaCBarrier(L, CLValue(fi), L.top);
            }
            LuaUnlock(L);
            return(name);
        }
예제 #11
0
        static StkId TryFuncTM(LuaState L, StkId func)
        {
            /*const*/ TValue tm = luaT_gettmbyobj(L, func, TMS.TM_CALL);
            StkId            p;
            ptrdiff_t        funcr = SaveStack(L, func);

            if (!TTIsFunction(tm))
            {
                LuaGTypeError(L, func, "call");
            }
            /* Open a hole inside the stack at `func' */
            for (p = L.top; p > func; StkId.Dec(ref p))
            {
                SetObj2S(L, p, p - 1);
            }
            IncrTop(L);
            func = RestoreStack(L, funcr); /* previous call may change stack */
            SetObj2S(L, func, tm);         /* tag method is the new function to be called */
            return(func);
        }
예제 #12
0
        public static int LuaNext(LuaState L, int idx)
        {
            StkId t;
            int   more;

            LuaLock(L);
            t = Index2Address(L, idx);
            ApiCheck(L, TTIsTable(t));
            more = luaH_next(L, HValue(t), L.top - 1);
            if (more != 0)
            {
                IncrementTop(L);
            }
            else                      /* no more elements */
            {
                StkId.Dec(ref L.top); /* remove key */
            }
            LuaUnlock(L);
            return(more);
        }
예제 #13
0
        public static int LinyeeGetInfo(LinyeeState L, CharPtr what, ref LinyeeDebug ar)
        {
            int      status;
            Closure  f  = null;
            CallInfo ci = null;

            LinyeeLock(L);
            if (what == '>')
            {
                StkId func = L.top - 1;
                luai_apicheck(L, TTIsFunction(func));
                what = what.next();         /* skip the '>' */
                f    = CLValue(func);
                StkId.Dec(ref L.top);       /* pop function */
            }
            else if (ar.i_ci != 0)          /* no tail call? */
            {
                ci = L.base_ci[ar.i_ci];
                LinyeeAssert(TTIsFunction(ci.func));
                f = CLValue(ci.func);
            }
            status = AuxGetInfo(L, what, ar, f, ci);
            if (strchr(what, 'f') != null)
            {
                if (f == null)
                {
                    SetNilValue(L.top);
                }
                else
                {
                    SetCLValue(L, L.top, f);
                }
                IncrTop(L);
            }
            if (strchr(what, 'L') != null)
            {
                CollectValidLines(L, f);
            }
            LinyeeUnlock(L);
            return(status);
        }
예제 #14
0
        public static int LuaSetFEnv(LuaState L, int idx)
        {
            StkId o;
            int   res = 1;

            LuaLock(L);
            CheckNElements(L, 1);
            o = Index2Address(L, idx);
            CheckValidIndex(L, o);
            ApiCheck(L, TTIsTable(L.top - 1));
            switch (TType(o))
            {
            case LUA_TFUNCTION:
                CLValue(o).c.env = HValue(L.top - 1);
                break;

            case LUA_TUSERDATA:
                UValue(o).env = HValue(L.top - 1);
                break;

            case LUA_TTHREAD:
                SetHValue(L, Gt(THValue(o)), HValue(L.top - 1));
                break;

            default:
                res = 0;
                break;
            }
            if (res != 0)
            {
                LuaCObjBarrier(L, GCValue(o), HValue(L.top - 1));
            }
            StkId.Dec(ref L.top);
            LuaUnlock(L);
            return(res);
        }
예제 #15
0
        public static void luaV_execute(LinyeeState L, int nexeccalls)
        {
            LClosure cl;
            StkId    base_;

            TValue[] k;
            /*const*/ InstructionPtr pc;

reentry:    /* entry point */
            LinyeeAssert(IsLinyee(L.ci));
            pc    = InstructionPtr.Assign(L.savedpc);
            cl    = CLValue(L.ci.func).l;
            base_ = L.base_;
            k     = cl.p.k;
            /* main loop of interpreter */
            for (;;)
            {
                /*const*/ Instruction i = InstructionPtr.inc(ref pc)[0];
                StkId ra;
                if (((L.hookmask & (LINYEE_MASKLINE | LINYEE_MASKCOUNT)) != 0) &&
                    (((--L.hookcount) == 0) || ((L.hookmask & LINYEE_MASKLINE) != 0)))
                {
                    traceexec(L, pc);
                    if (L.status == LINYEE_YIELD)          /* did hook yield? */
                    {
                        L.savedpc = new InstructionPtr(pc.codes, pc.pc - 1);
                        return;
                    }
                    base_ = L.base_;
                }
                /* warning!! several calls may realloc the stack and invalidate `ra' */
                ra = RA(L, base_, i);
                LinyeeAssert(base_ == L.base_ && L.base_ == L.ci.base_);
                LinyeeAssert(base_ <= L.top && ((L.top - L.stack) <= L.stacksize));
                LinyeeAssert(L.top == L.ci.top || (LinyeeGCheckOpenOp(i) != 0));
                //Dump(pc.pc, i);
                switch (GET_OPCODE(i))
                {
                case OpCode.OP_MOVE: {
                    SetObj2S(L, ra, RB(L, base_, i));
                    continue;
                }

                case OpCode.OP_LOADK: {
                    SetObj2S(L, ra, KBx(L, i, k));
                    continue;
                }

                case OpCode.OP_LOADBOOL: {
                    SetBValue(ra, GETARG_B(i));
                    if (GETARG_C(i) != 0)
                    {
                        InstructionPtr.inc(ref pc);                                /* skip next instruction (if C) */
                    }
                    continue;
                }

                case OpCode.OP_LOADNIL: {
                    TValue rb = RB(L, base_, i);
                    do
                    {
                        SetNilValue(StkId.Dec(ref rb));
                    } while (rb >= ra);
                    continue;
                }

                case OpCode.OP_GETUPVAL: {
                    int b = GETARG_B(i);
                    SetObj2S(L, ra, cl.upvals[b].v);
                    continue;
                }

                case OpCode.OP_GETGLOBAL: {
                    TValue g  = new LinyeeTypeValue();
                    TValue rb = KBx(L, i, k);
                    SetHValue(L, g, cl.env);
                    LinyeeAssert(TTIsString(rb));
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    luaV_gettable(L, g, rb, ra);
                    base_ = L.base_;
                    //);
                    L.savedpc = InstructionPtr.Assign(pc);
                    continue;
                }

                case OpCode.OP_GETTABLE: {
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    luaV_gettable(L, RB(L, base_, i), RKC(L, base_, i, k), ra);
                    base_ = L.base_;
                    //);
                    L.savedpc = InstructionPtr.Assign(pc);
                    continue;
                }

                case OpCode.OP_SETGLOBAL: {
                    TValue g = new LinyeeTypeValue();
                    SetHValue(L, g, cl.env);
                    LinyeeAssert(TTIsString(KBx(L, i, k)));
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    luaV_settable(L, g, KBx(L, i, k), ra);
                    base_ = L.base_;
                    //);
                    L.savedpc = InstructionPtr.Assign(pc);
                    continue;
                }

                case OpCode.OP_SETUPVAL: {
                    UpVal uv = cl.upvals[GETARG_B(i)];
                    SetObj(L, uv.v, ra);
                    LinyeeCBarrier(L, uv, ra);
                    continue;
                }

                case OpCode.OP_SETTABLE: {
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    luaV_settable(L, ra, RKB(L, base_, i, k), RKC(L, base_, i, k));
                    base_ = L.base_;
                    //);
                    L.savedpc = InstructionPtr.Assign(pc);
                    continue;
                }

                case OpCode.OP_NEWTABLE: {
                    int b = GETARG_B(i);
                    int c = GETARG_C(i);
                    SetHValue(L, ra, luaH_new(L, LinyeeOFBInt(b), LinyeeOFBInt(c)));
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    LinyeeCCheckGC(L);
                    base_ = L.base_;
                    //);
                    L.savedpc = InstructionPtr.Assign(pc);
                    continue;
                }

                case OpCode.OP_SELF: {
                    StkId rb = RB(L, base_, i);
                    SetObj2S(L, ra + 1, rb);
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    luaV_gettable(L, rb, RKC(L, base_, i, k), ra);
                    base_ = L.base_;
                    //);
                    L.savedpc = InstructionPtr.Assign(pc);
                    continue;
                }

                case OpCode.OP_ADD: {
                    arith_op(L, luai_numadd, TMS.TM_ADD, base_, i, k, ra, pc);
                    continue;
                }

                case OpCode.OP_SUB: {
                    arith_op(L, luai_numsub, TMS.TM_SUB, base_, i, k, ra, pc);
                    continue;
                }

                case OpCode.OP_MUL: {
                    arith_op(L, luai_nummul, TMS.TM_MUL, base_, i, k, ra, pc);
                    continue;
                }

                case OpCode.OP_DIV: {
                    arith_op(L, luai_numdiv, TMS.TM_DIV, base_, i, k, ra, pc);
                    continue;
                }

                case OpCode.OP_MOD: {
                    arith_op(L, luai_nummod, TMS.TM_MOD, base_, i, k, ra, pc);
                    continue;
                }

                case OpCode.OP_POW: {
                    arith_op(L, luai_numpow, TMS.TM_POW, base_, i, k, ra, pc);
                    continue;
                }

                case OpCode.OP_UNM: {
                    TValue rb = RB(L, base_, i);
                    if (TTIsNumber(rb))
                    {
                        ly_Number nb = NValue(rb);
                        SetNValue(ra, luai_numunm(nb));
                    }
                    else
                    {
                        //Protect(
                        L.savedpc = InstructionPtr.Assign(pc);
                        Arith(L, ra, rb, rb, TMS.TM_UNM);
                        base_ = L.base_;
                        //);
                        L.savedpc = InstructionPtr.Assign(pc);
                    }
                    continue;
                }

                case OpCode.OP_NOT: {
                    int res = LIsFalse(RB(L, base_, i)) == 0 ? 0 : 1;              /* next assignment may change this value */
                    SetBValue(ra, res);
                    continue;
                }

                case OpCode.OP_LEN: {
                    TValue rb = RB(L, base_, i);
                    switch (TType(rb))
                    {
                    case LINYEE_TTABLE: {
                        SetNValue(ra, (ly_Number)luaH_getn(HValue(rb)));
                        break;
                    }

                    case LINYEE_TSTRING: {
                        SetNValue(ra, (ly_Number)TSValue(rb).len);
                        break;
                    }

                    default: {                /* try metamethod */
                        //Protect(
                        L.savedpc = InstructionPtr.Assign(pc);
                        if (call_binTM(L, rb, LinyeeONilObject, ra, TMS.TM_LEN) == 0)
                        {
                            LinyeeGTypeError(L, rb, "get length of");
                        }
                        base_ = L.base_;
                        //)
                        break;
                    }
                    }
                    continue;
                }

                case OpCode.OP_CONCAT: {
                    int b = GETARG_B(i);
                    int c = GETARG_C(i);
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    luaV_concat(L, c - b + 1, c); LinyeeCCheckGC(L);
                    base_ = L.base_;
                    //);
                    SetObj2S(L, RA(L, base_, i), base_ + b);
                    continue;
                }

                case OpCode.OP_JMP: {
                    dojump(L, pc, GETARG_sBx(i));
                    continue;
                }

                case OpCode.OP_EQ: {
                    TValue rb = RKB(L, base_, i, k);
                    TValue rc = RKC(L, base_, i, k);
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    if (equalobj(L, rb, rc) == GETARG_A(i))
                    {
                        dojump(L, pc, GETARG_sBx(pc[0]));
                    }
                    base_ = L.base_;
                    //);
                    InstructionPtr.inc(ref pc);
                    continue;
                }

                case OpCode.OP_LT: {
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    if (luaV_lessthan(L, RKB(L, base_, i, k), RKC(L, base_, i, k)) == GETARG_A(i))
                    {
                        dojump(L, pc, GETARG_sBx(pc[0]));
                    }
                    base_ = L.base_;
                    //);
                    InstructionPtr.inc(ref pc);
                    continue;
                }

                case OpCode.OP_LE: {
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    if (lessequal(L, RKB(L, base_, i, k), RKC(L, base_, i, k)) == GETARG_A(i))
                    {
                        dojump(L, pc, GETARG_sBx(pc[0]));
                    }
                    base_ = L.base_;
                    //);
                    InstructionPtr.inc(ref pc);
                    continue;
                }

                case OpCode.OP_TEST: {
                    if (LIsFalse(ra) != GETARG_C(i))
                    {
                        dojump(L, pc, GETARG_sBx(pc[0]));
                    }
                    InstructionPtr.inc(ref pc);
                    continue;
                }

                case OpCode.OP_TESTSET: {
                    TValue rb = RB(L, base_, i);
                    if (LIsFalse(rb) != GETARG_C(i))
                    {
                        SetObj2S(L, ra, rb);
                        dojump(L, pc, GETARG_sBx(pc[0]));
                    }
                    InstructionPtr.inc(ref pc);
                    continue;
                }

                case OpCode.OP_CALL: {
                    int b        = GETARG_B(i);
                    int nresults = GETARG_C(i) - 1;
                    if (b != 0)
                    {
                        L.top = ra + b;                      /* else previous instruction set top */
                    }
                    L.savedpc = InstructionPtr.Assign(pc);
                    switch (LinyeeDPreCall(L, ra, nresults))
                    {
                    case PCRLUA: {
                        nexeccalls++;
                        goto reentry;                  /* restart luaV_execute over new Linyee function */
                    }

                    case PCRC: {
                        /* it was a C function (`precall' called it); adjust results */
                        if (nresults >= 0)
                        {
                            L.top = L.ci.top;
                        }
                        base_ = L.base_;
                        continue;
                    }

                    default: {
                        return;                  /* yield */
                    }
                    }
                }

                case OpCode.OP_TAILCALL: {
                    int b = GETARG_B(i);
                    if (b != 0)
                    {
                        L.top = ra + b;                      /* else previous instruction set top */
                    }
                    L.savedpc = InstructionPtr.Assign(pc);
                    LinyeeAssert(GETARG_C(i) - 1 == LINYEE_MULTRET);
                    switch (LinyeeDPreCall(L, ra, LINYEE_MULTRET))
                    {
                    case PCRLUA: {
                        /* tail call: put new frame in place of previous one */
                        CallInfo ci = L.ci - 1;                  /* previous frame */
                        int      aux;
                        StkId    func  = ci.func;
                        StkId    pfunc = (ci + 1).func;             /* previous function index */
                        if (L.openupval != null)
                        {
                            LinyeeFClose(L, ci.base_);
                        }
                        L.base_ = ci.base_ = ci.func + (ci[1].base_ - pfunc);
                        for (aux = 0; pfunc + aux < L.top; aux++)                /* move frame down */
                        {
                            SetObj2S(L, func + aux, pfunc + aux);
                        }
                        ci.top = L.top = func + aux;                /* correct top */
                        LinyeeAssert(L.top == L.base_ + CLValue(func).l.p.maxstacksize);
                        ci.savedpc = InstructionPtr.Assign(L.savedpc);
                        ci.tailcalls++;                  /* one more call lost */
                        CallInfo.Dec(ref L.ci);          /* remove new frame */
                        goto reentry;
                    }

                    case PCRC: {                /* it was a C function (`precall' called it) */
                        base_ = L.base_;
                        continue;
                    }

                    default: {
                        return;                  /* yield */
                    }
                    }
                }

                case OpCode.OP_RETURN: {
                    int b = GETARG_B(i);
                    if (b != 0)
                    {
                        L.top = ra + b - 1;
                    }
                    if (L.openupval != null)
                    {
                        LinyeeFClose(L, base_);
                    }
                    L.savedpc = InstructionPtr.Assign(pc);
                    b         = LinyeeDPosCall(L, ra);
                    if (--nexeccalls == 0) /* was previous function running `here'? */
                    {
                        return;            /* no: return */
                    }
                    else                   /* yes: continue its execution */
                    {
                        if (b != 0)
                        {
                            L.top = L.ci.top;
                        }
                        LinyeeAssert(IsLinyee(L.ci));
                        LinyeeAssert(GET_OPCODE(L.ci.savedpc[-1]) == OpCode.OP_CALL);
                        goto reentry;
                    }
                }

                case OpCode.OP_FORLOOP: {
                    ly_Number step  = NValue(ra + 2);
                    ly_Number idx   = luai_numadd(NValue(ra), step);           /* increment index */
                    ly_Number limit = NValue(ra + 1);
                    if (luai_numlt(0, step) ? luai_numle(idx, limit)
                                                                                : luai_numle(limit, idx))
                    {
                        dojump(L, pc, GETARG_sBx(i));  /* jump back */
                        SetNValue(ra, idx);            /* update internal index... */
                        SetNValue(ra + 3, idx);        /* ...and external index */
                    }
                    continue;
                }

                case OpCode.OP_FORPREP: {
                    TValue init   = ra;
                    TValue plimit = ra + 1;
                    TValue pstep  = ra + 2;
                    L.savedpc = InstructionPtr.Assign(pc);              /* next steps may throw errors */
                    if (tonumber(ref init, ra) == 0)
                    {
                        LinyeeGRunError(L, LINYEE_QL("for") + " initial value must be a number");
                    }
                    else if (tonumber(ref plimit, ra + 1) == 0)
                    {
                        LinyeeGRunError(L, LINYEE_QL("for") + " limit must be a number");
                    }
                    else if (tonumber(ref pstep, ra + 2) == 0)
                    {
                        LinyeeGRunError(L, LINYEE_QL("for") + " step must be a number");
                    }
                    SetNValue(ra, luai_numsub(NValue(ra), NValue(pstep)));
                    dojump(L, pc, GETARG_sBx(i));
                    continue;
                }

                case OpCode.OP_TFORLOOP: {
                    StkId cb = ra + 3;              /* call base */
                    SetObj2S(L, cb + 2, ra + 2);
                    SetObj2S(L, cb + 1, ra + 1);
                    SetObj2S(L, cb, ra);
                    L.top = cb + 3;            /* func. + 2 args (state and index) */
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    LinyeeDCall(L, cb, GETARG_C(i));
                    base_ = L.base_;
                    //);
                    L.top = L.ci.top;
                    cb    = RA(L, base_, i) + 3;          /* previous call may change the stack */
                    if (!TTIsNil(cb))                     /* continue loop? */
                    {
                        SetObj2S(L, cb - 1, cb);          /* save control variable */
                        dojump(L, pc, GETARG_sBx(pc[0])); /* jump back */
                    }
                    InstructionPtr.inc(ref pc);
                    continue;
                }

                case OpCode.OP_SETLIST: {
                    int   n = GETARG_B(i);
                    int   c = GETARG_C(i);
                    int   last;
                    Table h;
                    if (n == 0)
                    {
                        n     = CastInt(L.top - ra) - 1;
                        L.top = L.ci.top;
                    }
                    if (c == 0)
                    {
                        c = CastInt(pc[0]);
                        InstructionPtr.inc(ref pc);
                    }
                    runtime_check(L, TTIsTable(ra));
                    h    = HValue(ra);
                    last = ((c - 1) * LFIELDS_PER_FLUSH) + n;
                    if (last > h.sizearray)              /* needs more space? */
                    {
                        luaH_resizearray(L, h, last);    /* pre-alloc it at once */
                    }
                    for (; n > 0; n--)
                    {
                        TValue val = ra + n;
                        SetObj2T(L, luaH_setnum(L, h, last--), val);
                        LinyeeCBarrierT(L, h, val);
                    }
                    continue;
                }

                case OpCode.OP_CLOSE: {
                    LinyeeFClose(L, ra);
                    continue;
                }

                case OpCode.OP_CLOSURE: {
                    Proto   p;
                    Closure ncl;
                    int     nup, j;
                    p       = cl.p.p[GETARG_Bx(i)];
                    nup     = p.nups;
                    ncl     = LinyeeFNewLClosure(L, nup, cl.env);
                    ncl.l.p = p;
                    for (j = 0; j < nup; j++, InstructionPtr.inc(ref pc))
                    {
                        if (GET_OPCODE(pc[0]) == OpCode.OP_GETUPVAL)
                        {
                            ncl.l.upvals[j] = cl.upvals[GETARG_B(pc[0])];
                        }
                        else
                        {
                            LinyeeAssert(GET_OPCODE(pc[0]) == OpCode.OP_MOVE);
                            ncl.l.upvals[j] = LinyeeFindUpVal(L, base_ + GETARG_B(pc[0]));
                        }
                    }
                    SetCLValue(L, ra, ncl);
                    //Protect(
                    L.savedpc = InstructionPtr.Assign(pc);
                    LinyeeCCheckGC(L);
                    base_ = L.base_;
                    //);
                    continue;
                }

                case OpCode.OP_VARARG: {
                    int      b = GETARG_B(i) - 1;
                    int      j;
                    CallInfo ci = L.ci;
                    int      n  = CastInt(ci.base_ - ci.func) - cl.p.numparams - 1;
                    if (b == LINYEE_MULTRET)
                    {
                        //Protect(
                        L.savedpc = InstructionPtr.Assign(pc);
                        LinyeeDCheckStack(L, n);
                        base_ = L.base_;
                        //);
                        ra    = RA(L, base_, i);         /* previous call may change the stack */
                        b     = n;
                        L.top = ra + n;
                    }
                    for (j = 0; j < b; j++)
                    {
                        if (j < n)
                        {
                            SetObj2S(L, ra + j, ci.base_ - n + j);
                        }
                        else
                        {
                            SetNilValue(ra + j);
                        }
                    }
                    continue;
                }
                }
            }
        }