summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/lstate.c
diff options
context:
space:
mode:
authorRichard Quirk <richard.quirk@gmail.com>2014-03-19 19:31:31 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2014-04-02 20:31:54 +0200
commit36378988ad4059982742f05f5eb50580b456840a (patch)
treeee70be810d894566c5e351f21a1ebb79be742a85 /apps/plugins/lua/lstate.c
parent020f16a1c7d5bc9a302671cef03f56ac735e20c5 (diff)
downloadrockbox-36378988ad4059982742f05f5eb50580b456840a.tar.gz
rockbox-36378988ad4059982742f05f5eb50580b456840a.zip
Update lua plugin to 5.2.3
Prior to this patch the Lua plugin used version 5.1.4. This change reduces the number of modifications in the Lua source using some new defines and because the upstream source is now more flexible. Unless otherwise stated, l*.[ch] files are taken unmodified from the upstream lua-5.2.3. fscanf.c: file descriptors in rockbox are just ints, they are hidden behind a void* now so liolib requires less modifications. fscanf is updated to use void* too. getc.c: this is a new file required for getc implementation in lauxlib.c lauxlib.c: LoadF replaced FILE* with int, the rockbox file descriptor int are cast to FILE* (actually void* due to typedef). getc uses the PREFIX version. stdin is not used, as per 5.1.4. lbaselib.c: now uses strspn in the number parsing. print uses DEBUGF now rather than being commented out. lbitlib.c: use the built-in version from 5.2.3 rather than Reuben Thomas's external library. Backwards compatible and adds some new bit operations. ldo.c: the LUAI_THROW/TRY defines are now in the core lua code, so have been removed from rockconf.h liolib.c: here the implementation has changed to use the LStream from the original source, and cast the FILE* pointers to int. This has reduced the number of modifications from the upstream version. llex.c: the only change from upstream is to remove the locale include. lmathlib.c: updated from the 5.2.3 version and re-applied the changes that were made vs 5.1.4 for random numbers and to remove unsupported float functions. loadlib.c: upstream version, with the 5.1.4 changes for missing functions. lobject.c: upstream version, with ctype.h added and sprintf changed to snprintf. loslib.c: upstream version with locale.h removed and 5.1.4 changes for unsupportable functions. lstrlib.c: sprintf changed to snprintf. ltable.c: upstream with the hashnum function from 5.1.4 to avoid frexp in luai_hashnum. luaconf.h: updated to 5.2.3 version, restored relevant parts from the original 5.1.4 configuration. The COMPAT defines that are no longer available are not included. lundump.c: VERSION macro conflicts with the core Rockbox equivalent. rocklib.c: luaL_reg is no longer available, replaced by luaL_Reg equivalent. Moved checkboolean/optboolean functions to this file and out of core lua files. luaL_getn is no longer available, replaced by luaL_rawlen. luaL_register is deprecated, use the newlib/setfuncs replacements. rli_init has to be called before setting up the newlib to avoid overwriting the rb table. rocklib_aux.pl: use rli_checkboolean from rocklib.c. rocklua.c: new default bits library used, update the library loading code with idiomatic 5.2 code. strcspn.c: no longer needed, but strspn.c is required for strspn in lbaselib.c Change-Id: I0c7945c755f79083afe98ec117e1e8cf13de2651 Reviewed-on: http://gerrit.rockbox.org/774 Tested: Richard Quirk <richard.quirk@gmail.com> Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
Diffstat (limited to 'apps/plugins/lua/lstate.c')
-rw-r--r--apps/plugins/lua/lstate.c273
1 files changed, 191 insertions, 82 deletions
diff --git a/apps/plugins/lua/lstate.c b/apps/plugins/lua/lstate.c
index 4313b83a0c..c7f2672be7 100644
--- a/apps/plugins/lua/lstate.c
+++ b/apps/plugins/lua/lstate.c
@@ -1,17 +1,19 @@
1/* 1/*
2** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ 2** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#include <stddef.h> 8#include <stddef.h>
9#include <string.h>
9 10
10#define lstate_c 11#define lstate_c
11#define LUA_CORE 12#define LUA_CORE
12 13
13#include "lua.h" 14#include "lua.h"
14 15
16#include "lapi.h"
15#include "ldebug.h" 17#include "ldebug.h"
16#include "ldo.h" 18#include "ldo.h"
17#include "lfunc.h" 19#include "lfunc.h"
@@ -24,119 +26,240 @@
24#include "ltm.h" 26#include "ltm.h"
25 27
26 28
27#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) 29#if !defined(LUAI_GCPAUSE)
28#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) 30#define LUAI_GCPAUSE 200 /* 200% */
29#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) 31#endif
32
33#if !defined(LUAI_GCMAJOR)
34#define LUAI_GCMAJOR 200 /* 200% */
35#endif
36
37#if !defined(LUAI_GCMUL)
38#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
39#endif
40
41
42#define MEMERRMSG "not enough memory"
43
44
45/*
46** a macro to help the creation of a unique random seed when a state is
47** created; the seed is used to randomize hashes.
48*/
49#if !defined(luai_makeseed)
50#include <time.h>
51#define luai_makeseed() cast(unsigned int, time(NULL))
52#endif
53
54
55
56/*
57** thread state + extra space
58*/
59typedef struct LX {
60#if defined(LUAI_EXTRASPACE)
61 char buff[LUAI_EXTRASPACE];
62#endif
63 lua_State l;
64} LX;
30 65
31 66
32/* 67/*
33** Main thread combines a thread state and the global state 68** Main thread combines a thread state and the global state
34*/ 69*/
35typedef struct LG { 70typedef struct LG {
36 lua_State l; 71 LX l;
37 global_State g; 72 global_State g;
38} LG; 73} LG;
39 74
75
76
77#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
78
79
80/*
81** Compute an initial seed as random as possible. In ANSI, rely on
82** Address Space Layout Randomization (if present) to increase
83** randomness..
84*/
85#define addbuff(b,p,e) \
86 { size_t t = cast(size_t, e); \
87 memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); }
88
89static unsigned int makeseed (lua_State *L) {
90 char buff[4 * sizeof(size_t)];
91 unsigned int h = luai_makeseed();
92 int p = 0;
93 addbuff(buff, p, L); /* heap variable */
94 addbuff(buff, p, &h); /* local variable */
95 addbuff(buff, p, luaO_nilobject); /* global variable */
96 addbuff(buff, p, &lua_newstate); /* public function */
97 lua_assert(p == sizeof(buff));
98 return luaS_hash(buff, p, h);
99}
100
101
102/*
103** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
104** invariant
105*/
106void luaE_setdebt (global_State *g, l_mem debt) {
107 g->totalbytes -= (debt - g->GCdebt);
108 g->GCdebt = debt;
109}
110
111
112CallInfo *luaE_extendCI (lua_State *L) {
113 CallInfo *ci = luaM_new(L, CallInfo);
114 lua_assert(L->ci->next == NULL);
115 L->ci->next = ci;
116 ci->previous = L->ci;
117 ci->next = NULL;
118 return ci;
119}
120
121
122void luaE_freeCI (lua_State *L) {
123 CallInfo *ci = L->ci;
124 CallInfo *next = ci->next;
125 ci->next = NULL;
126 while ((ci = next) != NULL) {
127 next = ci->next;
128 luaM_free(L, ci);
129 }
130}
40 131
41 132
42static void stack_init (lua_State *L1, lua_State *L) { 133static void stack_init (lua_State *L1, lua_State *L) {
43 /* initialize CallInfo array */ 134 int i; CallInfo *ci;
44 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
45 L1->ci = L1->base_ci;
46 L1->size_ci = BASIC_CI_SIZE;
47 L1->end_ci = L1->base_ci + L1->size_ci - 1;
48 /* initialize stack array */ 135 /* initialize stack array */
49 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); 136 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
50 L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; 137 L1->stacksize = BASIC_STACK_SIZE;
138 for (i = 0; i < BASIC_STACK_SIZE; i++)
139 setnilvalue(L1->stack + i); /* erase new stack */
51 L1->top = L1->stack; 140 L1->top = L1->stack;
52 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 141 L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
53 /* initialize first ci */ 142 /* initialize first ci */
54 L1->ci->func = L1->top; 143 ci = &L1->base_ci;
55 setnilvalue(L1->top++); /* `function' entry for this `ci' */ 144 ci->next = ci->previous = NULL;
56 L1->base = L1->ci->base = L1->top; 145 ci->callstatus = 0;
57 L1->ci->top = L1->top + LUA_MINSTACK; 146 ci->func = L1->top;
147 setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
148 ci->top = L1->top + LUA_MINSTACK;
149 L1->ci = ci;
150}
151
152
153static void freestack (lua_State *L) {
154 if (L->stack == NULL)
155 return; /* stack not completely built yet */
156 L->ci = &L->base_ci; /* free the entire 'ci' list */
157 luaE_freeCI(L);
158 luaM_freearray(L, L->stack, L->stacksize); /* free stack array */
58} 159}
59 160
60 161
61static void freestack (lua_State *L, lua_State *L1) { 162/*
62 luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); 163** Create registry table and its predefined values
63 luaM_freearray(L, L1->stack, L1->stacksize, TValue); 164*/
165static void init_registry (lua_State *L, global_State *g) {
166 TValue mt;
167 /* create registry */
168 Table *registry = luaH_new(L);
169 sethvalue(L, &g->l_registry, registry);
170 luaH_resize(L, registry, LUA_RIDX_LAST, 0);
171 /* registry[LUA_RIDX_MAINTHREAD] = L */
172 setthvalue(L, &mt, L);
173 luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
174 /* registry[LUA_RIDX_GLOBALS] = table of globals */
175 sethvalue(L, &mt, luaH_new(L));
176 luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
64} 177}
65 178
66 179
67/* 180/*
68** open parts that may cause memory-allocation errors 181** open parts of the state that may cause memory-allocation errors
69*/ 182*/
70static void f_luaopen (lua_State *L, void *ud) { 183static void f_luaopen (lua_State *L, void *ud) {
71 global_State *g = G(L); 184 global_State *g = G(L);
72 UNUSED(ud); 185 UNUSED(ud);
73 stack_init(L, L); /* init stack */ 186 stack_init(L, L); /* init stack */
74 sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ 187 init_registry(L, g);
75 sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
76 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 188 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
77 luaT_init(L); 189 luaT_init(L);
78 luaX_init(L); 190 luaX_init(L);
79 luaS_fix(luaS_newliteral(L, MEMERRMSG)); 191 /* pre-create memory-error message */
80 g->GCthreshold = 4*g->totalbytes; 192 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
193 luaS_fix(g->memerrmsg); /* it should never be collected */
194 g->gcrunning = 1; /* allow gc */
195 g->version = lua_version(NULL);
196 luai_userstateopen(L);
81} 197}
82 198
83 199
200/*
201** preinitialize a state with consistent values without allocating
202** any memory (to avoid errors)
203*/
84static void preinit_state (lua_State *L, global_State *g) { 204static void preinit_state (lua_State *L, global_State *g) {
85 G(L) = g; 205 G(L) = g;
86 L->stack = NULL; 206 L->stack = NULL;
207 L->ci = NULL;
87 L->stacksize = 0; 208 L->stacksize = 0;
88 L->errorJmp = NULL; 209 L->errorJmp = NULL;
210 L->nCcalls = 0;
89 L->hook = NULL; 211 L->hook = NULL;
90 L->hookmask = 0; 212 L->hookmask = 0;
91 L->basehookcount = 0; 213 L->basehookcount = 0;
92 L->allowhook = 1; 214 L->allowhook = 1;
93 resethookcount(L); 215 resethookcount(L);
94 L->openupval = NULL; 216 L->openupval = NULL;
95 L->size_ci = 0; 217 L->nny = 1;
96 L->nCcalls = L->baseCcalls = 0; 218 L->status = LUA_OK;
97 L->status = 0;
98 L->base_ci = L->ci = NULL;
99 L->savedpc = NULL;
100 L->errfunc = 0; 219 L->errfunc = 0;
101 setnilvalue(gt(L));
102} 220}
103 221
104 222
105static void close_state (lua_State *L) { 223static void close_state (lua_State *L) {
106 global_State *g = G(L); 224 global_State *g = G(L);
107 luaF_close(L, L->stack); /* close all upvalues for this thread */ 225 luaF_close(L, L->stack); /* close all upvalues for this thread */
108 luaC_freeall(L); /* collect all objects */ 226 luaC_freeallobjects(L); /* collect all objects */
109 lua_assert(g->rootgc == obj2gco(L)); 227 if (g->version) /* closing a fully built state? */
110 lua_assert(g->strt.nuse == 0); 228 luai_userstateclose(L);
111 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); 229 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
112 luaZ_freebuffer(L, &g->buff); 230 luaZ_freebuffer(L, &g->buff);
113 freestack(L, L); 231 freestack(L);
114 lua_assert(g->totalbytes == sizeof(LG)); 232 lua_assert(gettotalbytes(g) == sizeof(LG));
115 (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); 233 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
116} 234}
117 235
118 236
119lua_State *luaE_newthread (lua_State *L) { 237LUA_API lua_State *lua_newthread (lua_State *L) {
120 lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); 238 lua_State *L1;
121 luaC_link(L, obj2gco(L1), LUA_TTHREAD); 239 lua_lock(L);
240 luaC_checkGC(L);
241 L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
242 setthvalue(L, L->top, L1);
243 api_incr_top(L);
122 preinit_state(L1, G(L)); 244 preinit_state(L1, G(L));
123 stack_init(L1, L); /* init stack */
124 setobj2n(L, gt(L1), gt(L)); /* share table of globals */
125 L1->hookmask = L->hookmask; 245 L1->hookmask = L->hookmask;
126 L1->basehookcount = L->basehookcount; 246 L1->basehookcount = L->basehookcount;
127 L1->hook = L->hook; 247 L1->hook = L->hook;
128 resethookcount(L1); 248 resethookcount(L1);
129 lua_assert(iswhite(obj2gco(L1))); 249 luai_userstatethread(L, L1);
250 stack_init(L1, L); /* init stack */
251 lua_unlock(L);
130 return L1; 252 return L1;
131} 253}
132 254
133 255
134void luaE_freethread (lua_State *L, lua_State *L1) { 256void luaE_freethread (lua_State *L, lua_State *L1) {
257 LX *l = fromstate(L1);
135 luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 258 luaF_close(L1, L1->stack); /* close all upvalues for this thread */
136 lua_assert(L1->openupval == NULL); 259 lua_assert(L1->openupval == NULL);
137 luai_userstatefree(L1); 260 luai_userstatefree(L, L1);
138 freestack(L, L1); 261 freestack(L1);
139 luaM_freemem(L, fromstate(L1), state_size(lua_State)); 262 luaM_free(L, l);
140} 263}
141 264
142 265
@@ -144,71 +267,57 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
144 int i; 267 int i;
145 lua_State *L; 268 lua_State *L;
146 global_State *g; 269 global_State *g;
147 void *l = (*f)(ud, NULL, 0, state_size(LG)); 270 LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
148 if (l == NULL) return NULL; 271 if (l == NULL) return NULL;
149 L = tostate(l); 272 L = &l->l.l;
150 g = &((LG *)L)->g; 273 g = &l->g;
151 L->next = NULL; 274 L->next = NULL;
152 L->tt = LUA_TTHREAD; 275 L->tt = LUA_TTHREAD;
153 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 276 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
154 L->marked = luaC_white(g); 277 L->marked = luaC_white(g);
155 set2bits(L->marked, FIXEDBIT, SFIXEDBIT); 278 g->gckind = KGC_NORMAL;
156 preinit_state(L, g); 279 preinit_state(L, g);
157 g->frealloc = f; 280 g->frealloc = f;
158 g->ud = ud; 281 g->ud = ud;
159 g->mainthread = L; 282 g->mainthread = L;
283 g->seed = makeseed(L);
160 g->uvhead.u.l.prev = &g->uvhead; 284 g->uvhead.u.l.prev = &g->uvhead;
161 g->uvhead.u.l.next = &g->uvhead; 285 g->uvhead.u.l.next = &g->uvhead;
162 g->GCthreshold = 0; /* mark it as unfinished state */ 286 g->gcrunning = 0; /* no GC while building state */
287 g->GCestimate = 0;
163 g->strt.size = 0; 288 g->strt.size = 0;
164 g->strt.nuse = 0; 289 g->strt.nuse = 0;
165 g->strt.hash = NULL; 290 g->strt.hash = NULL;
166 setnilvalue(registry(L)); 291 setnilvalue(&g->l_registry);
167 luaZ_initbuffer(L, &g->buff); 292 luaZ_initbuffer(L, &g->buff);
168 g->panic = NULL; 293 g->panic = NULL;
294 g->version = NULL;
169 g->gcstate = GCSpause; 295 g->gcstate = GCSpause;
170 g->rootgc = obj2gco(L); 296 g->allgc = NULL;
171 g->sweepstrgc = 0; 297 g->finobj = NULL;
172 g->sweepgc = &g->rootgc; 298 g->tobefnz = NULL;
173 g->gray = NULL; 299 g->sweepgc = g->sweepfin = NULL;
174 g->grayagain = NULL; 300 g->gray = g->grayagain = NULL;
175 g->weak = NULL; 301 g->weak = g->ephemeron = g->allweak = NULL;
176 g->tmudata = NULL;
177 g->totalbytes = sizeof(LG); 302 g->totalbytes = sizeof(LG);
303 g->GCdebt = 0;
178 g->gcpause = LUAI_GCPAUSE; 304 g->gcpause = LUAI_GCPAUSE;
305 g->gcmajorinc = LUAI_GCMAJOR;
179 g->gcstepmul = LUAI_GCMUL; 306 g->gcstepmul = LUAI_GCMUL;
180 g->gcdept = 0; 307 for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
181 for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; 308 if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
182 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
183 /* memory allocation error: free partial state */ 309 /* memory allocation error: free partial state */
184 close_state(L); 310 close_state(L);
185 L = NULL; 311 L = NULL;
186 } 312 }
187 else
188 luai_userstateopen(L);
189 return L; 313 return L;
190} 314}
191 315
192 316
193static void callallgcTM (lua_State *L, void *ud) {
194 UNUSED(ud);
195 luaC_callGCTM(L); /* call GC metamethods for all udata */
196}
197
198
199LUA_API void lua_close (lua_State *L) { 317LUA_API void lua_close (lua_State *L) {
200 L = G(L)->mainthread; /* only the main thread can be closed */ 318 L = G(L)->mainthread; /* only the main thread can be closed */
201 lua_lock(L); 319 lua_lock(L);
202 luaF_close(L, L->stack); /* close all upvalues for this thread */
203 luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
204 L->errfunc = 0; /* no error function during GC metamethods */
205 do { /* repeat until no more errors */
206 L->ci = L->base_ci;
207 L->base = L->top = L->ci->base;
208 L->nCcalls = L->baseCcalls = 0;
209 } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
210 lua_assert(G(L)->tmudata == NULL);
211 luai_userstateclose(L);
212 close_state(L); 320 close_state(L);
213} 321}
214 322
323