/* ** 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; }