Skip to content

Commit cb5a5a0

Browse files
authored
Merge pull request #48 from NiceAndPeter/claude/refactor-static-cast-01Mrj8MFXifWmTNwn6dYYCwF
Replace static_cast with better type alternatives
2 parents 17291bf + a7788d5 commit cb5a5a0

File tree

8 files changed

+1035
-48
lines changed

8 files changed

+1035
-48
lines changed

docs/TYPE_MODERNIZATION_ANALYSIS.md

Lines changed: 953 additions & 0 deletions
Large diffs are not rendered by default.

src/compiler/lcode.cpp

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ int FuncState::condjump(OpCode o, int A, int B, int C, int k) {
126126
*/
127127
Instruction *FuncState::getjumpcontrol(int position) {
128128
Instruction *pi = &getProto()->getCode()[position];
129-
if (position >= 1 && testTMode(InstructionView(*(pi-1)).opcode()))
129+
if (position >= 1 && InstructionView(*(pi-1)).testTMode())
130130
return pi-1;
131131
else
132132
return pi;
@@ -663,9 +663,10 @@ void FuncState::codeABRK(OpCode o, int A, int B, expdesc *ec) {
663663
*/
664664
void FuncState::negatecondition(expdesc *e) {
665665
Instruction *instr = getjumpcontrol(e->getInfo());
666-
lua_assert(testTMode(InstructionView(*instr).opcode()) && InstructionView(*instr).opcode() != OP_TESTSET &&
667-
InstructionView(*instr).opcode() != OP_TEST);
668-
SETARG_k(*instr, static_cast<unsigned int>(InstructionView(*instr).k() ^ 1));
666+
InstructionView view(*instr);
667+
lua_assert(view.testTMode() && view.opcode() != OP_TESTSET &&
668+
view.opcode() != OP_TEST);
669+
SETARG_k(*instr, static_cast<unsigned int>(view.k() ^ 1));
669670
}
670671

671672
/*
@@ -732,52 +733,52 @@ int FuncState::isKstr(expdesc *e) {
732733
/*
733734
** Check whether expression 'e' is a literal integer.
734735
*/
735-
static int isKint (expdesc *e) {
736+
static bool isKint (expdesc *e) {
736737
return (e->getKind() == VKINT && !hasjumps(e));
737738
}
738739

739740
/*
740741
** Check whether expression 'e' is a literal integer in
741742
** proper range to fit in register C
742743
*/
743-
static int isCint (expdesc *e) {
744+
static bool isCint (expdesc *e) {
744745
return isKint(e) && (l_castS2U(e->getIntValue()) <= l_castS2U(MAXARG_C));
745746
}
746747

747748
/*
748749
** Check whether expression 'e' is a literal integer in
749750
** proper range to fit in register sC
750751
*/
751-
static int isSCint (expdesc *e) {
752+
static bool isSCint (expdesc *e) {
752753
return isKint(e) && fitsC(e->getIntValue());
753754
}
754755

755756
/*
756757
** Check whether expression 'e' is a literal integer or float in
757758
** proper range to fit in a register (sB or sC).
758759
*/
759-
static int isSCnumber (expdesc *e, int *pi, int *isfloat) {
760+
static bool isSCnumber (expdesc *e, int *pi, int *isfloat) {
760761
lua_Integer i;
761762
if (e->getKind() == VKINT)
762763
i = e->getIntValue();
763764
else if (e->getKind() == VKFLT && luaV_flttointeger(e->getFloatValue(), &i, F2Imod::F2Ieq))
764765
*isfloat = 1;
765766
else
766-
return 0; /* not a number */
767+
return false; /* not a number */
767768
if (!hasjumps(e) && fitsC(i)) {
768769
*pi = int2sC(cast_int(i));
769-
return 1;
770+
return true;
770771
}
771772
else
772-
return 0;
773+
return false;
773774
}
774775

775776
/*
776777
** Return false if folding can raise an error.
777778
** Bitwise operations need operands convertible to integers; division
778779
** operations cannot have 0 as divisor.
779780
*/
780-
static int validop (int op, TValue *v1, TValue *v2) {
781+
static bool validop (int op, TValue *v1, TValue *v2) {
781782
switch (op) {
782783
case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
783784
case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */
@@ -787,7 +788,7 @@ static int validop (int op, TValue *v1, TValue *v2) {
787788
}
788789
case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */
789790
return (nvalue(v2) != 0);
790-
default: return 1; /* everything else is valid */
791+
default: return true; /* everything else is valid */
791792
}
792793
}
793794

@@ -1485,8 +1486,7 @@ int FuncState::getlabel() {
14851486
return getPC();
14861487
}
14871488

1488-
void FuncState::prefix(int opr, expdesc *e, int line) {
1489-
UnOpr op = static_cast<UnOpr>(opr);
1489+
void FuncState::prefix(UnOpr op, expdesc *e, int line) {
14901490
expdesc ef;
14911491
ef.setKind(VKINT);
14921492
ef.setIntValue(0);
@@ -1495,7 +1495,7 @@ void FuncState::prefix(int opr, expdesc *e, int line) {
14951495
dischargevars(e);
14961496
switch (op) {
14971497
case UnOpr::OPR_MINUS: case UnOpr::OPR_BNOT: /* use 'ef' as fake 2nd operand */
1498-
if (constfolding(cast_int(opr + LUA_OPUNM), e, &ef))
1498+
if (constfolding(cast_int(op) + LUA_OPUNM, e, &ef))
14991499
break;
15001500
/* else */ /* FALLTHROUGH */
15011501
case UnOpr::OPR_LEN:
@@ -1506,8 +1506,7 @@ void FuncState::prefix(int opr, expdesc *e, int line) {
15061506
}
15071507
}
15081508

1509-
void FuncState::infix(int opr, expdesc *v) {
1510-
BinOpr op = static_cast<BinOpr>(opr);
1509+
void FuncState::infix(BinOpr op, expdesc *v) {
15111510
dischargevars(v);
15121511
switch (op) {
15131512
case BinOpr::OPR_AND: {
@@ -1551,10 +1550,9 @@ void FuncState::infix(int opr, expdesc *v) {
15511550
}
15521551
}
15531552

1554-
void FuncState::posfix(int opr, expdesc *e1, expdesc *e2, int line) {
1555-
BinOpr op = static_cast<BinOpr>(opr);
1553+
void FuncState::posfix(BinOpr op, expdesc *e1, expdesc *e2, int line) {
15561554
dischargevars(e2);
1557-
if (foldbinop(op) && constfolding(cast_int(opr + LUA_OPADD), e1, e2))
1555+
if (foldbinop(op) && constfolding(cast_int(op) + LUA_OPADD, e1, e2))
15581556
return; /* done by folding */
15591557
switch (op) {
15601558
case BinOpr::OPR_AND: {

src/compiler/lopcodes.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,12 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
113113
** it results in multiple values.
114114
*/
115115
int luaP_isOT (Instruction i) {
116-
OpCode op = static_cast<OpCode>(InstructionView(i).opcode());
116+
InstructionView view(i);
117+
OpCode op = static_cast<OpCode>(view.opcode());
117118
switch (op) {
118119
case OP_TAILCALL: return 1;
119120
default:
120-
return testOTMode(op) && InstructionView(i).c() == 0;
121+
return view.testOTMode() && view.c() == 0;
121122
}
122123
}
123124

@@ -127,12 +128,13 @@ int luaP_isOT (Instruction i) {
127128
** it accepts multiple results.
128129
*/
129130
int luaP_isIT (Instruction i) {
130-
OpCode op = static_cast<OpCode>(InstructionView(i).opcode());
131+
InstructionView view(i);
132+
OpCode op = static_cast<OpCode>(view.opcode());
131133
switch (op) {
132134
case OP_SETLIST:
133-
return testITMode(InstructionView(i).opcode()) && InstructionView(i).vb() == 0;
135+
return view.testITMode() && view.vb() == 0;
134136
default:
135-
return testITMode(InstructionView(i).opcode()) && InstructionView(i).b() == 0;
137+
return view.testITMode() && view.b() == 0;
136138
}
137139
}
138140

src/compiler/lopcodes.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,15 @@ class InstructionView {
288288
constexpr int sj() const noexcept {
289289
return getarg(inst_, POS_sJ, SIZE_sJ) - OFFSET_sJ;
290290
}
291+
292+
/* Instruction property accessors - encapsulate luaP_opmodes array access */
293+
/* Defined below after luaP_opmodes declaration */
294+
inline OpMode getOpMode() const noexcept;
295+
inline bool testAMode() const noexcept;
296+
inline bool testTMode() const noexcept;
297+
inline bool testITMode() const noexcept;
298+
inline bool testOTMode() const noexcept;
299+
inline bool testMMMode() const noexcept;
291300
};
292301

293302

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

577+
/* InstructionView property method implementations (defined after luaP_opmodes) */
578+
inline OpMode InstructionView::getOpMode() const noexcept {
579+
return static_cast<OpMode>(luaP_opmodes[opcode()] & 7);
580+
}
581+
582+
inline bool InstructionView::testAMode() const noexcept {
583+
return (luaP_opmodes[opcode()] & (1 << 3)) != 0;
584+
}
585+
586+
inline bool InstructionView::testTMode() const noexcept {
587+
return (luaP_opmodes[opcode()] & (1 << 4)) != 0;
588+
}
589+
590+
inline bool InstructionView::testITMode() const noexcept {
591+
return (luaP_opmodes[opcode()] & (1 << 5)) != 0;
592+
}
593+
594+
inline bool InstructionView::testOTMode() const noexcept {
595+
return (luaP_opmodes[opcode()] & (1 << 6)) != 0;
596+
}
597+
598+
inline bool InstructionView::testMMMode() const noexcept {
599+
return (luaP_opmodes[opcode()] & (1 << 7)) != 0;
600+
}
601+
568602

569603
LUAI_FUNC int luaP_isOT (Instruction i);
570604
LUAI_FUNC int luaP_isIT (Instruction i);

src/compiler/lparser.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -577,11 +577,10 @@ class FuncState {
577577
void patchtohere(int list);
578578
void concat(int *l1, int l2);
579579
int getlabel();
580-
// Note: prefix, infix, posfix use UnOpr/BinOpr types from lcode.h
581-
// We use int here to avoid circular dependency, will cast in implementation
582-
void prefix(int op, expdesc *v, int line);
583-
void infix(int op, expdesc *v);
584-
void posfix(int op, expdesc *v1, expdesc *v2, int line);
580+
// Operator functions use strongly-typed enum classes for type safety
581+
void prefix(UnOpr op, expdesc *v, int line);
582+
void infix(BinOpr op, expdesc *v);
583+
void posfix(BinOpr op, expdesc *v1, expdesc *v2, int line);
585584
void settablesize(int pcpos, unsigned ra, unsigned asize, unsigned hsize);
586585
void setlist(int base, int nelems, int tostore);
587586
void finish();

src/compiler/parser.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ BinOpr Parser::subexpr( expdesc *v, int limit) {
879879
int line = ls->getLineNumber();
880880
ls->nextToken(); /* skip operator */
881881
subexpr(v, UNARY_PRIORITY);
882-
fs->prefix(static_cast<int>(uop), v, line);
882+
fs->prefix(uop, v, line);
883883
}
884884
else simpleexp(v);
885885
/* expand while operators have priorities higher than 'limit' */
@@ -889,10 +889,10 @@ BinOpr Parser::subexpr( expdesc *v, int limit) {
889889
BinOpr nextop;
890890
int line = ls->getLineNumber();
891891
ls->nextToken(); /* skip operator */
892-
fs->infix(static_cast<int>(op), v);
892+
fs->infix(op, v);
893893
/* read sub-expression with higher priority */
894894
nextop = subexpr(&v2, priority[static_cast<int>(op)].right);
895-
fs->posfix(static_cast<int>(op), v, &v2, line);
895+
fs->posfix(op, v, &v2, line);
896896
op = nextop;
897897
}
898898
leavelevel(ls);

src/core/ldebug.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,16 +456,17 @@ static int findsetreg (const Proto *p, int lastpc, int reg) {
456456
int pc;
457457
int setreg = -1; /* keep last instruction that changed 'reg' */
458458
int jmptarget = 0; /* any code before this address is conditional */
459-
if (testMMMode(InstructionView(p->getCode()[lastpc]).opcode()))
459+
if (InstructionView(p->getCode()[lastpc]).testMMMode())
460460
lastpc--; /* previous instruction was not actually executed */
461461
for (pc = 0; pc < lastpc; pc++) {
462462
Instruction i = p->getCode()[pc];
463-
OpCode op = static_cast<OpCode>(InstructionView(i).opcode());
464-
int a = InstructionView(i).a();
463+
InstructionView view(i);
464+
OpCode op = static_cast<OpCode>(view.opcode());
465+
int a = view.a();
465466
int change; /* true if current instruction changed 'reg' */
466467
switch (op) {
467468
case OP_LOADNIL: { /* set registers from 'a' to 'a+b' */
468-
int b = InstructionView(i).b();
469+
int b = view.b();
469470
change = (a <= reg && reg <= a + b);
470471
break;
471472
}
@@ -479,7 +480,7 @@ static int findsetreg (const Proto *p, int lastpc, int reg) {
479480
break;
480481
}
481482
case OP_JMP: { /* doesn't change registers, but changes 'jmptarget' */
482-
int b = InstructionView(i).sj();
483+
int b = view.sj();
483484
int dest = pc + 1 + b;
484485
/* jump does not skip 'lastpc' and is larger than current one? */
485486
if (dest <= lastpc && dest > jmptarget)
@@ -488,7 +489,7 @@ static int findsetreg (const Proto *p, int lastpc, int reg) {
488489
break;
489490
}
490491
default: /* any instruction that sets A */
491-
change = (testAMode(op) && reg == a);
492+
change = (view.testAMode() && reg == a);
492493
break;
493494
}
494495
if (change)

src/testing/ltests.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -303,19 +303,19 @@ void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) {
303303
** continue to be visited in all collections, and therefore can point to
304304
** new objects. They, and only they, are old but gray.)
305305
*/
306-
static int testobjref1 (global_State *g, GCObject *f, GCObject *t) {
307-
if (isdead(g,t)) return 0;
306+
static bool testobjref1 (global_State *g, GCObject *f, GCObject *t) {
307+
if (isdead(g,t)) return false;
308308
if (g->isSweepPhase())
309-
return 1; /* no invariants */
309+
return true; /* no invariants */
310310
else if (g->getGCKind() != GCKind::GenerationalMinor)
311311
return !(isblack(f) && iswhite(t)); /* basic incremental invariant */
312312
else { /* generational mode */
313313
if ((getage(f) == GCAge::Old && isblack(f)) && !isold(t))
314-
return 0;
314+
return false;
315315
if ((getage(f) == GCAge::Old1 || getage(f) == GCAge::Touched2) &&
316316
getage(t) == GCAge::New)
317-
return 0;
318-
return 1;
317+
return false;
318+
return true;
319319
}
320320
}
321321

@@ -374,8 +374,8 @@ void lua_printvalue (TValue *v) {
374374
}
375375

376376

377-
static int testobjref (global_State *g, GCObject *f, GCObject *t) {
378-
int r1 = testobjref1(g, f, t);
377+
static bool testobjref (global_State *g, GCObject *f, GCObject *t) {
378+
bool r1 = testobjref1(g, f, t);
379379
if (!r1) {
380380
printf("%d(%02X) - ", static_cast<int>(g->getGCState()), g->getCurrentWhite());
381381
printobj(g, f);

0 commit comments

Comments
 (0)