diff options
Diffstat (limited to 'src/lib_aux.c')
-rw-r--r-- | src/lib_aux.c | 117 |
1 files changed, 81 insertions, 36 deletions
diff --git a/src/lib_aux.c b/src/lib_aux.c index 8a64f185..7e81ac30 100644 --- a/src/lib_aux.c +++ b/src/lib_aux.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "lj_state.h" | 21 | #include "lj_state.h" |
22 | #include "lj_trace.h" | 22 | #include "lj_trace.h" |
23 | #include "lj_lib.h" | 23 | #include "lj_lib.h" |
24 | #include "lj_vmevent.h" | ||
24 | 25 | ||
25 | #if LJ_TARGET_POSIX | 26 | #if LJ_TARGET_POSIX |
26 | #include <sys/wait.h> | 27 | #include <sys/wait.h> |
@@ -107,38 +108,36 @@ LUALIB_API const char *luaL_findtable(lua_State *L, int idx, | |||
107 | static int libsize(const luaL_Reg *l) | 108 | static int libsize(const luaL_Reg *l) |
108 | { | 109 | { |
109 | int size = 0; | 110 | int size = 0; |
110 | for (; l->name; l++) size++; | 111 | for (; l && l->name; l++) size++; |
111 | return size; | 112 | return size; |
112 | } | 113 | } |
113 | 114 | ||
115 | LUALIB_API void luaL_pushmodule(lua_State *L, const char *modname, int sizehint) | ||
116 | { | ||
117 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16); | ||
118 | lua_getfield(L, -1, modname); | ||
119 | if (!lua_istable(L, -1)) { | ||
120 | lua_pop(L, 1); | ||
121 | if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, sizehint) != NULL) | ||
122 | lj_err_callerv(L, LJ_ERR_BADMODN, modname); | ||
123 | lua_pushvalue(L, -1); | ||
124 | lua_setfield(L, -3, modname); /* _LOADED[modname] = new table. */ | ||
125 | } | ||
126 | lua_remove(L, -2); /* Remove _LOADED table. */ | ||
127 | } | ||
128 | |||
114 | LUALIB_API void luaL_openlib(lua_State *L, const char *libname, | 129 | LUALIB_API void luaL_openlib(lua_State *L, const char *libname, |
115 | const luaL_Reg *l, int nup) | 130 | const luaL_Reg *l, int nup) |
116 | { | 131 | { |
117 | lj_lib_checkfpu(L); | 132 | lj_lib_checkfpu(L); |
118 | if (libname) { | 133 | if (libname) { |
119 | int size = libsize(l); | 134 | luaL_pushmodule(L, libname, libsize(l)); |
120 | /* check whether lib already exists */ | 135 | lua_insert(L, -(nup + 1)); /* Move module table below upvalues. */ |
121 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16); | ||
122 | lua_getfield(L, -1, libname); /* get _LOADED[libname] */ | ||
123 | if (!lua_istable(L, -1)) { /* not found? */ | ||
124 | lua_pop(L, 1); /* remove previous result */ | ||
125 | /* try global variable (and create one if it does not exist) */ | ||
126 | if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) | ||
127 | lj_err_callerv(L, LJ_ERR_BADMODN, libname); | ||
128 | lua_pushvalue(L, -1); | ||
129 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ | ||
130 | } | ||
131 | lua_remove(L, -2); /* remove _LOADED table */ | ||
132 | lua_insert(L, -(nup+1)); /* move library table to below upvalues */ | ||
133 | } | 136 | } |
134 | for (; l->name; l++) { | 137 | if (l) |
135 | int i; | 138 | luaL_setfuncs(L, l, nup); |
136 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ | 139 | else |
137 | lua_pushvalue(L, -nup); | 140 | lua_pop(L, nup); /* Remove upvalues. */ |
138 | lua_pushcclosure(L, l->func, nup); | ||
139 | lua_setfield(L, -(nup+2), l->name); | ||
140 | } | ||
141 | lua_pop(L, nup); /* remove upvalues */ | ||
142 | } | 141 | } |
143 | 142 | ||
144 | LUALIB_API void luaL_register(lua_State *L, const char *libname, | 143 | LUALIB_API void luaL_register(lua_State *L, const char *libname, |
@@ -147,6 +146,19 @@ LUALIB_API void luaL_register(lua_State *L, const char *libname, | |||
147 | luaL_openlib(L, libname, l, 0); | 146 | luaL_openlib(L, libname, l, 0); |
148 | } | 147 | } |
149 | 148 | ||
149 | LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) | ||
150 | { | ||
151 | luaL_checkstack(L, nup, "too many upvalues"); | ||
152 | for (; l->name; l++) { | ||
153 | int i; | ||
154 | for (i = 0; i < nup; i++) /* Copy upvalues to the top. */ | ||
155 | lua_pushvalue(L, -nup); | ||
156 | lua_pushcclosure(L, l->func, nup); | ||
157 | lua_setfield(L, -(nup + 2), l->name); | ||
158 | } | ||
159 | lua_pop(L, nup); /* Remove upvalues. */ | ||
160 | } | ||
161 | |||
150 | LUALIB_API const char *luaL_gsub(lua_State *L, const char *s, | 162 | LUALIB_API const char *luaL_gsub(lua_State *L, const char *s, |
151 | const char *p, const char *r) | 163 | const char *p, const char *r) |
152 | { | 164 | { |
@@ -207,8 +219,15 @@ LUALIB_API char *luaL_prepbuffer(luaL_Buffer *B) | |||
207 | 219 | ||
208 | LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l) | 220 | LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l) |
209 | { | 221 | { |
210 | while (l--) | 222 | if (l <= bufffree(B)) { |
211 | luaL_addchar(B, *s++); | 223 | memcpy(B->p, s, l); |
224 | B->p += l; | ||
225 | } else { | ||
226 | emptybuffer(B); | ||
227 | lua_pushlstring(B->L, s, l); | ||
228 | B->lvl++; | ||
229 | adjuststack(B); | ||
230 | } | ||
212 | } | 231 | } |
213 | 232 | ||
214 | LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s) | 233 | LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s) |
@@ -300,9 +319,21 @@ static int panic(lua_State *L) | |||
300 | return 0; | 319 | return 0; |
301 | } | 320 | } |
302 | 321 | ||
322 | #ifndef LUAJIT_DISABLE_VMEVENT | ||
323 | static int error_finalizer(lua_State *L) | ||
324 | { | ||
325 | const char *s = lua_tostring(L, -1); | ||
326 | fputs("ERROR in finalizer: ", stderr); | ||
327 | fputs(s ? s : "?", stderr); | ||
328 | fputc('\n', stderr); | ||
329 | fflush(stderr); | ||
330 | return 0; | ||
331 | } | ||
332 | #endif | ||
333 | |||
303 | #ifdef LUAJIT_USE_SYSMALLOC | 334 | #ifdef LUAJIT_USE_SYSMALLOC |
304 | 335 | ||
305 | #if LJ_64 && !defined(LUAJIT_USE_VALGRIND) | 336 | #if LJ_64 && !LJ_GC64 && !defined(LUAJIT_USE_VALGRIND) |
306 | #error "Must use builtin allocator for 64 bit target" | 337 | #error "Must use builtin allocator for 64 bit target" |
307 | #endif | 338 | #endif |
308 | 339 | ||
@@ -321,29 +352,43 @@ static void *mem_alloc(void *ud, void *ptr, size_t osize, size_t nsize) | |||
321 | LUALIB_API lua_State *luaL_newstate(void) | 352 | LUALIB_API lua_State *luaL_newstate(void) |
322 | { | 353 | { |
323 | lua_State *L = lua_newstate(mem_alloc, NULL); | 354 | lua_State *L = lua_newstate(mem_alloc, NULL); |
324 | if (L) G(L)->panic = panic; | 355 | if (L) { |
356 | G(L)->panic = panic; | ||
357 | #ifndef LUAJIT_DISABLE_VMEVENT | ||
358 | luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE); | ||
359 | lua_pushcfunction(L, error_finalizer); | ||
360 | lua_rawseti(L, -2, VMEVENT_HASH(LJ_VMEVENT_ERRFIN)); | ||
361 | G(L)->vmevmask = VMEVENT_MASK(LJ_VMEVENT_ERRFIN); | ||
362 | L->top--; | ||
363 | #endif | ||
364 | } | ||
325 | return L; | 365 | return L; |
326 | } | 366 | } |
327 | 367 | ||
328 | #else | 368 | #else |
329 | 369 | ||
330 | #include "lj_alloc.h" | ||
331 | |||
332 | LUALIB_API lua_State *luaL_newstate(void) | 370 | LUALIB_API lua_State *luaL_newstate(void) |
333 | { | 371 | { |
334 | lua_State *L; | 372 | lua_State *L; |
335 | void *ud = lj_alloc_create(); | 373 | #if LJ_64 && !LJ_GC64 |
336 | if (ud == NULL) return NULL; | 374 | L = lj_state_newstate(LJ_ALLOCF_INTERNAL, NULL); |
337 | #if LJ_64 | ||
338 | L = lj_state_newstate(lj_alloc_f, ud); | ||
339 | #else | 375 | #else |
340 | L = lua_newstate(lj_alloc_f, ud); | 376 | L = lua_newstate(LJ_ALLOCF_INTERNAL, NULL); |
341 | #endif | 377 | #endif |
342 | if (L) G(L)->panic = panic; | 378 | if (L) { |
379 | G(L)->panic = panic; | ||
380 | #ifndef LUAJIT_DISABLE_VMEVENT | ||
381 | luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE); | ||
382 | lua_pushcfunction(L, error_finalizer); | ||
383 | lua_rawseti(L, -2, VMEVENT_HASH(LJ_VMEVENT_ERRFIN)); | ||
384 | G(L)->vmevmask = VMEVENT_MASK(LJ_VMEVENT_ERRFIN); | ||
385 | L->top--; | ||
386 | #endif | ||
387 | } | ||
343 | return L; | 388 | return L; |
344 | } | 389 | } |
345 | 390 | ||
346 | #if LJ_64 | 391 | #if LJ_64 && !LJ_GC64 |
347 | LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) | 392 | LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) |
348 | { | 393 | { |
349 | UNUSED(f); UNUSED(ud); | 394 | UNUSED(f); UNUSED(ud); |