18e3e3a7aSWarner Losh /* 20495ed39SKyle Evans ** $Id: lstate.h $ 38e3e3a7aSWarner Losh ** Global State 48e3e3a7aSWarner Losh ** See Copyright Notice in lua.h 58e3e3a7aSWarner Losh */ 68e3e3a7aSWarner Losh 78e3e3a7aSWarner Losh #ifndef lstate_h 88e3e3a7aSWarner Losh #define lstate_h 98e3e3a7aSWarner Losh 108e3e3a7aSWarner Losh #include "lua.h" 118e3e3a7aSWarner Losh 12*a9490b81SWarner Losh 13*a9490b81SWarner Losh /* Some header files included here need this definition */ 14*a9490b81SWarner Losh typedef struct CallInfo CallInfo; 15*a9490b81SWarner Losh 16*a9490b81SWarner Losh 178e3e3a7aSWarner Losh #include "lobject.h" 188e3e3a7aSWarner Losh #include "ltm.h" 198e3e3a7aSWarner Losh #include "lzio.h" 208e3e3a7aSWarner Losh 218e3e3a7aSWarner Losh 228e3e3a7aSWarner Losh /* 238e3e3a7aSWarner Losh ** Some notes about garbage-collected objects: All objects in Lua must 248e3e3a7aSWarner Losh ** be kept somehow accessible until being freed, so all objects always 258e3e3a7aSWarner Losh ** belong to one (and only one) of these lists, using field 'next' of 268e3e3a7aSWarner Losh ** the 'CommonHeader' for the link: 278e3e3a7aSWarner Losh ** 288e3e3a7aSWarner Losh ** 'allgc': all objects not marked for finalization; 298e3e3a7aSWarner Losh ** 'finobj': all objects marked for finalization; 308e3e3a7aSWarner Losh ** 'tobefnz': all objects ready to be finalized; 318e3e3a7aSWarner Losh ** 'fixedgc': all objects that are not to be collected (currently 328e3e3a7aSWarner Losh ** only small strings, such as reserved words). 33e112e9d2SKyle Evans ** 340495ed39SKyle Evans ** For the generational collector, some of these lists have marks for 350495ed39SKyle Evans ** generations. Each mark points to the first element in the list for 360495ed39SKyle Evans ** that particular generation; that generation goes until the next mark. 370495ed39SKyle Evans ** 380495ed39SKyle Evans ** 'allgc' -> 'survival': new objects; 390495ed39SKyle Evans ** 'survival' -> 'old': objects that survived one collection; 400495ed39SKyle Evans ** 'old1' -> 'reallyold': objects that became old in last collection; 410495ed39SKyle Evans ** 'reallyold' -> NULL: objects old for more than one cycle. 420495ed39SKyle Evans ** 430495ed39SKyle Evans ** 'finobj' -> 'finobjsur': new objects marked for finalization; 440495ed39SKyle Evans ** 'finobjsur' -> 'finobjold1': survived """"; 450495ed39SKyle Evans ** 'finobjold1' -> 'finobjrold': just old """"; 460495ed39SKyle Evans ** 'finobjrold' -> NULL: really old """". 470495ed39SKyle Evans ** 480495ed39SKyle Evans ** All lists can contain elements older than their main ages, due 490495ed39SKyle Evans ** to 'luaC_checkfinalizer' and 'udata2finalize', which move 500495ed39SKyle Evans ** objects between the normal lists and the "marked for finalization" 510495ed39SKyle Evans ** lists. Moreover, barriers can age young objects in young lists as 520495ed39SKyle Evans ** OLD0, which then become OLD1. However, a list never contains 530495ed39SKyle Evans ** elements younger than their main ages. 540495ed39SKyle Evans ** 550495ed39SKyle Evans ** The generational collector also uses a pointer 'firstold1', which 560495ed39SKyle Evans ** points to the first OLD1 object in the list. It is used to optimize 570495ed39SKyle Evans ** 'markold'. (Potentially OLD1 objects can be anywhere between 'allgc' 580495ed39SKyle Evans ** and 'reallyold', but often the list has no OLD1 objects or they are 590495ed39SKyle Evans ** after 'old1'.) Note the difference between it and 'old1': 600495ed39SKyle Evans ** 'firstold1': no OLD1 objects before this point; there can be all 610495ed39SKyle Evans ** ages after it. 620495ed39SKyle Evans ** 'old1': no objects younger than OLD1 after this point. 630495ed39SKyle Evans */ 640495ed39SKyle Evans 650495ed39SKyle Evans /* 66e112e9d2SKyle Evans ** Moreover, there is another set of lists that control gray objects. 67e112e9d2SKyle Evans ** These lists are linked by fields 'gclist'. (All objects that 68e112e9d2SKyle Evans ** can become gray have such a field. The field is not the same 69e112e9d2SKyle Evans ** in all objects, but it always has this name.) Any gray object 70e112e9d2SKyle Evans ** must belong to one of these lists, and all objects in these lists 710495ed39SKyle Evans ** must be gray (with two exceptions explained below): 72e112e9d2SKyle Evans ** 73e112e9d2SKyle Evans ** 'gray': regular gray objects, still waiting to be visited. 74e112e9d2SKyle Evans ** 'grayagain': objects that must be revisited at the atomic phase. 75e112e9d2SKyle Evans ** That includes 76e112e9d2SKyle Evans ** - black objects got in a write barrier; 77e112e9d2SKyle Evans ** - all kinds of weak tables during propagation phase; 78e112e9d2SKyle Evans ** - all threads. 79e112e9d2SKyle Evans ** 'weak': tables with weak values to be cleared; 80e112e9d2SKyle Evans ** 'ephemeron': ephemeron tables with white->white entries; 81e112e9d2SKyle Evans ** 'allweak': tables with weak keys and/or weak values to be cleared. 820495ed39SKyle Evans ** 830495ed39SKyle Evans ** The exceptions to that "gray rule" are: 840495ed39SKyle Evans ** - TOUCHED2 objects in generational mode stay in a gray list (because 850495ed39SKyle Evans ** they must be visited again at the end of the cycle), but they are 860495ed39SKyle Evans ** marked black because assignments to them must activate barriers (to 870495ed39SKyle Evans ** move them back to TOUCHED1). 880495ed39SKyle Evans ** - Open upvales are kept gray to avoid barriers, but they stay out 890495ed39SKyle Evans ** of gray lists. (They don't even have a 'gclist' field.) 908e3e3a7aSWarner Losh */ 918e3e3a7aSWarner Losh 928e3e3a7aSWarner Losh 930495ed39SKyle Evans 940495ed39SKyle Evans /* 950495ed39SKyle Evans ** About 'nCcalls': This count has two parts: the lower 16 bits counts 960495ed39SKyle Evans ** the number of recursive invocations in the C stack; the higher 970495ed39SKyle Evans ** 16 bits counts the number of non-yieldable calls in the stack. 980495ed39SKyle Evans ** (They are together so that we can change and save both with one 990495ed39SKyle Evans ** instruction.) 1000495ed39SKyle Evans */ 1010495ed39SKyle Evans 1020495ed39SKyle Evans 1030495ed39SKyle Evans /* true if this thread does not have non-yieldable calls in the stack */ 1040495ed39SKyle Evans #define yieldable(L) (((L)->nCcalls & 0xffff0000) == 0) 1050495ed39SKyle Evans 1060495ed39SKyle Evans /* real number of C calls */ 1070495ed39SKyle Evans #define getCcalls(L) ((L)->nCcalls & 0xffff) 1080495ed39SKyle Evans 1090495ed39SKyle Evans 1100495ed39SKyle Evans /* Increment the number of non-yieldable calls */ 1110495ed39SKyle Evans #define incnny(L) ((L)->nCcalls += 0x10000) 1120495ed39SKyle Evans 1130495ed39SKyle Evans /* Decrement the number of non-yieldable calls */ 1140495ed39SKyle Evans #define decnny(L) ((L)->nCcalls -= 0x10000) 1150495ed39SKyle Evans 1160495ed39SKyle Evans /* Non-yieldable call increment */ 1170495ed39SKyle Evans #define nyci (0x10000 | 1) 1180495ed39SKyle Evans 1190495ed39SKyle Evans 1200495ed39SKyle Evans 1210495ed39SKyle Evans 1228e3e3a7aSWarner Losh struct lua_longjmp; /* defined in ldo.c */ 1238e3e3a7aSWarner Losh 1248e3e3a7aSWarner Losh 1258e3e3a7aSWarner Losh /* 1268e3e3a7aSWarner Losh ** Atomic type (relative to signals) to better ensure that 'lua_sethook' 1278e3e3a7aSWarner Losh ** is thread safe 1288e3e3a7aSWarner Losh */ 1298e3e3a7aSWarner Losh #if !defined(l_signalT) 1308e3e3a7aSWarner Losh #include <signal.h> 1318e3e3a7aSWarner Losh #define l_signalT sig_atomic_t 1328e3e3a7aSWarner Losh #endif 1338e3e3a7aSWarner Losh 1348e3e3a7aSWarner Losh 1350495ed39SKyle Evans /* 1360495ed39SKyle Evans ** Extra stack space to handle TM calls and some other extras. This 1370495ed39SKyle Evans ** space is not included in 'stack_last'. It is used only to avoid stack 1380495ed39SKyle Evans ** checks, either because the element will be promptly popped or because 1390495ed39SKyle Evans ** there will be a stack check soon after the push. Function frames 1400495ed39SKyle Evans ** never use this extra space, so it does not need to be kept clean. 1410495ed39SKyle Evans */ 1428e3e3a7aSWarner Losh #define EXTRA_STACK 5 1438e3e3a7aSWarner Losh 1448e3e3a7aSWarner Losh 1458e3e3a7aSWarner Losh #define BASIC_STACK_SIZE (2*LUA_MINSTACK) 1468e3e3a7aSWarner Losh 147*a9490b81SWarner Losh #define stacksize(th) cast_int((th)->stack_last.p - (th)->stack.p) 1480495ed39SKyle Evans 1498e3e3a7aSWarner Losh 1508e3e3a7aSWarner Losh /* kinds of Garbage Collection */ 1510495ed39SKyle Evans #define KGC_INC 0 /* incremental gc */ 1520495ed39SKyle Evans #define KGC_GEN 1 /* generational gc */ 1538e3e3a7aSWarner Losh 1548e3e3a7aSWarner Losh 1558e3e3a7aSWarner Losh typedef struct stringtable { 1568e3e3a7aSWarner Losh TString **hash; 1578e3e3a7aSWarner Losh int nuse; /* number of elements */ 1588e3e3a7aSWarner Losh int size; 1598e3e3a7aSWarner Losh } stringtable; 1608e3e3a7aSWarner Losh 1618e3e3a7aSWarner Losh 1628e3e3a7aSWarner Losh /* 1638e3e3a7aSWarner Losh ** Information about a call. 1648c784bb8SWarner Losh ** About union 'u': 1658c784bb8SWarner Losh ** - field 'l' is used only for Lua functions; 1668c784bb8SWarner Losh ** - field 'c' is used only for C functions. 1678c784bb8SWarner Losh ** About union 'u2': 1688c784bb8SWarner Losh ** - field 'funcidx' is used only by C functions while doing a 1698c784bb8SWarner Losh ** protected call; 1708c784bb8SWarner Losh ** - field 'nyield' is used only while a function is "doing" an 1718c784bb8SWarner Losh ** yield (from the yield until the next resume); 1728c784bb8SWarner Losh ** - field 'nres' is used only while closing tbc variables when 1738c784bb8SWarner Losh ** returning from a function; 1748c784bb8SWarner Losh ** - field 'transferinfo' is used only during call/returnhooks, 1758c784bb8SWarner Losh ** before the function starts or after it ends. 1768e3e3a7aSWarner Losh */ 177*a9490b81SWarner Losh struct CallInfo { 178*a9490b81SWarner Losh StkIdRel func; /* function index in the stack */ 179*a9490b81SWarner Losh StkIdRel top; /* top for this function */ 1808e3e3a7aSWarner Losh struct CallInfo *previous, *next; /* dynamic call link */ 1818e3e3a7aSWarner Losh union { 1828e3e3a7aSWarner Losh struct { /* only for Lua functions */ 1838e3e3a7aSWarner Losh const Instruction *savedpc; 1840495ed39SKyle Evans volatile l_signalT trap; 1850495ed39SKyle Evans int nextraargs; /* # of extra arguments in vararg functions */ 1868e3e3a7aSWarner Losh } l; 1878e3e3a7aSWarner Losh struct { /* only for C functions */ 1888e3e3a7aSWarner Losh lua_KFunction k; /* continuation in case of yields */ 1898e3e3a7aSWarner Losh ptrdiff_t old_errfunc; 1908e3e3a7aSWarner Losh lua_KContext ctx; /* context info. in case of yields */ 1918e3e3a7aSWarner Losh } c; 1928e3e3a7aSWarner Losh } u; 1930495ed39SKyle Evans union { 1940495ed39SKyle Evans int funcidx; /* called-function index */ 1950495ed39SKyle Evans int nyield; /* number of values yielded */ 1968c784bb8SWarner Losh int nres; /* number of values returned */ 1970495ed39SKyle Evans struct { /* info about transferred values (for call/return hooks) */ 1980495ed39SKyle Evans unsigned short ftransfer; /* offset of first value transferred */ 1990495ed39SKyle Evans unsigned short ntransfer; /* number of values transferred */ 2000495ed39SKyle Evans } transferinfo; 2010495ed39SKyle Evans } u2; 2028e3e3a7aSWarner Losh short nresults; /* expected number of results from this function */ 2038e3e3a7aSWarner Losh unsigned short callstatus; 204*a9490b81SWarner Losh }; 2058e3e3a7aSWarner Losh 2068e3e3a7aSWarner Losh 2078e3e3a7aSWarner Losh /* 2088e3e3a7aSWarner Losh ** Bits in CallInfo status 2098e3e3a7aSWarner Losh */ 2108e3e3a7aSWarner Losh #define CIST_OAH (1<<0) /* original value of 'allowhook' */ 2110495ed39SKyle Evans #define CIST_C (1<<1) /* call is running a C function */ 2120495ed39SKyle Evans #define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ 2130495ed39SKyle Evans #define CIST_HOOKED (1<<3) /* call is running a debug hook */ 2148c784bb8SWarner Losh #define CIST_YPCALL (1<<4) /* doing a yieldable protected call */ 2158e3e3a7aSWarner Losh #define CIST_TAIL (1<<5) /* call was tail called */ 2168e3e3a7aSWarner Losh #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ 2178c784bb8SWarner Losh #define CIST_FIN (1<<7) /* function "called" a finalizer */ 2180495ed39SKyle Evans #define CIST_TRAN (1<<8) /* 'ci' has transfer information */ 2198c784bb8SWarner Losh #define CIST_CLSRET (1<<9) /* function is closing tbc variables */ 2208c784bb8SWarner Losh /* Bits 10-12 are used for CIST_RECST (see below) */ 2218c784bb8SWarner Losh #define CIST_RECST 10 2220495ed39SKyle Evans #if defined(LUA_COMPAT_LT_LE) 2238c784bb8SWarner Losh #define CIST_LEQ (1<<13) /* using __lt for __le */ 2240495ed39SKyle Evans #endif 2258e3e3a7aSWarner Losh 2268c784bb8SWarner Losh 2278c784bb8SWarner Losh /* 2288c784bb8SWarner Losh ** Field CIST_RECST stores the "recover status", used to keep the error 2298c784bb8SWarner Losh ** status while closing to-be-closed variables in coroutines, so that 2308c784bb8SWarner Losh ** Lua can correctly resume after an yield from a __close method called 2318c784bb8SWarner Losh ** because of an error. (Three bits are enough for error status.) 2328c784bb8SWarner Losh */ 2338c784bb8SWarner Losh #define getcistrecst(ci) (((ci)->callstatus >> CIST_RECST) & 7) 2348c784bb8SWarner Losh #define setcistrecst(ci,st) \ 2358c784bb8SWarner Losh check_exp(((st) & 7) == (st), /* status must fit in three bits */ \ 2368c784bb8SWarner Losh ((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) \ 2378c784bb8SWarner Losh | ((st) << CIST_RECST))) 2388c784bb8SWarner Losh 2398c784bb8SWarner Losh 2400495ed39SKyle Evans /* active function is a Lua function */ 2410495ed39SKyle Evans #define isLua(ci) (!((ci)->callstatus & CIST_C)) 2420495ed39SKyle Evans 2430495ed39SKyle Evans /* call is running Lua code (not a hook) */ 2440495ed39SKyle Evans #define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED))) 2458e3e3a7aSWarner Losh 2468e3e3a7aSWarner Losh /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ 2478e3e3a7aSWarner Losh #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) 2488e3e3a7aSWarner Losh #define getoah(st) ((st) & CIST_OAH) 2498e3e3a7aSWarner Losh 2508e3e3a7aSWarner Losh 2518e3e3a7aSWarner Losh /* 2528e3e3a7aSWarner Losh ** 'global state', shared by all threads of this state 2538e3e3a7aSWarner Losh */ 2548e3e3a7aSWarner Losh typedef struct global_State { 2558e3e3a7aSWarner Losh lua_Alloc frealloc; /* function to reallocate memory */ 2568e3e3a7aSWarner Losh void *ud; /* auxiliary data to 'frealloc' */ 2578e3e3a7aSWarner Losh l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ 2588e3e3a7aSWarner Losh l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ 2598e3e3a7aSWarner Losh lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ 2600495ed39SKyle Evans lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */ 2618e3e3a7aSWarner Losh stringtable strt; /* hash table for strings */ 2628e3e3a7aSWarner Losh TValue l_registry; 2630495ed39SKyle Evans TValue nilvalue; /* a nil value */ 2648e3e3a7aSWarner Losh unsigned int seed; /* randomized seed for hashes */ 2658e3e3a7aSWarner Losh lu_byte currentwhite; 2668e3e3a7aSWarner Losh lu_byte gcstate; /* state of garbage collector */ 2678e3e3a7aSWarner Losh lu_byte gckind; /* kind of GC running */ 2688c784bb8SWarner Losh lu_byte gcstopem; /* stops emergency collections */ 2690495ed39SKyle Evans lu_byte genminormul; /* control for minor generational collections */ 2700495ed39SKyle Evans lu_byte genmajormul; /* control for major generational collections */ 2718c784bb8SWarner Losh lu_byte gcstp; /* control whether GC is running */ 2720495ed39SKyle Evans lu_byte gcemergency; /* true if this is an emergency collection */ 2730495ed39SKyle Evans lu_byte gcpause; /* size of pause between successive GCs */ 2740495ed39SKyle Evans lu_byte gcstepmul; /* GC "speed" */ 2750495ed39SKyle Evans lu_byte gcstepsize; /* (log2 of) GC granularity */ 2768e3e3a7aSWarner Losh GCObject *allgc; /* list of all collectable objects */ 2778e3e3a7aSWarner Losh GCObject **sweepgc; /* current position of sweep in list */ 2788e3e3a7aSWarner Losh GCObject *finobj; /* list of collectable objects with finalizers */ 2798e3e3a7aSWarner Losh GCObject *gray; /* list of gray objects */ 2808e3e3a7aSWarner Losh GCObject *grayagain; /* list of objects to be traversed atomically */ 2818e3e3a7aSWarner Losh GCObject *weak; /* list of tables with weak values */ 2828e3e3a7aSWarner Losh GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ 2838e3e3a7aSWarner Losh GCObject *allweak; /* list of all-weak tables */ 2848e3e3a7aSWarner Losh GCObject *tobefnz; /* list of userdata to be GC */ 2858e3e3a7aSWarner Losh GCObject *fixedgc; /* list of objects not to be collected */ 2860495ed39SKyle Evans /* fields for generational collector */ 2870495ed39SKyle Evans GCObject *survival; /* start of objects that survived one GC cycle */ 2880495ed39SKyle Evans GCObject *old1; /* start of old1 objects */ 2890495ed39SKyle Evans GCObject *reallyold; /* objects more than one cycle old ("really old") */ 2900495ed39SKyle Evans GCObject *firstold1; /* first OLD1 object in the list (if any) */ 2910495ed39SKyle Evans GCObject *finobjsur; /* list of survival objects with finalizers */ 2920495ed39SKyle Evans GCObject *finobjold1; /* list of old1 objects with finalizers */ 2930495ed39SKyle Evans GCObject *finobjrold; /* list of really old objects with finalizers */ 2948e3e3a7aSWarner Losh struct lua_State *twups; /* list of threads with open upvalues */ 2958e3e3a7aSWarner Losh lua_CFunction panic; /* to be called in unprotected errors */ 2968e3e3a7aSWarner Losh struct lua_State *mainthread; 2970495ed39SKyle Evans TString *memerrmsg; /* message for memory-allocation errors */ 2988e3e3a7aSWarner Losh TString *tmname[TM_N]; /* array with tag-method names */ 299*a9490b81SWarner Losh struct Table *mt[LUA_NUMTYPES]; /* metatables for basic types */ 3008e3e3a7aSWarner Losh TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ 3010495ed39SKyle Evans lua_WarnFunction warnf; /* warning function */ 3020495ed39SKyle Evans void *ud_warn; /* auxiliary data to 'warnf' */ 3038e3e3a7aSWarner Losh } global_State; 3048e3e3a7aSWarner Losh 3058e3e3a7aSWarner Losh 3068e3e3a7aSWarner Losh /* 3078e3e3a7aSWarner Losh ** 'per thread' state 3088e3e3a7aSWarner Losh */ 3098e3e3a7aSWarner Losh struct lua_State { 3108e3e3a7aSWarner Losh CommonHeader; 3118e3e3a7aSWarner Losh lu_byte status; 3120495ed39SKyle Evans lu_byte allowhook; 3130495ed39SKyle Evans unsigned short nci; /* number of items in 'ci' list */ 314*a9490b81SWarner Losh StkIdRel top; /* first free slot in the stack */ 3158e3e3a7aSWarner Losh global_State *l_G; 3168e3e3a7aSWarner Losh CallInfo *ci; /* call info for current function */ 317*a9490b81SWarner Losh StkIdRel stack_last; /* end of stack (last element + 1) */ 318*a9490b81SWarner Losh StkIdRel stack; /* stack base */ 3198e3e3a7aSWarner Losh UpVal *openupval; /* list of open upvalues in this stack */ 320*a9490b81SWarner Losh StkIdRel tbclist; /* list of to-be-closed variables */ 3218e3e3a7aSWarner Losh GCObject *gclist; 3228e3e3a7aSWarner Losh struct lua_State *twups; /* list of threads with open upvalues */ 3238e3e3a7aSWarner Losh struct lua_longjmp *errorJmp; /* current error recover point */ 3248e3e3a7aSWarner Losh CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ 3258e3e3a7aSWarner Losh volatile lua_Hook hook; 3268e3e3a7aSWarner Losh ptrdiff_t errfunc; /* current error handling function (stack index) */ 3270495ed39SKyle Evans l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ 3280495ed39SKyle Evans int oldpc; /* last pc traced */ 3298e3e3a7aSWarner Losh int basehookcount; 3308e3e3a7aSWarner Losh int hookcount; 3310495ed39SKyle Evans volatile l_signalT hookmask; 3328e3e3a7aSWarner Losh }; 3338e3e3a7aSWarner Losh 3348e3e3a7aSWarner Losh 3358e3e3a7aSWarner Losh #define G(L) (L->l_G) 3368e3e3a7aSWarner Losh 3378c784bb8SWarner Losh /* 3388c784bb8SWarner Losh ** 'g->nilvalue' being a nil value flags that the state was completely 3398c784bb8SWarner Losh ** build. 3408c784bb8SWarner Losh */ 3418c784bb8SWarner Losh #define completestate(g) ttisnil(&g->nilvalue) 3428c784bb8SWarner Losh 3438e3e3a7aSWarner Losh 3448e3e3a7aSWarner Losh /* 3458e3e3a7aSWarner Losh ** Union of all collectable objects (only for conversions) 3460495ed39SKyle Evans ** ISO C99, 6.5.2.3 p.5: 3470495ed39SKyle Evans ** "if a union contains several structures that share a common initial 3480495ed39SKyle Evans ** sequence [...], and if the union object currently contains one 3490495ed39SKyle Evans ** of these structures, it is permitted to inspect the common initial 3500495ed39SKyle Evans ** part of any of them anywhere that a declaration of the complete type 3510495ed39SKyle Evans ** of the union is visible." 3528e3e3a7aSWarner Losh */ 3538e3e3a7aSWarner Losh union GCUnion { 3548e3e3a7aSWarner Losh GCObject gc; /* common header */ 3558e3e3a7aSWarner Losh struct TString ts; 3568e3e3a7aSWarner Losh struct Udata u; 3578e3e3a7aSWarner Losh union Closure cl; 3588e3e3a7aSWarner Losh struct Table h; 3598e3e3a7aSWarner Losh struct Proto p; 3608e3e3a7aSWarner Losh struct lua_State th; /* thread */ 3610495ed39SKyle Evans struct UpVal upv; 3628e3e3a7aSWarner Losh }; 3638e3e3a7aSWarner Losh 3648e3e3a7aSWarner Losh 3650495ed39SKyle Evans /* 3660495ed39SKyle Evans ** ISO C99, 6.7.2.1 p.14: 3670495ed39SKyle Evans ** "A pointer to a union object, suitably converted, points to each of 3680495ed39SKyle Evans ** its members [...], and vice versa." 3690495ed39SKyle Evans */ 3708e3e3a7aSWarner Losh #define cast_u(o) cast(union GCUnion *, (o)) 3718e3e3a7aSWarner Losh 3728e3e3a7aSWarner Losh /* macros to convert a GCObject into a specific value */ 3738e3e3a7aSWarner Losh #define gco2ts(o) \ 3748e3e3a7aSWarner Losh check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) 3750495ed39SKyle Evans #define gco2u(o) check_exp((o)->tt == LUA_VUSERDATA, &((cast_u(o))->u)) 3760495ed39SKyle Evans #define gco2lcl(o) check_exp((o)->tt == LUA_VLCL, &((cast_u(o))->cl.l)) 3770495ed39SKyle Evans #define gco2ccl(o) check_exp((o)->tt == LUA_VCCL, &((cast_u(o))->cl.c)) 3788e3e3a7aSWarner Losh #define gco2cl(o) \ 3798e3e3a7aSWarner Losh check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) 3800495ed39SKyle Evans #define gco2t(o) check_exp((o)->tt == LUA_VTABLE, &((cast_u(o))->h)) 3810495ed39SKyle Evans #define gco2p(o) check_exp((o)->tt == LUA_VPROTO, &((cast_u(o))->p)) 3820495ed39SKyle Evans #define gco2th(o) check_exp((o)->tt == LUA_VTHREAD, &((cast_u(o))->th)) 3830495ed39SKyle Evans #define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv)) 3848e3e3a7aSWarner Losh 3858e3e3a7aSWarner Losh 3860495ed39SKyle Evans /* 3870495ed39SKyle Evans ** macro to convert a Lua object into a GCObject 3880495ed39SKyle Evans ** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.) 3890495ed39SKyle Evans */ 3900495ed39SKyle Evans #define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc)) 3918e3e3a7aSWarner Losh 3928e3e3a7aSWarner Losh 3938e3e3a7aSWarner Losh /* actual number of total bytes allocated */ 3948e3e3a7aSWarner Losh #define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) 3958e3e3a7aSWarner Losh 3968e3e3a7aSWarner Losh LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 3978e3e3a7aSWarner Losh LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 3988e3e3a7aSWarner Losh LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 3998e3e3a7aSWarner Losh LUAI_FUNC void luaE_freeCI (lua_State *L); 4008e3e3a7aSWarner Losh LUAI_FUNC void luaE_shrinkCI (lua_State *L); 4010495ed39SKyle Evans LUAI_FUNC void luaE_checkcstack (lua_State *L); 4020495ed39SKyle Evans LUAI_FUNC void luaE_incCstack (lua_State *L); 4030495ed39SKyle Evans LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); 4040495ed39SKyle Evans LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); 4058c784bb8SWarner Losh LUAI_FUNC int luaE_resetthread (lua_State *L, int status); 4068e3e3a7aSWarner Losh 4078e3e3a7aSWarner Losh 4088e3e3a7aSWarner Losh #endif 4098e3e3a7aSWarner Losh 410