Skip to content

Commit 7ddb44e

Browse files
committed
Phase 112 Part 2: Encapsulate opcode properties in InstructionView
Moved luaP_opmodes array access into InstructionView methods: - Added getOpMode() method - returns OpMode enum - Added testAMode() method - tests if instruction sets register A - Added testTMode() method - tests if instruction is a test/jump - Added testITMode() method - tests if instruction uses top from previous - Added testOTMode() method - tests if instruction sets top for next - Added testMMMode() method - tests if instruction is metamethod call Impact: - Better encapsulation - opcode properties accessed through InstructionView - Cleaner code - view.testTMode() instead of testTMode(view.opcode()) - Eliminated redundant InstructionView creations at call sites - Zero-cost abstraction - all methods are inline Files changed: - src/compiler/lopcodes.h (method declarations and implementations) - src/compiler/lopcodes.cpp (luaP_isIT, luaP_isOT - use view methods) - src/compiler/lcode.cpp (getjumpcontrol, negatecondition - use view methods) - src/core/ldebug.cpp (findsetreg - use view methods, eliminated duplicate views) Performance: 4.33s avg (baseline 4.20s, exactly at target!) All tests passing: "final OK !!!"
1 parent e5d33b0 commit 7ddb44e

File tree

4 files changed

+53
-15
lines changed

4 files changed

+53
-15
lines changed

src/compiler/lcode.cpp

Lines changed: 5 additions & 4 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
/*

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/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)

0 commit comments

Comments
 (0)