mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-11-17 01:51:00 +03:00
c84a37ae93
Linux 6.10+ with CONFIG_FORTIFY_SOURCE notices memcpy() accessing past the end of TString, because it has no indication that there there may be an additional allocation there. There's no appropriate upstream change for this (ancient) version of Lua, so this is the narrowest change I could come up with to add a flex array field to the end of TString to satisfy the check. It's loosely based on changes from lua/lua@ca41b43f and lua/lua@9514abc2. Sponsored-by: https://despairlabs.com/sponsor/ Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <robn@despairlabs.com> Closes #16541 Closes #16583
229 lines
7.4 KiB
C
229 lines
7.4 KiB
C
/*
|
|
** $Id: lstate.h,v 2.82.1.1 2013/04/12 18:48:47 roberto Exp $
|
|
** Global State
|
|
** See Copyright Notice in lua.h
|
|
*/
|
|
|
|
#ifndef lstate_h
|
|
#define lstate_h
|
|
|
|
#include <sys/lua/lua.h>
|
|
|
|
#include "lobject.h"
|
|
#include "ltm.h"
|
|
#include "lzio.h"
|
|
|
|
|
|
/*
|
|
|
|
** Some notes about garbage-collected objects: All objects in Lua must
|
|
** be kept somehow accessible until being freed.
|
|
**
|
|
** Lua keeps most objects linked in list g->allgc. The link uses field
|
|
** 'next' of the CommonHeader.
|
|
**
|
|
** Strings are kept in several lists headed by the array g->strt.hash.
|
|
**
|
|
** Open upvalues are not subject to independent garbage collection. They
|
|
** are collected together with their respective threads. Lua keeps a
|
|
** double-linked list with all open upvalues (g->uvhead) so that it can
|
|
** mark objects referred by them. (They are always gray, so they must
|
|
** be remarked in the atomic step. Usually their contents would be marked
|
|
** when traversing the respective threads, but the thread may already be
|
|
** dead, while the upvalue is still accessible through closures.)
|
|
**
|
|
** Objects with finalizers are kept in the list g->finobj.
|
|
**
|
|
** The list g->tobefnz links all objects being finalized.
|
|
|
|
*/
|
|
|
|
|
|
struct lua_longjmp; /* defined in ldo.c */
|
|
|
|
|
|
|
|
/* extra stack space to handle TM calls and some other extras */
|
|
#define EXTRA_STACK 5
|
|
|
|
|
|
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
|
|
|
|
|
|
/* kinds of Garbage Collection */
|
|
#define KGC_NORMAL 0
|
|
#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */
|
|
#define KGC_GEN 2 /* generational collection */
|
|
|
|
|
|
typedef struct stringtable {
|
|
GCObject **hash;
|
|
lu_int32 nuse; /* number of elements */
|
|
int size;
|
|
} stringtable;
|
|
|
|
|
|
/*
|
|
** information about a call
|
|
*/
|
|
typedef struct CallInfo {
|
|
StkId func; /* function index in the stack */
|
|
StkId top; /* top for this function */
|
|
struct CallInfo *previous, *next; /* dynamic call link */
|
|
short nresults; /* expected number of results from this function */
|
|
lu_byte callstatus;
|
|
ptrdiff_t extra;
|
|
union {
|
|
struct { /* only for Lua functions */
|
|
StkId base; /* base for this function */
|
|
const Instruction *savedpc;
|
|
} l;
|
|
struct { /* only for C functions */
|
|
int ctx; /* context info. in case of yields */
|
|
lua_CFunction k; /* continuation in case of yields */
|
|
ptrdiff_t old_errfunc;
|
|
lu_byte old_allowhook;
|
|
lu_byte status;
|
|
} c;
|
|
} u;
|
|
} CallInfo;
|
|
|
|
|
|
/*
|
|
** Bits in CallInfo status
|
|
*/
|
|
#define CIST_LUA (1<<0) /* call is running a Lua function */
|
|
#define CIST_HOOKED (1<<1) /* call is running a debug hook */
|
|
#define CIST_REENTRY (1<<2) /* call is running on same invocation of
|
|
luaV_execute of previous call */
|
|
#define CIST_YIELDED (1<<3) /* call reentered after suspension */
|
|
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
|
|
#define CIST_STAT (1<<5) /* call has an error status (pcall) */
|
|
#define CIST_TAIL (1<<6) /* call was tail called */
|
|
#define CIST_HOOKYIELD (1<<7) /* last hook called yielded */
|
|
|
|
|
|
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
|
|
|
|
|
|
/*
|
|
** `global state', shared by all threads of this state
|
|
*/
|
|
typedef struct global_State {
|
|
lua_Alloc frealloc; /* function to reallocate memory */
|
|
void *ud; /* auxiliary data to `frealloc' */
|
|
lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */
|
|
l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
|
|
lu_mem GCmemtrav; /* memory traversed by the GC */
|
|
lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
|
|
stringtable strt; /* hash table for strings */
|
|
TValue l_registry;
|
|
unsigned int seed; /* randomized seed for hashes */
|
|
lu_byte currentwhite;
|
|
lu_byte gcstate; /* state of garbage collector */
|
|
lu_byte gckind; /* kind of GC running */
|
|
lu_byte gcrunning; /* true if GC is running */
|
|
int sweepstrgc; /* position of sweep in `strt' */
|
|
GCObject *allgc; /* list of all collectable objects */
|
|
GCObject *finobj; /* list of collectable objects with finalizers */
|
|
GCObject **sweepgc; /* current position of sweep in list 'allgc' */
|
|
GCObject **sweepfin; /* current position of sweep in list 'finobj' */
|
|
GCObject *gray; /* list of gray objects */
|
|
GCObject *grayagain; /* list of objects to be traversed atomically */
|
|
GCObject *weak; /* list of tables with weak values */
|
|
GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
|
|
GCObject *allweak; /* list of all-weak tables */
|
|
GCObject *tobefnz; /* list of userdata to be GC */
|
|
UpVal uvhead; /* head of double-linked list of all open upvalues */
|
|
Mbuffer buff; /* temporary buffer for string concatenation */
|
|
int gcpause; /* size of pause between successive GCs */
|
|
int gcmajorinc; /* pause between major collections (only in gen. mode) */
|
|
int gcstepmul; /* GC `granularity' */
|
|
lua_CFunction panic; /* to be called in unprotected errors */
|
|
struct lua_State *mainthread;
|
|
const lua_Number *version; /* pointer to version number */
|
|
TString *memerrmsg; /* memory-error message */
|
|
TString *tmname[TM_N]; /* array with tag-method names */
|
|
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
|
|
} global_State;
|
|
|
|
|
|
/*
|
|
** `per thread' state
|
|
*/
|
|
struct lua_State {
|
|
CommonHeader;
|
|
lu_byte status;
|
|
StkId top; /* first free slot in the stack */
|
|
global_State *l_G;
|
|
CallInfo *ci; /* call info for current function */
|
|
const Instruction *oldpc; /* last pc traced */
|
|
StkId stack_last; /* last free slot in the stack */
|
|
StkId stack; /* stack base */
|
|
int stacksize;
|
|
unsigned short nny; /* number of non-yieldable calls in stack */
|
|
unsigned short nCcalls; /* number of nested C calls */
|
|
lu_byte hookmask;
|
|
lu_byte allowhook;
|
|
lu_byte runerror; /* handling a runtime error */
|
|
int basehookcount;
|
|
int hookcount;
|
|
lua_Hook hook;
|
|
GCObject *openupval; /* list of open upvalues in this stack */
|
|
GCObject *gclist;
|
|
struct lua_longjmp *errorJmp; /* current error recover point */
|
|
ptrdiff_t errfunc; /* current error handling function (stack index) */
|
|
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
|
|
};
|
|
|
|
|
|
#define G(L) (L->l_G)
|
|
|
|
|
|
/*
|
|
** Union of all collectable objects
|
|
*/
|
|
union GCObject {
|
|
GCheader gch; /* common header */
|
|
struct TString ts;
|
|
union Udata u;
|
|
union Closure cl;
|
|
struct Table h;
|
|
struct Proto p;
|
|
struct UpVal uv;
|
|
struct lua_State th; /* thread */
|
|
};
|
|
|
|
|
|
#define gch(o) (&(o)->gch)
|
|
|
|
/* macros to convert a GCObject into a specific value */
|
|
#define rawgco2ts(o) \
|
|
check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts))
|
|
#define gco2ts(o) (&rawgco2ts(o)->tsv)
|
|
#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
|
|
#define gco2u(o) (&rawgco2u(o)->uv)
|
|
#define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l))
|
|
#define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c))
|
|
#define gco2cl(o) \
|
|
check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl))
|
|
#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
|
|
#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
|
|
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
|
|
#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
|
|
|
|
/* macro to convert any Lua object into a GCObject */
|
|
#define obj2gco(v) (cast(GCObject *, (v)))
|
|
|
|
|
|
/* actual number of total bytes allocated */
|
|
#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt)
|
|
|
|
LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
|
|
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
|
|
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
|
|
LUAI_FUNC void luaE_freeCI (lua_State *L);
|
|
|
|
|
|
#endif
|