Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
953 changes: 953 additions & 0 deletions docs/TYPE_MODERNIZATION_ANALYSIS.md

Large diffs are not rendered by default.

40 changes: 19 additions & 21 deletions src/compiler/lcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ int FuncState::condjump(OpCode o, int A, int B, int C, int k) {
*/
Instruction *FuncState::getjumpcontrol(int position) {
Instruction *pi = &getProto()->getCode()[position];
if (position >= 1 && testTMode(InstructionView(*(pi-1)).opcode()))
if (position >= 1 && InstructionView(*(pi-1)).testTMode())
return pi-1;
else
return pi;
Expand Down Expand Up @@ -663,9 +663,10 @@ void FuncState::codeABRK(OpCode o, int A, int B, expdesc *ec) {
*/
void FuncState::negatecondition(expdesc *e) {
Instruction *instr = getjumpcontrol(e->getInfo());
lua_assert(testTMode(InstructionView(*instr).opcode()) && InstructionView(*instr).opcode() != OP_TESTSET &&
InstructionView(*instr).opcode() != OP_TEST);
SETARG_k(*instr, static_cast<unsigned int>(InstructionView(*instr).k() ^ 1));
InstructionView view(*instr);
lua_assert(view.testTMode() && view.opcode() != OP_TESTSET &&
view.opcode() != OP_TEST);
SETARG_k(*instr, static_cast<unsigned int>(view.k() ^ 1));
}

/*
Expand Down Expand Up @@ -732,52 +733,52 @@ int FuncState::isKstr(expdesc *e) {
/*
** Check whether expression 'e' is a literal integer.
*/
static int isKint (expdesc *e) {
static bool isKint (expdesc *e) {
return (e->getKind() == VKINT && !hasjumps(e));
}

/*
** Check whether expression 'e' is a literal integer in
** proper range to fit in register C
*/
static int isCint (expdesc *e) {
static bool isCint (expdesc *e) {
return isKint(e) && (l_castS2U(e->getIntValue()) <= l_castS2U(MAXARG_C));
}

/*
** Check whether expression 'e' is a literal integer in
** proper range to fit in register sC
*/
static int isSCint (expdesc *e) {
static bool isSCint (expdesc *e) {
return isKint(e) && fitsC(e->getIntValue());
}

/*
** Check whether expression 'e' is a literal integer or float in
** proper range to fit in a register (sB or sC).
*/
static int isSCnumber (expdesc *e, int *pi, int *isfloat) {
static bool isSCnumber (expdesc *e, int *pi, int *isfloat) {
lua_Integer i;
if (e->getKind() == VKINT)
i = e->getIntValue();
else if (e->getKind() == VKFLT && luaV_flttointeger(e->getFloatValue(), &i, F2Imod::F2Ieq))
*isfloat = 1;
else
return 0; /* not a number */
return false; /* not a number */
if (!hasjumps(e) && fitsC(i)) {
*pi = int2sC(cast_int(i));
return 1;
return true;
}
else
return 0;
return false;
}

/*
** Return false if folding can raise an error.
** Bitwise operations need operands convertible to integers; division
** operations cannot have 0 as divisor.
*/
static int validop (int op, TValue *v1, TValue *v2) {
static bool validop (int op, TValue *v1, TValue *v2) {
switch (op) {
case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */
Expand All @@ -787,7 +788,7 @@ static int validop (int op, TValue *v1, TValue *v2) {
}
case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */
return (nvalue(v2) != 0);
default: return 1; /* everything else is valid */
default: return true; /* everything else is valid */
}
}

Expand Down Expand Up @@ -1485,8 +1486,7 @@ int FuncState::getlabel() {
return getPC();
}

void FuncState::prefix(int opr, expdesc *e, int line) {
UnOpr op = static_cast<UnOpr>(opr);
void FuncState::prefix(UnOpr op, expdesc *e, int line) {
expdesc ef;
ef.setKind(VKINT);
ef.setIntValue(0);
Expand All @@ -1495,7 +1495,7 @@ void FuncState::prefix(int opr, expdesc *e, int line) {
dischargevars(e);
switch (op) {
case UnOpr::OPR_MINUS: case UnOpr::OPR_BNOT: /* use 'ef' as fake 2nd operand */
if (constfolding(cast_int(opr + LUA_OPUNM), e, &ef))
if (constfolding(cast_int(op) + LUA_OPUNM, e, &ef))
break;
/* else */ /* FALLTHROUGH */
case UnOpr::OPR_LEN:
Expand All @@ -1506,8 +1506,7 @@ void FuncState::prefix(int opr, expdesc *e, int line) {
}
}

void FuncState::infix(int opr, expdesc *v) {
BinOpr op = static_cast<BinOpr>(opr);
void FuncState::infix(BinOpr op, expdesc *v) {
dischargevars(v);
switch (op) {
case BinOpr::OPR_AND: {
Expand Down Expand Up @@ -1551,10 +1550,9 @@ void FuncState::infix(int opr, expdesc *v) {
}
}

void FuncState::posfix(int opr, expdesc *e1, expdesc *e2, int line) {
BinOpr op = static_cast<BinOpr>(opr);
void FuncState::posfix(BinOpr op, expdesc *e1, expdesc *e2, int line) {
dischargevars(e2);
if (foldbinop(op) && constfolding(cast_int(opr + LUA_OPADD), e1, e2))
if (foldbinop(op) && constfolding(cast_int(op) + LUA_OPADD, e1, e2))
return; /* done by folding */
switch (op) {
case BinOpr::OPR_AND: {
Expand Down
12 changes: 7 additions & 5 deletions src/compiler/lopcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
** it results in multiple values.
*/
int luaP_isOT (Instruction i) {
OpCode op = static_cast<OpCode>(InstructionView(i).opcode());
InstructionView view(i);
OpCode op = static_cast<OpCode>(view.opcode());
switch (op) {
case OP_TAILCALL: return 1;
default:
return testOTMode(op) && InstructionView(i).c() == 0;
return view.testOTMode() && view.c() == 0;
}
}

Expand All @@ -127,12 +128,13 @@ int luaP_isOT (Instruction i) {
** it accepts multiple results.
*/
int luaP_isIT (Instruction i) {
OpCode op = static_cast<OpCode>(InstructionView(i).opcode());
InstructionView view(i);
OpCode op = static_cast<OpCode>(view.opcode());
switch (op) {
case OP_SETLIST:
return testITMode(InstructionView(i).opcode()) && InstructionView(i).vb() == 0;
return view.testITMode() && view.vb() == 0;
default:
return testITMode(InstructionView(i).opcode()) && InstructionView(i).b() == 0;
return view.testITMode() && view.b() == 0;
}
}

34 changes: 34 additions & 0 deletions src/compiler/lopcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,15 @@ class InstructionView {
constexpr int sj() const noexcept {
return getarg(inst_, POS_sJ, SIZE_sJ) - OFFSET_sJ;
}

/* Instruction property accessors - encapsulate luaP_opmodes array access */
/* Defined below after luaP_opmodes declaration */
inline OpMode getOpMode() const noexcept;
inline bool testAMode() const noexcept;
inline bool testTMode() const noexcept;
inline bool testITMode() const noexcept;
inline bool testOTMode() const noexcept;
inline bool testMMMode() const noexcept;
};


Expand Down Expand Up @@ -565,6 +574,31 @@ inline bool testMMMode(int m) noexcept {
return (luaP_opmodes[m] & (1 << 7)) != 0;
}

/* InstructionView property method implementations (defined after luaP_opmodes) */
inline OpMode InstructionView::getOpMode() const noexcept {
return static_cast<OpMode>(luaP_opmodes[opcode()] & 7);
}

inline bool InstructionView::testAMode() const noexcept {
return (luaP_opmodes[opcode()] & (1 << 3)) != 0;
}

inline bool InstructionView::testTMode() const noexcept {
return (luaP_opmodes[opcode()] & (1 << 4)) != 0;
}

inline bool InstructionView::testITMode() const noexcept {
return (luaP_opmodes[opcode()] & (1 << 5)) != 0;
}

inline bool InstructionView::testOTMode() const noexcept {
return (luaP_opmodes[opcode()] & (1 << 6)) != 0;
}

inline bool InstructionView::testMMMode() const noexcept {
return (luaP_opmodes[opcode()] & (1 << 7)) != 0;
}


LUAI_FUNC int luaP_isOT (Instruction i);
LUAI_FUNC int luaP_isIT (Instruction i);
Expand Down
9 changes: 4 additions & 5 deletions src/compiler/lparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -577,11 +577,10 @@ class FuncState {
void patchtohere(int list);
void concat(int *l1, int l2);
int getlabel();
// Note: prefix, infix, posfix use UnOpr/BinOpr types from lcode.h
// We use int here to avoid circular dependency, will cast in implementation
void prefix(int op, expdesc *v, int line);
void infix(int op, expdesc *v);
void posfix(int op, expdesc *v1, expdesc *v2, int line);
// Operator functions use strongly-typed enum classes for type safety
void prefix(UnOpr op, expdesc *v, int line);
void infix(BinOpr op, expdesc *v);
void posfix(BinOpr op, expdesc *v1, expdesc *v2, int line);
void settablesize(int pcpos, unsigned ra, unsigned asize, unsigned hsize);
void setlist(int base, int nelems, int tostore);
void finish();
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ BinOpr Parser::subexpr( expdesc *v, int limit) {
int line = ls->getLineNumber();
ls->nextToken(); /* skip operator */
subexpr(v, UNARY_PRIORITY);
fs->prefix(static_cast<int>(uop), v, line);
fs->prefix(uop, v, line);
}
else simpleexp(v);
/* expand while operators have priorities higher than 'limit' */
Expand All @@ -889,10 +889,10 @@ BinOpr Parser::subexpr( expdesc *v, int limit) {
BinOpr nextop;
int line = ls->getLineNumber();
ls->nextToken(); /* skip operator */
fs->infix(static_cast<int>(op), v);
fs->infix(op, v);
/* read sub-expression with higher priority */
nextop = subexpr(&v2, priority[static_cast<int>(op)].right);
fs->posfix(static_cast<int>(op), v, &v2, line);
fs->posfix(op, v, &v2, line);
op = nextop;
}
leavelevel(ls);
Expand Down
13 changes: 7 additions & 6 deletions src/core/ldebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,16 +456,17 @@ static int findsetreg (const Proto *p, int lastpc, int reg) {
int pc;
int setreg = -1; /* keep last instruction that changed 'reg' */
int jmptarget = 0; /* any code before this address is conditional */
if (testMMMode(InstructionView(p->getCode()[lastpc]).opcode()))
if (InstructionView(p->getCode()[lastpc]).testMMMode())
lastpc--; /* previous instruction was not actually executed */
for (pc = 0; pc < lastpc; pc++) {
Instruction i = p->getCode()[pc];
OpCode op = static_cast<OpCode>(InstructionView(i).opcode());
int a = InstructionView(i).a();
InstructionView view(i);
OpCode op = static_cast<OpCode>(view.opcode());
int a = view.a();
int change; /* true if current instruction changed 'reg' */
switch (op) {
case OP_LOADNIL: { /* set registers from 'a' to 'a+b' */
int b = InstructionView(i).b();
int b = view.b();
change = (a <= reg && reg <= a + b);
break;
}
Expand All @@ -479,7 +480,7 @@ static int findsetreg (const Proto *p, int lastpc, int reg) {
break;
}
case OP_JMP: { /* doesn't change registers, but changes 'jmptarget' */
int b = InstructionView(i).sj();
int b = view.sj();
int dest = pc + 1 + b;
/* jump does not skip 'lastpc' and is larger than current one? */
if (dest <= lastpc && dest > jmptarget)
Expand All @@ -488,7 +489,7 @@ static int findsetreg (const Proto *p, int lastpc, int reg) {
break;
}
default: /* any instruction that sets A */
change = (testAMode(op) && reg == a);
change = (view.testAMode() && reg == a);
break;
}
if (change)
Expand Down
16 changes: 8 additions & 8 deletions src/testing/ltests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,19 +303,19 @@ void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) {
** continue to be visited in all collections, and therefore can point to
** new objects. They, and only they, are old but gray.)
*/
static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
if (isdead(g,t)) return 0;
static bool testobjref1 (global_State *g, GCObject *f, GCObject *t) {
if (isdead(g,t)) return false;
if (g->isSweepPhase())
return 1; /* no invariants */
return true; /* no invariants */
else if (g->getGCKind() != GCKind::GenerationalMinor)
return !(isblack(f) && iswhite(t)); /* basic incremental invariant */
else { /* generational mode */
if ((getage(f) == GCAge::Old && isblack(f)) && !isold(t))
return 0;
return false;
if ((getage(f) == GCAge::Old1 || getage(f) == GCAge::Touched2) &&
getage(t) == GCAge::New)
return 0;
return 1;
return false;
return true;
}
}

Expand Down Expand Up @@ -374,8 +374,8 @@ void lua_printvalue (TValue *v) {
}


static int testobjref (global_State *g, GCObject *f, GCObject *t) {
int r1 = testobjref1(g, f, t);
static bool testobjref (global_State *g, GCObject *f, GCObject *t) {
bool r1 = testobjref1(g, f, t);
if (!r1) {
printf("%d(%02X) - ", static_cast<int>(g->getGCState()), g->getCurrentWhite());
printobj(g, f);
Expand Down
Loading