From 5ef45948c74bfe0b6d4d4e10a71b9d17cfa4fdb7 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Nov 2025 21:49:01 +0000 Subject: [PATCH 1/3] Phase 120: Complete boolean return type conversions Converted 4 remaining predicate functions from int to bool: - iscleared() (gc_weak.cpp:52) - GC weak table predicate - isneg() (lobject.cpp:207) - Sign checking predicate - rawfinishnodeset() (ltable.cpp:1187) - Table insertion success check - checkbuffer() (lzio.cpp:46) - Buffer validation predicate Also updated call site in Table::setInt() to use bool variable. This completes the boolean modernization initiative started in Phases 113 and 117, bringing total bool conversions to 16 functions. Testing: - All tests pass (final OK !!!) - Performance: 4.45s avg (within acceptable bounds) Follows pattern from Phase 117 (5 predicates) and Phase 113 (7 predicates). --- src/memory/gc/gc_weak.cpp | 6 +++--- src/objects/lobject.cpp | 6 +++--- src/objects/ltable.cpp | 8 ++++---- src/serialization/lzio.cpp | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/memory/gc/gc_weak.cpp b/src/memory/gc/gc_weak.cpp index f3dc52d8..156a6166 100644 --- a/src/memory/gc/gc_weak.cpp +++ b/src/memory/gc/gc_weak.cpp @@ -49,11 +49,11 @@ ** For other objects: if really collected, cannot keep them; for objects ** being finalized, keep them in keys, but not in values. */ -static int iscleared(global_State* g, const GCObject* o) { - if (o == nullptr) return 0; /* non-collectable value */ +static bool iscleared(global_State* g, const GCObject* o) { + if (o == nullptr) return false; /* non-collectable value */ else if (novariant(o->getType()) == LUA_TSTRING) { markobject(g, o); /* strings are 'values', so are never weak */ - return 0; + return false; } else return iswhite(o); } diff --git a/src/objects/lobject.cpp b/src/objects/lobject.cpp index a5c12678..8465ce9b 100644 --- a/src/objects/lobject.cpp +++ b/src/objects/lobject.cpp @@ -204,10 +204,10 @@ lu_byte luaO_hexavalue (int c) { } -static int isneg (const char **s) { - if (**s == '-') { (*s)++; return 1; } +static bool isneg (const char **s) { + if (**s == '-') { (*s)++; return true; } else if (**s == '+') (*s)++; - return 0; + return false; } diff --git a/src/objects/ltable.cpp b/src/objects/ltable.cpp index 0fc889be..017d3a0c 100644 --- a/src/objects/ltable.cpp +++ b/src/objects/ltable.cpp @@ -1184,12 +1184,12 @@ static int finishnodeset (Table *t, TValue *slot, TValue *val) { } -static int rawfinishnodeset (TValue *slot, TValue *val) { +static bool rawfinishnodeset (TValue *slot, TValue *val) { if (isabstkey(slot)) - return 0; /* no slot with that key */ + return false; /* no slot with that key */ else { *slot = *val; - return 1; /* success */ + return true; /* success */ } } @@ -1522,7 +1522,7 @@ void Table::setInt(lua_State* L, lua_Integer key, TValue* value) { if (ik > 0) obj2arr(this, ik - 1, value); else { - int ok = rawfinishnodeset(getintfromhash(this, key), value); + bool ok = rawfinishnodeset(getintfromhash(this, key), value); if (!ok) { TValue k; setivalue(&k, key); diff --git a/src/serialization/lzio.cpp b/src/serialization/lzio.cpp index 308ac858..0ee23bcf 100644 --- a/src/serialization/lzio.cpp +++ b/src/serialization/lzio.cpp @@ -43,16 +43,16 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { /* --------------------------------------------------------------- read --- */ -static int checkbuffer (ZIO *z) { +static bool checkbuffer (ZIO *z) { if (z->n == 0) { /* no bytes in buffer? */ if (luaZ_fill(z) == EOZ) /* try to read more */ - return 0; /* no more input */ + return false; /* no more input */ else { z->n++; /* luaZ_fill consumed first byte; put it back */ z->p--; } } - return 1; /* now buffer has something */ + return true; /* now buffer has something */ } From 4969379ffbd8ed1e726bf57803fa233f68998792 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Nov 2025 22:01:42 +0000 Subject: [PATCH 2/3] Phase 121: std::span callsite conversion (Part 1 - Testing) Converted 6 opportunities in ltests.cpp to use std::span accessors: 1. checkproto() - 4 range-based for loops using span accessors 2. listcode() - codeSpan iteration with index tracking 3. printcode() - codeSpan iteration with index tracking 4. listk() - constantsSpan iteration 5. listabslineinfo() - absLineInfoSpan iteration 6. lua_checkpc() - bounds check using codeSpan.data() All conversions use existing span accessors from Phase 115-116: - Proto::getCodeSpan() - Proto::getConstantsSpan() - Proto::getProtosSpan() - Proto::getUpvaluesSpan() - ProtoDebugInfo::getAbsLineInfoSpan() - ProtoDebugInfo::getLocVarsSpan() Benefits: - Type-safe array access - Cleaner range-based for loops - Better intent expression Testing: - All tests pass (final OK !!!) - Performance: 4.44s avg (vs 4.45s from Phase 120) - Zero performance regression This is part 1 of the std::span expansion effort (Option 2). --- src/testing/ltests.cpp | 55 ++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/testing/ltests.cpp b/src/testing/ltests.cpp index c2c32216..841ac949 100644 --- a/src/testing/ltests.cpp +++ b/src/testing/ltests.cpp @@ -443,19 +443,18 @@ static void checkudata (global_State *g, Udata *u) { static void checkproto (global_State *g, Proto *f) { - int i; GCObject *fgc = obj2gco(f); checkobjrefN(g, fgc, f->getSource()); - for (i=0; igetConstantsSize(); i++) { - if (iscollectable(f->getConstants() + i)) - checkobjref(g, fgc, gcvalue(f->getConstants() + i)); + for (const auto& constant : f->getConstantsSpan()) { + if (iscollectable(&constant)) + checkobjref(g, fgc, gcvalue(&constant)); } - for (i=0; igetUpvaluesSize(); i++) - checkobjrefN(g, fgc, f->getUpvalues()[i].getName()); - for (i=0; igetProtosSize(); i++) - checkobjrefN(g, fgc, f->getProtos()[i]); - for (i=0; igetLocVarsSize(); i++) - checkobjrefN(g, fgc, f->getLocVars()[i].getVarName()); + for (const auto& upval : f->getUpvaluesSpan()) + checkobjrefN(g, fgc, upval.getName()); + for (Proto* proto : f->getProtosSpan()) + checkobjrefN(g, fgc, proto); + for (const auto& locvar : f->getDebugInfo().getLocVarsSpan()) + checkobjrefN(g, fgc, locvar.getVarName()); } @@ -487,8 +486,10 @@ static int lua_checkpc (CallInfo *ci) { else { StkId f = ci->funcRef().p; Proto *p = clLvalue(s2v(f))->getProto(); - return p->getCode() <= ci->getSavedPC() && - ci->getSavedPC() <= p->getCode() + p->getCodeSize(); + auto codeSpan = p->getCodeSpan(); + const Instruction* savedPC = ci->getSavedPC(); + return codeSpan.data() <= savedPC && + savedPC <= codeSpan.data() + codeSpan.size(); } } @@ -781,11 +782,14 @@ static int listcode (lua_State *L) { lua_newtable(L); setnameval(L, "maxstack", p->getMaxStackSize()); setnameval(L, "numparams", p->getNumParams()); - for (pc=0; pcgetCodeSize(); pc++) { + pc = 0; + for (const auto& instr : p->getCodeSpan()) { + (void)instr; /* unused */ char buff[100]; lua_pushinteger(L, pc+1); lua_pushstring(L, buildop(p, pc, buff)); lua_settable(L, -3); + pc++; } return 1; } @@ -799,9 +803,12 @@ static int printcode (lua_State *L) { p = getproto(obj_at(L, 1)); printf("maxstack: %d\n", p->getMaxStackSize()); printf("numparams: %d\n", p->getNumParams()); - for (pc=0; pcgetCodeSize(); pc++) { + pc = 0; + for (const auto& instr : p->getCodeSpan()) { + (void)instr; /* unused */ char buff[100]; printf("%s\n", buildop(p, pc, buff)); + pc++; } return 0; } @@ -813,10 +820,13 @@ static int listk (lua_State *L) { luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); p = getproto(obj_at(L, 1)); - lua_createtable(L, p->getConstantsSize(), 0); - for (i=0; igetConstantsSize(); i++) { - pushobject(L, p->getConstants()+i); + auto constantsSpan = p->getConstantsSpan(); + lua_createtable(L, static_cast(constantsSpan.size()), 0); + i = 0; + for (const auto& constant : constantsSpan) { + pushobject(L, &constant); lua_rawseti(L, -2, i+1); + i++; } return 1; } @@ -829,12 +839,15 @@ static int listabslineinfo (lua_State *L) { 1, "Lua function expected"); p = getproto(obj_at(L, 1)); luaL_argcheck(L, p->getAbsLineInfo() != nullptr, 1, "function has no debug info"); - lua_createtable(L, 2 * p->getAbsLineInfoSize(), 0); - for (i=0; i < p->getAbsLineInfoSize(); i++) { - lua_pushinteger(L, p->getAbsLineInfo()[i].getPC()); + auto absLineInfoSpan = p->getDebugInfo().getAbsLineInfoSpan(); + lua_createtable(L, 2 * static_cast(absLineInfoSpan.size()), 0); + i = 0; + for (const auto& absline : absLineInfoSpan) { + lua_pushinteger(L, absline.getPC()); lua_rawseti(L, -2, 2 * i + 1); - lua_pushinteger(L, p->getAbsLineInfo()[i].getLine()); + lua_pushinteger(L, absline.getLine()); lua_rawseti(L, -2, 2 * i + 2); + i++; } return 1; } From c0777f2bc5b4027ff16f18b59312c9b991c09a38 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Nov 2025 22:10:25 +0000 Subject: [PATCH 3/3] Phase 122-123: std::span callsite conversion (Parts 2-3 - Compiler & Runtime) Converted 9 additional patterns to use existing std::span accessors: **Phase 122 - Compiler Code (7 conversions):** funcstate.cpp: 1. registerlocalvar() - locVarsSpan initialization loop 2. searchupvalue() - upvaluesSpan search loop 3. allocupvalue() - upvaluesSpan initialization loop lcode.cpp: 4. addk() - constantsSpan initialization loop 5. finaltarget() - codeSpan jump chain following 6. finish() - codeSpan instruction loop parser.cpp: 7. addprototype() - protosSpan initialization loop **Phase 123 - Runtime Code (2 conversions):** lfunc.cpp: 8. Proto::getLocalName() - locVarsSpan range-based for loop lvm.cpp: 9. lua_State::pushClosure() - upvaluesSpan range-based for loop All conversions use existing span accessors from Phase 115-116: - Proto::getCodeSpan() - Proto::getConstantsSpan() - Proto::getProtosSpan() - Proto::getUpvaluesSpan() - ProtoDebugInfo::getLocVarsSpan() Benefits: - Type-safe array access throughout compiler and runtime - Cleaner range-based for loops where applicable - Better bounds safety with std::span - More idiomatic modern C++23 code Testing: - All tests pass (final OK !!!) - Performance: 4.61s avg (within acceptable bounds) - Total std::span conversions: 15 (Phase 121: 6 + Phase 122: 7 + Phase 123: 2) This completes the std::span expansion effort (Option 2) with 15 new call sites converted beyond the original Phase 115-116 accessor additions. --- src/compiler/funcstate.cpp | 23 ++++++++++++----------- src/compiler/lcode.cpp | 14 ++++++++------ src/compiler/parser.cpp | 7 ++++--- src/objects/lfunc.cpp | 10 ++++++---- src/vm/lvm.cpp | 15 ++++++++------- 5 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/compiler/funcstate.cpp b/src/compiler/funcstate.cpp index 1889ef63..9730eb0b 100644 --- a/src/compiler/funcstate.cpp +++ b/src/compiler/funcstate.cpp @@ -91,10 +91,11 @@ short FuncState::registerlocalvar(TString *varname) { int oldsize = proto->getLocVarsSize(); luaM_growvector(getLexState()->getLuaState(), proto->getLocVarsRef(), getNumDebugVars(), proto->getLocVarsSizeRef(), LocVar, SHRT_MAX, "local variables"); - while (oldsize < proto->getLocVarsSize()) - proto->getLocVars()[oldsize++].setVarName(nullptr); - proto->getLocVars()[getNumDebugVars()].setVarName(varname); - proto->getLocVars()[getNumDebugVars()].setStartPC(getPC()); + auto locVarsSpan = proto->getDebugInfo().getLocVarsSpan(); + while (oldsize < static_cast(locVarsSpan.size())) + locVarsSpan[oldsize++].setVarName(nullptr); + locVarsSpan[getNumDebugVars()].setVarName(varname); + locVarsSpan[getNumDebugVars()].setStartPC(getPC()); luaC_objbarrier(getLexState()->getLuaState(), proto, varname); return postIncrementNumDebugVars(); } @@ -181,10 +182,9 @@ void FuncState::removevars(int tolevel) { ** with the given 'name'. */ int FuncState::searchupvalue(TString *name) { - int i; - Upvaldesc *up = getProto()->getUpvalues(); - for (i = 0; i < getNumUpvalues(); i++) { - if (eqstr(up[i].getName(), name)) return i; + auto upvaluesSpan = getProto()->getUpvaluesSpan(); + for (size_t i = 0; i < static_cast(getNumUpvalues()); i++) { + if (eqstr(upvaluesSpan[i].getName(), name)) return static_cast(i); } return -1; /* not found */ } @@ -196,9 +196,10 @@ Upvaldesc *FuncState::allocupvalue() { checklimit(getNumUpvalues() + 1, MAXUPVAL, "upvalues"); luaM_growvector(getLexState()->getLuaState(), proto->getUpvaluesRef(), getNumUpvalues(), proto->getUpvaluesSizeRef(), Upvaldesc, MAXUPVAL, "upvalues"); - while (oldsize < proto->getUpvaluesSize()) - proto->getUpvalues()[oldsize++].setName(nullptr); - return &proto->getUpvalues()[getNumUpvaluesRef()++]; + auto upvaluesSpan = proto->getUpvaluesSpan(); + while (oldsize < static_cast(upvaluesSpan.size())) + upvaluesSpan[oldsize++].setName(nullptr); + return &upvaluesSpan[getNumUpvaluesRef()++]; } diff --git a/src/compiler/lcode.cpp b/src/compiler/lcode.cpp index 5e267e53..8b00264c 100644 --- a/src/compiler/lcode.cpp +++ b/src/compiler/lcode.cpp @@ -319,9 +319,10 @@ int FuncState::addk(Proto *proto, TValue *v) { int oldsize = proto->getConstantsSize(); int k = getNK(); luaM_growvector(L, proto->getConstantsRef(), k, proto->getConstantsSizeRef(), TValue, MAXARG_Ax, "constants"); - while (oldsize < proto->getConstantsSize()) - setnilvalue(&proto->getConstants()[oldsize++]); - proto->getConstants()[k] = *v; + auto constantsSpan = proto->getConstantsSpan(); + while (oldsize < static_cast(constantsSpan.size())) + setnilvalue(&constantsSpan[oldsize++]); + constantsSpan[k] = *v; incrementNK(); luaC_barrier(L, proto, v); return k; @@ -1071,10 +1072,10 @@ void FuncState::codeconcat(expdesc *e1, expdesc *e2, int line) { ** return the final target of a jump (skipping jumps to jumps) */ int FuncState::finaltarget(int i) { - Instruction *code = getProto()->getCode(); + auto codeSpan = getProto()->getCodeSpan(); int count; for (count = 0; count < 100; count++) { /* avoid infinite loops */ - Instruction instr = code[i]; + Instruction instr = codeSpan[i]; if (InstructionView(instr).opcode() != OP_JMP) break; else @@ -1654,8 +1655,9 @@ void FuncState::setlist(int base, int nelems, int tostore) { void FuncState::finish() { int i; Proto *p = getProto(); + auto codeSpan = p->getCodeSpan(); for (i = 0; i < getPC(); i++) { - Instruction *instr = &p->getCode()[i]; + Instruction *instr = &codeSpan[i]; /* avoid "not used" warnings when assert is off (for 'onelua.c') */ (void)luaP_isOT; (void)luaP_isIT; lua_assert(i == 0 || luaP_isOT(*(instr - 1)) == luaP_isIT(*instr)); diff --git a/src/compiler/parser.cpp b/src/compiler/parser.cpp index f3132bf9..8a8496a9 100644 --- a/src/compiler/parser.cpp +++ b/src/compiler/parser.cpp @@ -412,10 +412,11 @@ Proto *Parser::addprototype() { if (funcstate->getNP() >= proto->getProtosSize()) { int oldsize = proto->getProtosSize(); luaM_growvector(state, proto->getProtosRef(), funcstate->getNP(), proto->getProtosSizeRef(), Proto *, MAXARG_Bx, "functions"); - while (oldsize < proto->getProtosSize()) - proto->getProtos()[oldsize++] = nullptr; + auto protosSpan = proto->getProtosSpan(); + while (oldsize < static_cast(protosSpan.size())) + protosSpan[oldsize++] = nullptr; } - proto->getProtos()[funcstate->getNPRef()++] = clp = luaF_newproto(state); + proto->getProtosSpan()[funcstate->getNPRef()++] = clp = luaF_newproto(state); luaC_objbarrier(state, proto, clp); return clp; } diff --git a/src/objects/lfunc.cpp b/src/objects/lfunc.cpp index 760a9d96..89b1ec8a 100644 --- a/src/objects/lfunc.cpp +++ b/src/objects/lfunc.cpp @@ -319,12 +319,14 @@ void luaF_freeproto (lua_State *L, Proto *f) { ** Returns nullptr if not found. */ const char* Proto::getLocalName(int local_number, int pc) const { - int i; - for (i = 0; i pc) + break; + if (pc < locvar.getEndPC()) { /* is variable active? */ local_number--; if (local_number == 0) - return getstr(getLocVars()[i].getVarName()); + return getstr(locvar.getVarName()); } } return nullptr; /* not found */ diff --git a/src/vm/lvm.cpp b/src/vm/lvm.cpp index 585d02d0..69ee8679 100644 --- a/src/vm/lvm.cpp +++ b/src/vm/lvm.cpp @@ -135,18 +135,19 @@ inline constexpr int MAXTAGLOOP = 2000; ** its upvalues. */ void lua_State::pushClosure(Proto *p, UpVal **encup, StkId base, StkId ra) { - int nup = p->getUpvaluesSize(); - Upvaldesc *uv = p->getUpvalues(); - int i; + auto upvaluesSpan = p->getUpvaluesSpan(); + int nup = static_cast(upvaluesSpan.size()); + int i = 0; LClosure *ncl = LClosure::create(this, nup); ncl->setProto(p); setclLvalue2s(this, ra, ncl); /* anchor new closure in stack */ - for (i = 0; i < nup; i++) { /* fill in its upvalues */ - if (uv[i].isInStack()) /* upvalue refers to local variable? */ - ncl->setUpval(i, luaF_findupval(this, base + uv[i].getIndex())); + for (const auto& uv : upvaluesSpan) { /* fill in its upvalues */ + if (uv.isInStack()) /* upvalue refers to local variable? */ + ncl->setUpval(i, luaF_findupval(this, base + uv.getIndex())); else /* get upvalue from enclosing function */ - ncl->setUpval(i, encup[uv[i].getIndex()]); + ncl->setUpval(i, encup[uv.getIndex()]); luaC_objbarrier(this, ncl, ncl->getUpval(i)); + i++; } }