diff --git a/lapi.c b/lapi.c index 073baa4d..0e99abef 100644 --- a/lapi.c +++ b/lapi.c @@ -574,7 +574,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { LUA_API void lua_pushboolean (lua_State *L, int b) { lua_lock(L); - setbvalue(s2v(L->top), (b != 0)); /* ensure that true is 1 */ + if (b) + setbtvalue(s2v(L->top)); + else + setbfvalue(s2v(L->top)); api_incr_top(L); lua_unlock(L); } diff --git a/lcode.c b/lcode.c index 4fc97e2b..72a8820b 100644 --- a/lcode.c +++ b/lcode.c @@ -84,8 +84,11 @@ int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) { if (hasjumps(e)) return 0; /* not a constant */ switch (e->k) { - case VFALSE: case VTRUE: - setbvalue(v, e->k == VTRUE); + case VFALSE: + setbfvalue(v); + return 1; + case VTRUE: + setbtvalue(v); return 1; case VNIL: setnilvalue(v); @@ -604,11 +607,21 @@ static int luaK_numberK (FuncState *fs, lua_Number r) { /* -** Add a boolean to list of constants and return its index. +** Add a false to list of constants and return its index. */ -static int boolK (FuncState *fs, int b) { +static int boolF (FuncState *fs) { TValue o; - setbvalue(&o, b); + setbfvalue(&o); + return addk(fs, &o, &o); /* use boolean itself as key */ +} + + +/* +** Add a true to list of constants and return its index. +*/ +static int boolT (FuncState *fs) { + TValue o; + setbtvalue(&o); return addk(fs, &o, &o); /* use boolean itself as key */ } @@ -671,8 +684,11 @@ static void const2exp (TValue *v, expdesc *e) { case LUA_TNUMFLT: e->k = VKFLT; e->u.nval = fltvalue(v); break; - case LUA_TBOOLEAN: - e->k = bvalue(v) ? VTRUE : VFALSE; + case LUA_TFALSE: + e->k = VFALSE; + break; + case LUA_TTRUE: + e->k = VTRUE; break; case LUA_TNIL: e->k = VNIL; @@ -801,8 +817,12 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { luaK_nil(fs, reg, 1); break; } - case VFALSE: case VTRUE: { - luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + case VFALSE: { + luaK_codeABC(fs, OP_LOADFALSE, reg, 0, 0); + break; + } + case VTRUE: { + luaK_codeABC(fs, OP_LOADTRUE, reg, 0, 0); break; } case VKSTR: { @@ -852,9 +872,9 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { } -static int code_loadbool (FuncState *fs, int A, int b, int jump) { +static int code_loadbool (FuncState *fs, int A, OpCode op, int jump) { luaK_getlabel(fs); /* those instructions may be jump targets */ - return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); + return luaK_codeABC(fs, op, A, jump, 0); } @@ -888,8 +908,8 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { int p_t = NO_JUMP; /* position of an eventual LOAD true */ if (need_value(fs, e->t) || need_value(fs, e->f)) { int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); - p_f = code_loadbool(fs, reg, 0, 1); /* load false and skip next i. */ - p_t = code_loadbool(fs, reg, 1, 0); /* load true */ + p_f = code_loadbool(fs, reg, OP_LOADFALSE, 1); /* skip next inst. */ + p_t = code_loadbool(fs, reg, OP_LOADTRUE, 0); /* jump around these booleans if 'e' is not a test */ luaK_patchtohere(fs, fj); } @@ -963,8 +983,8 @@ static int luaK_exp2K (FuncState *fs, expdesc *e) { if (!hasjumps(e)) { int info; switch (e->k) { /* move constants to 'k' */ - case VTRUE: info = boolK(fs, 1); break; - case VFALSE: info = boolK(fs, 0); break; + case VTRUE: info = boolT(fs); break; + case VFALSE: info = boolF(fs); break; case VNIL: info = nilK(fs); break; case VKINT: info = luaK_intK(fs, e->u.ival); break; case VKFLT: info = luaK_numberK(fs, e->u.nval); break; diff --git a/ldebug.c b/ldebug.c index 6e16b0fb..c229f759 100644 --- a/ldebug.c +++ b/ldebug.c @@ -306,7 +306,7 @@ static void collectvalidlines (lua_State *L, Closure *f) { Table *t = luaH_new(L); /* new table to store active lines */ sethvalue2s(L, L->top, t); /* push it on stack */ api_incr_top(L); - setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ + setbtvalue(&v); /* boolean 'true' to be the value of all indices */ for (i = 0; i < p->sizelineinfo; i++) { /* for all lines with code */ currentline = nextline(p, currentline, i); luaH_setint(L, t, currentline, &v); /* table[line] = true */ diff --git a/ldump.c b/ldump.c index 9b501729..93cadbcc 100644 --- a/ldump.c +++ b/ldump.c @@ -113,10 +113,7 @@ static void DumpConstants (const Proto *f, DumpState *D) { const TValue *o = &f->k[i]; DumpByte(ttypetag(o), D); switch (ttypetag(o)) { - case LUA_TNIL: - break; - case LUA_TBOOLEAN: - DumpByte(bvalue(o), D); + case LUA_TNIL: case LUA_TFALSE: case LUA_TTRUE: break; case LUA_TNUMFLT: DumpNumber(fltvalue(o), D); diff --git a/ljumptab.h b/ljumptab.h index 37fe1e25..22e9575f 100644 --- a/ljumptab.h +++ b/ljumptab.h @@ -30,7 +30,8 @@ static void *disptab[NUM_OPCODES] = { &&L_OP_LOADF, &&L_OP_LOADK, &&L_OP_LOADKX, -&&L_OP_LOADBOOL, +&&L_OP_LOADFALSE, +&&L_OP_LOADTRUE, &&L_OP_LOADNIL, &&L_OP_GETUPVAL, &&L_OP_SETUPVAL, diff --git a/llex.c b/llex.c index f88057fe..90a7951f 100644 --- a/llex.c +++ b/llex.c @@ -136,7 +136,7 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) { if (isempty(o)) { /* not in use yet? */ /* boolean value does not need GC barrier; table is not a metatable, so it does not need to invalidate cache */ - setbvalue(o, 1); /* t[string] = true */ + setbtvalue(o); /* t[string] = true */ luaC_checkGC(L); } else { /* string already present */ diff --git a/lobject.h b/lobject.h index 7d30b46f..a529ceba 100644 --- a/lobject.h +++ b/lobject.h @@ -44,7 +44,6 @@ typedef union Value { struct GCObject *gc; /* collectable objects */ void *p; /* light userdata */ - int b; /* booleans */ lua_CFunction f; /* light C functions */ lua_Integer i; /* integer numbers */ lua_Number n; /* float numbers */ @@ -210,16 +209,20 @@ typedef StackValue *StkId; ** =================================================================== */ -#define ttisboolean(o) checktag((o), LUA_TBOOLEAN) -#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) +#define LUA_TFALSE (LUA_TBOOLEAN | (1 << 4)) +#define LUA_TTRUE (LUA_TBOOLEAN | (2 << 4)) -#define bvalueraw(v) ((v).b) +#define ttisboolean(o) checktype((o), LUA_TBOOLEAN) +#define ttisfalse(o) checktag((o), LUA_TFALSE) +#define ttistrue(o) checktag((o), LUA_TTRUE) -#define l_isfalse(o) (ttisboolean(o) ? bvalue(o) == 0 : ttisnil(o)) -#define setbvalue(obj,x) \ - { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } +#define l_isfalse(o) (ttisfalse(o) || ttisnil(o)) + + +#define setbfvalue(obj) settt_(obj, LUA_TFALSE) +#define setbtvalue(obj) settt_(obj, LUA_TTRUE) /* }================================================================== */ diff --git a/lopcodes.c b/lopcodes.c index 90d4cd1a..f5347a3c 100644 --- a/lopcodes.c +++ b/lopcodes.c @@ -24,7 +24,8 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADF */ ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADK */ ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADKX */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADBOOL */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADFALSE */ + ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADTRUE */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADNIL */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETUPVAL */ ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ diff --git a/lopcodes.h b/lopcodes.h index aec9dcbc..f512f15a 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -202,7 +202,8 @@ OP_LOADI,/* A sBx R[A] := sBx */ OP_LOADF,/* A sBx R[A] := (lua_Number)sBx */ OP_LOADK,/* A Bx R[A] := K[Bx] */ OP_LOADKX,/* A R[A] := K[extra arg] */ -OP_LOADBOOL,/* A B C R[A] := (Bool)B; if (C) pc++ */ +OP_LOADFALSE,/* A B R[A] := false; if (B) pc++ */ +OP_LOADTRUE,/* A R[A] := true */ OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */ OP_GETUPVAL,/* A B R[A] := UpValue[B] */ OP_SETUPVAL,/* A B UpValue[B] := R[A] */ diff --git a/lopnames.h b/lopnames.h index de347301..a2097a74 100644 --- a/lopnames.h +++ b/lopnames.h @@ -15,7 +15,8 @@ static const char *const opnames[] = { "LOADF", "LOADK", "LOADKX", - "LOADBOOL", + "LOADFALSE", + "LOADTRUE", "LOADNIL", "GETUPVAL", "SETUPVAL", diff --git a/ltable.c b/ltable.c index cc3c3dd4..ebd45dda 100644 --- a/ltable.c +++ b/ltable.c @@ -143,8 +143,10 @@ static Node *mainposition (const Table *t, int ktt, const Value *kvl) { return hashstr(t, tsvalueraw(*kvl)); case LUA_TLNGSTR: return hashpow2(t, luaS_hashlongstr(tsvalueraw(*kvl))); - case LUA_TBOOLEAN: - return hashboolean(t, bvalueraw(*kvl)); + case LUA_TFALSE: + return hashboolean(t, 0); + case LUA_TTRUE: + return hashboolean(t, 1); case LUA_TLIGHTUSERDATA: return hashpointer(t, pvalueraw(*kvl)); case LUA_TLCF: @@ -175,14 +177,12 @@ static int equalkey (const TValue *k1, const Node *n2) { if (rawtt(k1) != keytt(n2)) /* not the same variants? */ return 0; /* cannot be same key */ switch (ttypetag(k1)) { - case LUA_TNIL: + case LUA_TNIL: case LUA_TFALSE: case LUA_TTRUE: return 1; case LUA_TNUMINT: return (ivalue(k1) == keyival(n2)); case LUA_TNUMFLT: return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2))); - case LUA_TBOOLEAN: - return bvalue(k1) == bvalueraw(keyval(n2)); case LUA_TLIGHTUSERDATA: return pvalue(k1) == pvalueraw(keyval(n2)); case LUA_TLCF: diff --git a/lundump.c b/lundump.c index 8f2a490c..45e0b637 100644 --- a/lundump.c +++ b/lundump.c @@ -160,8 +160,11 @@ static void LoadConstants (LoadState *S, Proto *f) { case LUA_TNIL: setnilvalue(o); break; - case LUA_TBOOLEAN: - setbvalue(o, LoadByte(S)); + case LUA_TFALSE: + setbfvalue(o); + break; + case LUA_TTRUE: + setbtvalue(o); break; case LUA_TNUMFLT: setfltvalue(o, LoadNumber(S)); diff --git a/lvm.c b/lvm.c index 78c0ebe7..656def81 100644 --- a/lvm.c +++ b/lvm.c @@ -577,10 +577,9 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { } /* values have same type and same variant */ switch (ttypetag(t1)) { - case LUA_TNIL: return 1; + case LUA_TNIL: case LUA_TFALSE: case LUA_TTRUE: return 1; case LUA_TNUMINT: return (ivalue(t1) == ivalue(t2)); case LUA_TNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2)); - case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1! */ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); case LUA_TLCF: return fvalue(t1) == fvalue(t2); case LUA_TSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2)); @@ -1182,9 +1181,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { setobj2s(L, ra, rb); vmbreak; } - vmcase(OP_LOADBOOL) { - setbvalue(s2v(ra), GETARG_B(i)); - if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ + vmcase(OP_LOADFALSE) { + setbfvalue(s2v(ra)); + if (GETARG_B(i)) pc++; /* if B, skip next instruction */ + vmbreak; + } + vmcase(OP_LOADTRUE) { + setbtvalue(s2v(ra)); vmbreak; } vmcase(OP_LOADNIL) { @@ -1503,8 +1506,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) { } vmcase(OP_NOT) { TValue *rb = vRB(i); - int nrb = l_isfalse(rb); /* next assignment may change this value */ - setbvalue(s2v(ra), nrb); + if (l_isfalse(rb)) + setbtvalue(s2v(ra)); + else + setbfvalue(s2v(ra)); vmbreak; } vmcase(OP_LEN) { diff --git a/testes/code.lua b/testes/code.lua index e12f3f91..34b04668 100644 --- a/testes/code.lua +++ b/testes/code.lua @@ -144,10 +144,10 @@ check(function (a,b,c,d) return a..b..c..d end, 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN1') -- not -check(function () return not not nil end, 'LOADBOOL', 'RETURN1') -check(function () return not not kFalse end, 'LOADBOOL', 'RETURN1') -check(function () return not not true end, 'LOADBOOL', 'RETURN1') -check(function () return not not k3 end, 'LOADBOOL', 'RETURN1') +check(function () return not not nil end, 'LOADFALSE', 'RETURN1') +check(function () return not not kFalse end, 'LOADFALSE', 'RETURN1') +check(function () return not not true end, 'LOADTRUE', 'RETURN1') +check(function () return not not k3 end, 'LOADTRUE', 'RETURN1') -- direct access to locals check(function () @@ -194,7 +194,7 @@ check(function () local a,b a[kTrue] = false end, - 'LOADNIL', 'LOADBOOL', 'SETTABLE', 'RETURN0') + 'LOADNIL', 'LOADTRUE', 'SETTABLE', 'RETURN0') -- equalities