Exemple #1
0
        /*
        ** Execute the given opcode. Return 0 in success or 1 on error.
        */
        public static int lua_execute(BytePtr pc)
        {
            ObjectRef oldbase = new ObjectRef(@base);

            @base = new ObjectRef(top);
            while (true)
            {
                OpCode opcode;
                opcode = (OpCode)pc[0]; pc.inc();
                switch (opcode)
                {
                case OpCode.PUSHNIL:
                    tag(top.get(), Type.T_NIL);
                    top.inc();
                    break;

                case OpCode.PUSH0:
                    tag(top.get(), Type.T_NUMBER);
                    nvalue(top.get(), 0);
                    top.inc();
                    break;

                case OpCode.PUSH1:
                    tag(top.get(), Type.T_NUMBER);
                    nvalue(top.get(), 1);
                    top.inc();
                    break;

                case OpCode.PUSH2:
                    tag(top.get(), Type.T_NUMBER);
                    nvalue(top.get(), 2);
                    top.inc();
                    break;

                case OpCode.PUSHBYTE:
                    tag(top.get(), Type.T_NUMBER);
                    nvalue(top.get(), pc[0]); pc.inc();
                    top.inc();
                    break;

                case OpCode.PUSHWORD:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    tag(top.get(), Type.T_NUMBER);
                    nvalue(top.get(), code.w);
                    top.inc();
                }
                break;

                case OpCode.PUSHFLOAT:
                {
                    CodeFloat code = new CodeFloat();
                    get_float(code, pc);
                    tag(top.get(), Type.T_NUMBER);
                    nvalue(top.get(), code.f);
                    top.inc();
                }
                break;

                case OpCode.PUSHSTRING:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    tag(top.get(), Type.T_STRING);
                    svalue(top.get(), lua_constant[code.w]);
                    top.inc();
                }
                break;

                case OpCode.PUSHLOCAL0:
                case OpCode.PUSHLOCAL1:
                case OpCode.PUSHLOCAL2:
                case OpCode.PUSHLOCAL3:
                case OpCode.PUSHLOCAL4:
                case OpCode.PUSHLOCAL5:
                case OpCode.PUSHLOCAL6:
                case OpCode.PUSHLOCAL7:
                case OpCode.PUSHLOCAL8:
                case OpCode.PUSHLOCAL9:
                    top.set(0, @base.get((int)(opcode - OpCode.PUSHLOCAL0)));
                    top.inc();
                    break;

                case OpCode.PUSHLOCAL:
                    top.set(0, @base.get(pc[0]));
                    top.inc();
                    pc.inc();
                    break;

                case OpCode.PUSHGLOBAL:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    top.set(0, s_object(code.w));
                    top.inc();
                }
                break;

                case OpCode.PUSHINDEXED:
                    top.dec();
                    if (tag(top.get(-1)) != Type.T_ARRAY)
                    {
                        lua_reportbug("indexed expression not a table");
                        return(1);
                    }
                    {
                        Object_ h = lua_hashdefine(avalue(top.get(-1)), top.get());
                        if (h == null)
                        {
                            return(1);
                        }
                        top.set(-1, h);
                    }
                    break;

                case OpCode.PUSHMARK:
                    tag(top.get(), Type.T_MARK);
                    top.inc();
                    break;

                case OpCode.PUSHOBJECT:
                    top.set(0, top.get(-3));
                    top.inc();
                    break;

                case OpCode.STORELOCAL0:
                case OpCode.STORELOCAL1:
                case OpCode.STORELOCAL2:
                case OpCode.STORELOCAL3:
                case OpCode.STORELOCAL4:
                case OpCode.STORELOCAL5:
                case OpCode.STORELOCAL6:
                case OpCode.STORELOCAL7:
                case OpCode.STORELOCAL8:
                case OpCode.STORELOCAL9:
                    top.dec();
                    @base.set((int)(opcode - OpCode.STORELOCAL0), top.get());
                    break;

                case OpCode.STORELOCAL:
                    top.dec();
                    @base.set(pc[0], top.get());
                    pc.inc();
                    break;

                case OpCode.STOREGLOBAL:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    top.dec();
                    s_object(code.w, top.get());
                }
                break;

                case OpCode.STOREINDEXED0:
                    if (tag(top.get(-3)) != Type.T_ARRAY)
                    {
                        lua_reportbug("indexed expression not a table");
                        return(1);
                    }
                    {
                        Object_ h = lua_hashdefine(avalue(top.get(-3)), top.get(-2));
                        if (h == null)
                        {
                            return(1);
                        }
                        h.set(top.get(-1));
                    }
                    top.add(-3);
                    break;

                case OpCode.STOREINDEXED:
                {
                    int n = pc[0]; pc.inc();
                    if (tag(top.get(-3 - n)) != Type.T_ARRAY)
                    {
                        lua_reportbug("indexed expression not a table");
                        return(1);
                    }
                    {
                        Object_ h = lua_hashdefine(avalue(top.get(-3 - n)), top.get(-2 - n));
                        if (h == null)
                        {
                            return(1);
                        }
                        h.set(top.get(-1));
                    }
                    top.dec();
                }
                break;

                case OpCode.STORELIST0:
                case OpCode.STORELIST:
                {
                    int     m, n;
                    Object_ arr;
                    if (opcode == OpCode.STORELIST0)
                    {
                        m = 0;
                    }
                    else
                    {
                        m = pc[0] * FIELDS_PER_FLUSH; pc.inc();
                    }
                    n   = pc[0]; pc.inc();
                    arr = top.get(-n - 1);
                    if (tag(arr) != Type.T_ARRAY)
                    {
                        lua_reportbug("internal error - table expected");
                        return(1);
                    }
                    while (n != 0)
                    {
                        tag(top.get(), Type.T_NUMBER); nvalue(top.get(), n + m);
                        lua_hashdefine(avalue(arr), top.get()).set(top.get(-1));
                        top.dec();
                        n--;
                    }
                }
                break;

                case OpCode.STORERECORD:
                {
                    int     n   = pc[0]; pc.inc();
                    Object_ arr = top.get(-n - 1);
                    if (tag(arr) != Type.T_ARRAY)
                    {
                        lua_reportbug("internal error - table expected");
                        return(1);
                    }
                    while (n != 0)
                    {
                        CodeWord code = new CodeWord();
                        get_word(code, pc);
                        tag(top.get(), Type.T_STRING); svalue(top.get(), lua_constant[code.w]);
                        (lua_hashdefine(avalue(arr), top.get())).set(top.get(-1));
                        top.dec();
                        n--;
                    }
                }
                break;

                case OpCode.ADJUST:
                {
                    ObjectRef newtop = @base.getRef(pc[0]); pc.inc();
                    while (top.isLessThan(newtop.get()))
                    {
                        tag(top.get(), Type.T_NIL); top.inc();
                    }
                    top = newtop;                          /* top could be bigger than newtop */
                }
                break;

                case OpCode.CREATEARRAY:
                    if (tag(top.get(-1)) == Type.T_NIL)
                    {
                        nvalue(top.get(-1), 101);
                    }
                    else
                    {
                        if (tonumber(top.get(-1)))
                        {
                            return(1);
                        }
                        if (nvalue(top.get(-1)) <= 0)
                        {
                            nvalue(top.get(-1), 101);
                        }
                    }
                    avalue(top.get(-1), (Hash)lua_createarray((int)nvalue(top.get(-1))));
                    if (avalue(top.get(-1)) == null)
                    {
                        return(1);
                    }
                    tag(top.get(-1), Type.T_ARRAY);
                    break;

                case OpCode.EQOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    top.dec();
                    if (tag(l) != tag(r))
                    {
                        tag(top.get(-1), Type.T_NIL);
                    }
                    else
                    {
                        switch (tag(l))
                        {
                        case Type.T_NIL:
                            tag(top.get(-1), Type.T_NUMBER);
                            break;

                        case Type.T_NUMBER:
                            tag(top.get(-1), (nvalue(l) == nvalue(r)) ? Type.T_NUMBER : Type.T_NIL);
                            break;

                        case Type.T_ARRAY:
                            tag(top.get(-1), (avalue(l) == avalue(r)) ? Type.T_NUMBER : Type.T_NIL);
                            break;

                        case Type.T_FUNCTION:
                            tag(top.get(-1), (bvalue(l) == bvalue(r)) ? Type.T_NUMBER : Type.T_NIL);
                            break;

                        case Type.T_CFUNCTION:
                            tag(top.get(-1), (fvalue(l) == fvalue(r)) ? Type.T_NUMBER : Type.T_NIL);
                            break;

                        case Type.T_USERDATA:
                            tag(top.get(-1), (uvalue(l) == uvalue(r)) ? Type.T_NUMBER : Type.T_NIL);
                            break;

                        case Type.T_STRING:
                            tag(top.get(-1), (strcmp(svalue(l), svalue(r)) == 0) ? Type.T_NUMBER : Type.T_NIL);
                            break;

                        case Type.T_MARK:
                            return(1);
                        }
                    }
                    nvalue(top.get(-1), 1);
                }
                break;

                case OpCode.LTOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    top.dec();
                    if (tag(l) == Type.T_NUMBER && tag(r) == Type.T_NUMBER)
                    {
                        tag(top.get(-1), (nvalue(l) < nvalue(r)) ? Type.T_NUMBER : Type.T_NIL);
                    }
                    else
                    {
                        if (tostring(l) || tostring(r))
                        {
                            return(1);
                        }
                        tag(top.get(-1), (strcmp(svalue(l), svalue(r)) < 0) ? Type.T_NUMBER : Type.T_NIL);
                    }
                    nvalue(top.get(-1), 1);
                }
                break;

                case OpCode.LEOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    top.dec();
                    if (tag(l) == Type.T_NUMBER && tag(r) == Type.T_NUMBER)
                    {
                        tag(top.get(-1), (nvalue(l) <= nvalue(r)) ? Type.T_NUMBER : Type.T_NIL);
                    }
                    else
                    {
                        if (tostring(l) || tostring(r))
                        {
                            return(1);
                        }
                        tag(top.get(-1), (strcmp(svalue(l), svalue(r)) <= 0) ? Type.T_NUMBER : Type.T_NIL);
                    }
                    nvalue(top.get(-1), 1);
                }
                break;

                case OpCode.ADDOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tonumber(r) || tonumber(l))
                    {
                        return(1);
                    }
                    nvalue(l, nvalue(l) + nvalue(r));
                    top.dec();
                }
                break;

                case OpCode.SUBOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tonumber(r) || tonumber(l))
                    {
                        return(1);
                    }
                    nvalue(l, nvalue(l) - nvalue(r));
                    top.dec();
                }
                break;

                case OpCode.MULTOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tonumber(r) || tonumber(l))
                    {
                        return(1);
                    }
                    nvalue(l, nvalue(l) * nvalue(r));
                    top.dec();
                }
                break;

                case OpCode.DIVOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tonumber(r) || tonumber(l))
                    {
                        return(1);
                    }
                    nvalue(l, nvalue(l) / nvalue(r));
                    top.dec();
                }
                break;

                case OpCode.CONCOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tostring(r) || tostring(l))
                    {
                        return(1);
                    }
                    svalue(l, lua_createstring(lua_strconc(svalue(l), svalue(r))));
                    if (svalue(l) == null)
                    {
                        return(1);
                    }
                    top.dec();
                }
                break;

                case OpCode.MINUSOP:
                    if (tonumber(top.get(-1)))
                    {
                        return(1);
                    }
                    nvalue(top.get(-1), -nvalue(top.get(-1)));
                    break;

                case OpCode.NOTOP:
                    tag(top.get(-1), tag(top.get(-1)) == Type.T_NIL ? Type.T_NUMBER : Type.T_NIL);
                    break;

                case OpCode.ONTJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    if (tag(top.get(-1)) != Type.T_NIL)
                    {
                        pc += code.w;
                    }
                }
                break;

                case OpCode.ONFJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    if (tag(top.get(-1)) == Type.T_NIL)
                    {
                        pc += code.w;
                    }
                }
                break;

                case OpCode.JMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    pc += code.w;
                }
                break;

                case OpCode.UPJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    pc -= code.w;
                }
                break;

                case OpCode.IFFJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    top.dec();
                    if (tag(top.get()) == Type.T_NIL)
                    {
                        pc += code.w;
                    }
                }
                break;

                case OpCode.IFFUPJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    top.dec();
                    if (tag(top.get()) == Type.T_NIL)
                    {
                        pc -= code.w;
                    }
                }
                break;

                case OpCode.POP:
                    top.dec();
                    break;

                case OpCode.CALLFUNC:
                {
//				        if (pc.chars != code.chars && pc.index == 4454)
//				        {
//				            Console.WriteLine("=================");
//				        }
                    BytePtr   newpc;
                    ObjectRef b_ = top.getRef(-1);
                    while (tag(b_.get()) != Type.T_MARK)
                    {
                        b_.dec();
                    }
//						if (b_.obj == stack)
//						{
//							Console.WriteLine("================");
//						}
                    if (tag(b_.get(-1)) == Type.T_FUNCTION)
                    {
                        lua_debugline = 0;                                                      /* always reset debug flag */
                        newpc         = bvalue(b_.get(-1));
                        bvalue(b_.get(-1), pc);                                                 /* store return code */
                        nvalue(b_.get(), @base.minus(stack));                                   /* store base value */
                        @base = b_.getRef(+1);
                        pc    = new BytePtr(newpc);
                        if (MAXSTACK - @base.minus(stack) < STACKGAP)
                        {
                            lua_error("stack overflow");
                            return(1);
                        }
                    }
                    else if (tag(b_.get(-1)) == Type.T_CFUNCTION)
                    {
                        int nparam;
                        lua_debugline = 0;                                 // always reset debug flag
                        nvalue(b_.get(), @base.minus(stack));              // store base value
                        @base  = b_.getRef(+1);
                        nparam = top.minus(@base);                         // number of parameters
                        (fvalue(b_.get(-1)))();                            // call C function

                        /* shift returned values */
                        {
                            int i;
                            int nretval = top.minus(@base) - nparam;
                            top   = @base.getRef(-2);
                            @base = new ObjectRef(stack, (int)nvalue(@base.get(-1)));
                            for (i = 0; i < nretval; i++)
                            {
                                top.get().set(top.get(nparam + 2));
                                top.inc();
                            }
                        }
                    }
                    else
                    {
                        lua_reportbug("call expression not a function");
                        return(1);
                    }
                }
                break;

                case OpCode.RETCODE:
                {
                    int i;
                    int shift   = pc[0]; pc.inc();
                    int nretval = top.minus(@base) - shift;
                    top.setRef(@base.get(-2));
                    pc    = bvalue(@base.get(-2));
                    @base = new ObjectRef(stack, (int)nvalue(@base.get(-1)));                              //FIXME:???new ObjectRef???
                    for (i = 0; i < nretval; i++)
                    {
                        top.get().set(top.get(shift + 2));
                        top.inc();
                    }
                }
                break;

                case OpCode.HALT:
                    @base = new ObjectRef(oldbase);
                    return(0);                    // success

                case OpCode.SETFUNCTION:
                {
                    CodeWord file = new CodeWord(), func = new CodeWord();
                    get_word(file, pc);
                    get_word(func, pc);
                    if (0 != lua_pushfunction(file.w, func.w))
                    {
                        return(1);
                    }
                }
                break;

                case OpCode.SETLINE:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    lua_debugline = code.w;
                }
                break;

                case OpCode.RESET:
                    lua_popfunction();
                    break;

                default:
                    lua_error("internal error - opcode didn't match");
                    return(1);
                }
            }
        }
 public static void get_float(CodeFloat code, BytePtr pc)
 {
     code.m.c1 = (Byte)pc[0]; pc.inc(); code.m.c2 = (Byte)pc[0]; pc.inc();
     code.m.c3 = (Byte)pc[0]; pc.inc(); code.m.c4 = (Byte)pc[0]; pc.inc();
 }
        /*
        ** Execute the given opcode, until a RET. Parameters are between
        ** [stack+base,top). Returns n such that the the results are between
        ** [stack+n,top).
        */
        private static StkId lua_execute(BytePtr pc, StkId @base)
        {
            //pc = new BytePtr(pc);
            lua_checkstack(STACKGAP + MAX_TEMPS + @base);
            while (true)
            {
#if MY_DEBUG
                //printf(">>> %d,", ObjectRef.minus(top, stack));
#endif
                OpCode opcode;
                opcode = (OpCode)pc[0]; pc.inc();
                switch (opcode)
                {
                case OpCode.PUSHNIL: tag(top.get(), lua_Type.LUA_T_NIL); top.inc(); break;

                case OpCode.PUSH0:
                case OpCode.PUSH1:
                case OpCode.PUSH2:
                    tag(top.get(), lua_Type.LUA_T_NUMBER);
                    nvalue(top.get(), opcode - OpCode.PUSH0); top.inc();
                    break;

                case OpCode.PUSHBYTE: tag(top.get(), lua_Type.LUA_T_NUMBER); nvalue(top.get(), pc[0]); top.inc(); pc.inc(); break;

                case OpCode.PUSHWORD:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    tag(top.get(), lua_Type.LUA_T_NUMBER); nvalue(top.get(), code.w); top.inc();
                }
                break;

                case OpCode.PUSHFLOAT:
                {
                    CodeFloat code = new CodeFloat();
                    get_float(code, pc);
                    tag(top.get(), lua_Type.LUA_T_NUMBER); nvalue(top.get(), code.f); top.inc();
                }
                break;

                case OpCode.PUSHSTRING:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    tag(top.get(), lua_Type.LUA_T_STRING); tsvalue(top.get(), lua_constant[code.w]); top.inc();
                }
                break;

                case OpCode.PUSHFUNCTION:
                {
                    CodeCode code = new CodeCode();
                    get_code(code, pc);
                    tag(top.get(), lua_Type.LUA_T_FUNCTION); bvalue(top.get(), new BytePtr(code.b, 0)); top.inc();
                }
                break;

                case OpCode.PUSHLOCAL0:
                case OpCode.PUSHLOCAL1:
                case OpCode.PUSHLOCAL2:
                case OpCode.PUSHLOCAL3:
                case OpCode.PUSHLOCAL4:
                case OpCode.PUSHLOCAL5:
                case OpCode.PUSHLOCAL6:
                case OpCode.PUSHLOCAL7:
                case OpCode.PUSHLOCAL8:
                case OpCode.PUSHLOCAL9: top.get().set(stack[(@base) + (int)(opcode - OpCode.PUSHLOCAL0)]); top.inc(); break;

                case OpCode.PUSHLOCAL: top.get().set(stack[(@base) + pc[0]]); top.inc(); pc.inc(); break;

                case OpCode.PUSHGLOBAL:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    top.get().set(s_object(code.w)); top.inc();
                }
                break;

                case OpCode.PUSHINDEXED:
                    pushsubscript();
                    break;

                case OpCode.PUSHSELF:
                {
                    Object_  receiver = top.get(-1);
                    CodeWord code     = new CodeWord();
                    get_word(code, pc);
                    tag(top.get(), lua_Type.LUA_T_STRING); tsvalue(top.get(), lua_constant[code.w]); top.inc();
                    pushsubscript();
                    top.get().set(receiver); top.inc();
                    break;
                }

                case OpCode.STORELOCAL0:
                case OpCode.STORELOCAL1:
                case OpCode.STORELOCAL2:
                case OpCode.STORELOCAL3:
                case OpCode.STORELOCAL4:
                case OpCode.STORELOCAL5:
                case OpCode.STORELOCAL6:
                case OpCode.STORELOCAL7:
                case OpCode.STORELOCAL8:
                case OpCode.STORELOCAL9:
                    top.dec();
                    stack[(@base) + (int)(opcode - OpCode.STORELOCAL0)].set(top.get());
                    break;

                case OpCode.STORELOCAL: top.dec(); stack[(@base) + pc[0]].set(top.get()); pc.inc(); break;

                case OpCode.STOREGLOBAL:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    top.dec();
                    s_object(code.w, top.get(0));
                }
                break;

                case OpCode.STOREINDEXED0:
                    storesubscript();
                    break;

                case OpCode.STOREINDEXED:
                {
                    int n = pc[0]; pc.inc();
                    if (tag(top.get(-3 - n)) != lua_Type.LUA_T_ARRAY)
                    {
                        top.get(+1).set(top.get(-1));
                        top.get().set(top.get(-2 - n));
                        top.get(-1).set(top.get(-3 - n));
                        top.add(2);
                        do_call(luaI_fallBacks[FB_SETTABLE].function, ObjectRef.minus(top, stack) - 3, 0, ObjectRef.minus(top, stack) - 3);
                    }
                    else
                    {
                        Object_ h = lua_hashdefine(avalue(top.get(-3 - n)), top.get(-2 - n));
                        h.set(top.get(-1));
                        top.dec();
                    }
                }
                break;

                case OpCode.STORELIST0:
                case OpCode.STORELIST:
                {
                    int     m, n;
                    Object_ arr;
                    if (opcode == OpCode.STORELIST0)
                    {
                        m = 0;
                    }
                    else
                    {
                        m = pc[0] * FIELDS_PER_FLUSH; pc.inc();
                    }
                    n   = pc[0]; pc.inc();
                    arr = top.get(-n - 1);
                    while (n != 0)
                    {
                        tag(top.get(), lua_Type.LUA_T_NUMBER); nvalue(top.get(), n + m);
                        lua_hashdefine(avalue(arr), top.get()).set(top.get(-1));
                        top.dec();
                        n--;
                    }
                }
                break;

                case OpCode.STORERECORD:
                {
                    int     n   = pc[0]; pc.inc();
                    Object_ arr = top.get(-n - 1);
                    while (n != 0)
                    {
                        CodeWord code = new CodeWord();
                        get_word(code, pc);
                        tag(top.get(), lua_Type.LUA_T_STRING); tsvalue(top.get(), lua_constant[code.w]);
                        lua_hashdefine(avalue(arr), top.get()).set(top.get(-1));
                        top.dec();
                        n--;
                    }
                }
                break;

                case OpCode.ADJUST0:
                    adjust_top(@base);
                    break;

                case OpCode.ADJUST:
                    adjust_top(@base + pc[0]); pc.inc();
                    break;

                case OpCode.CREATEARRAY:
                {
                    CodeWord size = new CodeWord();
                    get_word(size, pc);
                    avalue(top.get(), lua_createarray(size.w));
                    tag(top.get(), lua_Type.LUA_T_ARRAY);
                    top.inc();
                }
                break;

                case OpCode.EQOP:
                {
                    int res = lua_equalObj(top.get(-2), top.get(-1));
                    top.dec();
                    tag(top.get(-1), res != 0 ? lua_Type.LUA_T_NUMBER : lua_Type.LUA_T_NIL);
                    nvalue(top.get(-1), 1);
                }
                break;

                case OpCode.LTOP:
                    comparison(lua_Type.LUA_T_NUMBER, lua_Type.LUA_T_NIL, lua_Type.LUA_T_NIL, "lt");
                    break;

                case OpCode.LEOP:
                    comparison(lua_Type.LUA_T_NUMBER, lua_Type.LUA_T_NUMBER, lua_Type.LUA_T_NIL, "le");
                    break;

                case OpCode.GTOP:
                    comparison(lua_Type.LUA_T_NIL, lua_Type.LUA_T_NIL, lua_Type.LUA_T_NUMBER, "gt");
                    break;

                case OpCode.GEOP:
                    comparison(lua_Type.LUA_T_NIL, lua_Type.LUA_T_NUMBER, lua_Type.LUA_T_NUMBER, "ge");
                    break;

                case OpCode.ADDOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tonumber(r) || tonumber(l))
                    {
                        call_arith("add");
                    }
                    else
                    {
                        nvalue(l, nvalue(l) + nvalue(r));
                        top.dec();
                    }
                }
                break;

                case OpCode.SUBOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tonumber(r) || tonumber(l))
                    {
                        call_arith("sub");
                    }
                    else
                    {
                        nvalue(l, nvalue(l) - nvalue(r));
                        top.dec();
                    }
                }
                break;

                case OpCode.MULTOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tonumber(r) || tonumber(l))
                    {
                        call_arith("mul");
                    }
                    else
                    {
                        nvalue(l, nvalue(l) * nvalue(r));
                        top.dec();
                    }
                }
                break;

                case OpCode.DIVOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tonumber(r) || tonumber(l))
                    {
                        call_arith("div");
                    }
                    else
                    {
                        nvalue(l, nvalue(l) / nvalue(r));
                        top.dec();
                    }
                }
                break;

                case OpCode.POWOP:
                    call_arith("pow");
                    break;

                case OpCode.CONCOP:
                {
                    Object_ l = top.get(-2);
                    Object_ r = top.get(-1);
                    if (tostring(r) || tostring(l))
                    {
                        do_call(luaI_fallBacks[FB_CONCAT].function, ObjectRef.minus(top, stack) - 2, 1, ObjectRef.minus(top, stack) - 2);
                    }
                    else
                    {
                        tsvalue(l, lua_createstring(lua_strconc(svalue(l), svalue(r))));
                        top.dec();
                    }
                }
                break;

                case OpCode.MINUSOP:
                    if (tonumber(top.get(-1)))
                    {
                        tag(top.get(), lua_Type.LUA_T_NIL); top.inc();
                        call_arith("unm");
                    }
                    else
                    {
                        nvalue(top.get(-1), -nvalue(top.get(-1)));
                    }
                    break;

                case OpCode.NOTOP:
                    tag(top.get(-1), (tag(top.get(-1)) == lua_Type.LUA_T_NIL) ? lua_Type.LUA_T_NUMBER : lua_Type.LUA_T_NIL);
                    nvalue(top.get(-1), 1);
                    break;

                case OpCode.ONTJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    if (tag(top.get(-1)) != lua_Type.LUA_T_NIL)
                    {
                        pc += code.w;
                    }
                }
                break;

                case OpCode.ONFJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    if (tag(top.get(-1)) == lua_Type.LUA_T_NIL)
                    {
                        pc += code.w;
                    }
                }
                break;

                case OpCode.JMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    pc += code.w;
                }
                break;

                case OpCode.UPJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    pc -= code.w;
                }
                break;

                case OpCode.IFFJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    top.dec();
                    if (tag(top.get()) == lua_Type.LUA_T_NIL)
                    {
                        pc += code.w;
                    }
                }
                break;

                case OpCode.IFFUPJMP:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    top.dec();
                    if (tag(top.get()) == lua_Type.LUA_T_NIL)
                    {
                        pc -= code.w;
                    }
                }
                break;

                case OpCode.POP: top.dec(); break;

                case OpCode.CALLFUNC:
                {
                    int     nParams  = pc[0]; pc.inc();
                    int     nResults = pc[0]; pc.inc();
                    Object_ func     = top.get(-1 - nParams);                               /* function is below parameters */
                    StkId   newBase  = ObjectRef.minus(top, stack) - nParams;
                    do_call(func, newBase, nResults, newBase - 1);
                }
                break;

                case OpCode.RETCODE0:
                    return(@base);

                case OpCode.RETCODE:
                    return(@base + pc[0]);

                case OpCode.SETFUNCTION:
                {
                    CodeCode file = new CodeCode();
                    CodeWord func = new CodeWord();
                    get_code(file, pc);
                    get_word(func, pc);
                    lua_pushfunction(new CharPtr(file.b), func.w);
                }
                break;

                case OpCode.SETLINE:
                {
                    CodeWord code = new CodeWord();
                    get_word(code, pc);
                    lua_debugline = code.w;
                }
                break;

                case OpCode.RESET:
                    lua_popfunction();
                    break;

                default:
                    lua_error("internal error - opcode doesn't match");
                    break;
                }
            }
        }
 public CodeFloat_m_struct(CodeFloat parent)
 {
     this.parent_ = parent;
 }