Skip to content

Commit 39bc94e

Browse files
committed
WIP Phase 121: Header modularization - split god headers (partial)
Created focused headers to split lobject.h (2027 lines): - lobject_core.h: GCObject, GCBase<T>, Udata, type constants - lproto.h: Proto, ProtoDebugInfo, Upvaldesc, LocVar (NEW) - Updated lstring.h: Added TString class definition - Updated ltable.h: Added Table and Node class definitions - Updated lfunc.h: Added UpVal, CClosure, LClosure classes Progress: ✅ Created 6 focused headers ✅ Moved ~1200 lines out of lobject.h ✅ Resolved circular dependency (ltable.h ↔ ltm.h) ⚠️ Build errors remain (duplicate definitions to clean up) Next: Remove duplicates from lobject.h, test compilation See docs/HEADER_ORGANIZATION_ANALYSIS.md for full plan
1 parent 69e4df1 commit 39bc94e

File tree

6 files changed

+1701
-565
lines changed

6 files changed

+1701
-565
lines changed

src/objects/lfunc.h

Lines changed: 225 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,231 @@
88
#define lfunc_h
99

1010

11-
#include "lobject.h"
11+
#include "lobject_core.h" /* GCBase, GCObject, TValue */
12+
#include "lproto.h" /* Proto */
13+
14+
/* Forward declarations */
15+
class lua_State;
16+
class TString;
17+
typedef union StackValue *StkId;
18+
19+
20+
/*
21+
** {==================================================================
22+
** Functions
23+
** ===================================================================
24+
*/
25+
26+
inline constexpr int LUA_VUPVAL = makevariant(LUA_TUPVAL, 0);
27+
28+
29+
/* Variant tags for functions */
30+
inline constexpr int LUA_VLCL = makevariant(LUA_TFUNCTION, 0); /* Lua closure */
31+
inline constexpr int LUA_VLCF = makevariant(LUA_TFUNCTION, 1); /* light C function */
32+
inline constexpr int LUA_VCCL = makevariant(LUA_TFUNCTION, 2); /* C closure */
33+
34+
constexpr bool ttisfunction(const TValue* o) noexcept { return checktype(o, LUA_TFUNCTION); }
35+
constexpr bool ttisLclosure(const TValue* o) noexcept { return checktag(o, ctb(LUA_VLCL)); }
36+
constexpr bool ttislcf(const TValue* o) noexcept { return checktag(o, LUA_VLCF); }
37+
constexpr bool ttisCclosure(const TValue* o) noexcept { return checktag(o, ctb(LUA_VCCL)); }
38+
constexpr bool ttisclosure(const TValue* o) noexcept { return ttisLclosure(o) || ttisCclosure(o); }
39+
40+
constexpr bool TValue::isFunction() const noexcept { return checktype(this, LUA_TFUNCTION); }
41+
constexpr bool TValue::isLClosure() const noexcept { return checktag(this, ctb(LUA_VLCL)); }
42+
constexpr bool TValue::isLightCFunction() const noexcept { return checktag(this, LUA_VLCF); }
43+
constexpr bool TValue::isCClosure() const noexcept { return checktag(this, ctb(LUA_VCCL)); }
44+
constexpr bool TValue::isClosure() const noexcept { return isLClosure() || isCClosure(); }
45+
46+
inline constexpr bool isLfunction(const TValue* o) noexcept {
47+
return ttisLclosure(o);
48+
}
49+
50+
constexpr bool TValue::isLuaFunction() const noexcept { return isLClosure(); }
51+
52+
inline Closure* clvalue(const TValue* o) noexcept { return o->closureValue(); }
53+
inline LClosure* clLvalue(const TValue* o) noexcept { return o->lClosureValue(); }
54+
inline CClosure* clCvalue(const TValue* o) noexcept { return o->cClosureValue(); }
55+
56+
inline lua_CFunction fvalue(const TValue* o) noexcept { return o->functionValue(); }
57+
58+
constexpr lua_CFunction fvalueraw(const Value& v) noexcept { return v.f; }
59+
60+
61+
/* setfvalue now defined as inline function below */
62+
63+
/* setclCvalue now defined as inline function below */
64+
65+
66+
/*
67+
** Upvalues for Lua closures
68+
*/
69+
// UpVal inherits from GCBase (CRTP)
70+
class UpVal : public GCBase<UpVal> {
71+
private:
72+
union {
73+
TValue *p; /* points to stack or to its own value */
74+
ptrdiff_t offset; /* used while the stack is being reallocated */
75+
} v;
76+
union {
77+
struct { /* (when open) */
78+
UpVal *next; /* linked list */
79+
UpVal **previous;
80+
} open;
81+
TValue value; /* the value (when closed) */
82+
} u;
83+
84+
public:
85+
// Phase 50: Constructor - initializes all fields to safe defaults
86+
UpVal() noexcept {
87+
v.p = nullptr; // Initialize v union (pointer variant)
88+
// Initialize u union as closed upvalue with nil
89+
u.value.valueField().n = 0; // Zero-initialize Value union
90+
u.value.setType(LUA_TNIL);
91+
}
92+
93+
// Phase 50: Destructor - trivial (GC handles deallocation)
94+
~UpVal() noexcept = default;
95+
96+
// Phase 50: Placement new operator - integrates with Lua's GC (implemented in lgc.h)
97+
static void* operator new(size_t size, lua_State* L, lu_byte tt);
98+
99+
// Disable regular new/delete (must use placement new with GC)
100+
static void* operator new(size_t) = delete;
101+
static void operator delete(void*) = delete;
102+
103+
// Inline accessors for v union
104+
TValue* getVP() noexcept { return v.p; }
105+
const TValue* getVP() const noexcept { return v.p; }
106+
void setVP(TValue* ptr) noexcept { v.p = ptr; }
107+
108+
ptrdiff_t getOffset() const noexcept { return v.offset; }
109+
void setOffset(ptrdiff_t off) noexcept { v.offset = off; }
110+
111+
// Inline accessors for u union (open upvalues)
112+
UpVal* getOpenNext() const noexcept { return u.open.next; }
113+
void setOpenNext(UpVal* next_uv) noexcept { u.open.next = next_uv; }
114+
UpVal** getOpenNextPtr() noexcept { return &u.open.next; }
115+
116+
UpVal** getOpenPrevious() const noexcept { return u.open.previous; }
117+
void setOpenPrevious(UpVal** prev) noexcept { u.open.previous = prev; }
118+
119+
// Accessor for u.value (closed upvalues)
120+
TValue* getValueSlot() noexcept { return &u.value; }
121+
const TValue* getValueSlot() const noexcept { return &u.value; }
122+
123+
// Status check
124+
bool isOpen() const noexcept { return v.p != &u.value; }
125+
126+
// Level accessor for open upvalues (Phase 44.3)
127+
StkId getLevel() const noexcept {
128+
lua_assert(isOpen());
129+
return reinterpret_cast<StkId>(v.p);
130+
}
131+
132+
// Backward compatibility (getValue returns current value pointer)
133+
TValue* getValue() noexcept { return v.p; }
134+
const TValue* getValue() const noexcept { return v.p; }
135+
136+
// Methods (implemented in lfunc.cpp)
137+
void unlink();
138+
};
139+
140+
141+
142+
// Closures inherit from GCBase (CRTP)
143+
// ClosureHeader fields: nupvalues, gclist (GC fields inherited from GCBase)
144+
145+
class CClosure : public GCBase<CClosure> {
146+
private:
147+
lu_byte nupvalues;
148+
GCObject *gclist;
149+
lua_CFunction f;
150+
TValue upvalue[1]; /* list of upvalues */
151+
152+
public:
153+
// Member placement new operator for GC allocation (defined in lgc.h)
154+
static void* operator new(size_t size, lua_State* L, lu_byte tt, size_t extra = 0);
155+
156+
// Constructor
157+
CClosure(int nupvals);
158+
159+
// Factory method
160+
static CClosure* create(lua_State* L, int nupvals);
161+
162+
// Inline accessors
163+
lua_CFunction getFunction() const noexcept { return f; }
164+
void setFunction(lua_CFunction func) noexcept { f = func; }
165+
166+
lu_byte getNumUpvalues() const noexcept { return nupvalues; }
167+
void setNumUpvalues(lu_byte n) noexcept { nupvalues = n; }
168+
169+
TValue* getUpvalue(int idx) noexcept { return &upvalue[idx]; }
170+
const TValue* getUpvalue(int idx) const noexcept { return &upvalue[idx]; }
171+
172+
GCObject* getGclist() noexcept { return gclist; }
173+
void setGclist(GCObject* gc) noexcept { gclist = gc; }
174+
// For GC gray list traversal - allows efficient list manipulation
175+
GCObject** getGclistPtr() noexcept { return &gclist; }
176+
177+
// Static helper for size calculation (can access private upvalue field)
178+
static constexpr size_t sizeForUpvalues(int n) noexcept {
179+
return offsetof(CClosure, upvalue) + sizeof(TValue) * cast_uint(n);
180+
}
181+
};
182+
183+
class LClosure : public GCBase<LClosure> {
184+
private:
185+
lu_byte nupvalues;
186+
GCObject *gclist;
187+
Proto *p;
188+
UpVal *upvals[1]; /* list of upvalues */
189+
190+
public:
191+
// Member placement new operator for GC allocation (defined in lgc.h)
192+
static void* operator new(size_t size, lua_State* L, lu_byte tt, size_t extra = 0);
193+
194+
// Constructor
195+
LClosure(int nupvals);
196+
197+
// Factory method
198+
static LClosure* create(lua_State* L, int nupvals);
199+
200+
// Inline accessors
201+
Proto* getProto() const noexcept { return p; }
202+
void setProto(Proto* proto) noexcept { p = proto; }
203+
204+
lu_byte getNumUpvalues() const noexcept { return nupvalues; }
205+
void setNumUpvalues(lu_byte n) noexcept { nupvalues = n; }
206+
207+
UpVal* getUpval(int idx) const noexcept { return upvals[idx]; }
208+
void setUpval(int idx, UpVal* uv) noexcept { upvals[idx] = uv; }
209+
UpVal** getUpvalPtr(int idx) noexcept { return &upvals[idx]; }
210+
211+
GCObject* getGclist() noexcept { return gclist; }
212+
void setGclist(GCObject* gc) noexcept { gclist = gc; }
213+
// For GC gray list traversal - allows efficient list manipulation
214+
GCObject** getGclistPtr() noexcept { return &gclist; }
215+
216+
// Static helper for size calculation (can access private upvals field)
217+
static constexpr size_t sizeForUpvalues(int n) noexcept {
218+
return offsetof(LClosure, upvals) + sizeof(UpVal *) * cast_uint(n);
219+
}
220+
221+
// Methods (implemented in lfunc.cpp)
222+
void initUpvals(lua_State* L);
223+
};
224+
225+
226+
typedef union Closure {
227+
CClosure c;
228+
LClosure l;
229+
} Closure;
230+
231+
inline Proto* getproto(const TValue* o) noexcept {
232+
return clLvalue(o)->getProto();
233+
}
234+
235+
/* }================================================================== */
12236

13237

14238
// Phase 88: Convert sizeCclosure and sizeLclosure macros to inline constexpr functions

0 commit comments

Comments
 (0)