diff options
Diffstat (limited to 'libraries/luajit-2.0/src/lib_aux.c')
-rw-r--r-- | libraries/luajit-2.0/src/lib_aux.c | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/libraries/luajit-2.0/src/lib_aux.c b/libraries/luajit-2.0/src/lib_aux.c new file mode 100644 index 0000000..628d6a5 --- /dev/null +++ b/libraries/luajit-2.0/src/lib_aux.c | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | ** Auxiliary library for the Lua/C API. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | ** | ||
5 | ** Major parts taken verbatim or adapted from the Lua interpreter. | ||
6 | ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h | ||
7 | */ | ||
8 | |||
9 | #include <errno.h> | ||
10 | #include <stdarg.h> | ||
11 | #include <stdio.h> | ||
12 | |||
13 | #define lib_aux_c | ||
14 | #define LUA_LIB | ||
15 | |||
16 | #include "lua.h" | ||
17 | #include "lauxlib.h" | ||
18 | |||
19 | #include "lj_obj.h" | ||
20 | #include "lj_err.h" | ||
21 | #include "lj_state.h" | ||
22 | #include "lj_lib.h" | ||
23 | |||
24 | /* -- Module registration ------------------------------------------------- */ | ||
25 | |||
26 | LUALIB_API const char *luaL_findtable(lua_State *L, int idx, | ||
27 | const char *fname, int szhint) | ||
28 | { | ||
29 | const char *e; | ||
30 | lua_pushvalue(L, idx); | ||
31 | do { | ||
32 | e = strchr(fname, '.'); | ||
33 | if (e == NULL) e = fname + strlen(fname); | ||
34 | lua_pushlstring(L, fname, (size_t)(e - fname)); | ||
35 | lua_rawget(L, -2); | ||
36 | if (lua_isnil(L, -1)) { /* no such field? */ | ||
37 | lua_pop(L, 1); /* remove this nil */ | ||
38 | lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ | ||
39 | lua_pushlstring(L, fname, (size_t)(e - fname)); | ||
40 | lua_pushvalue(L, -2); | ||
41 | lua_settable(L, -4); /* set new table into field */ | ||
42 | } else if (!lua_istable(L, -1)) { /* field has a non-table value? */ | ||
43 | lua_pop(L, 2); /* remove table and value */ | ||
44 | return fname; /* return problematic part of the name */ | ||
45 | } | ||
46 | lua_remove(L, -2); /* remove previous table */ | ||
47 | fname = e + 1; | ||
48 | } while (*e == '.'); | ||
49 | return NULL; | ||
50 | } | ||
51 | |||
52 | static int libsize(const luaL_Reg *l) | ||
53 | { | ||
54 | int size = 0; | ||
55 | for (; l->name; l++) size++; | ||
56 | return size; | ||
57 | } | ||
58 | |||
59 | LUALIB_API void luaL_openlib(lua_State *L, const char *libname, | ||
60 | const luaL_Reg *l, int nup) | ||
61 | { | ||
62 | lj_lib_checkfpu(L); | ||
63 | if (libname) { | ||
64 | int size = libsize(l); | ||
65 | /* check whether lib already exists */ | ||
66 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16); | ||
67 | lua_getfield(L, -1, libname); /* get _LOADED[libname] */ | ||
68 | if (!lua_istable(L, -1)) { /* not found? */ | ||
69 | lua_pop(L, 1); /* remove previous result */ | ||
70 | /* try global variable (and create one if it does not exist) */ | ||
71 | if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) | ||
72 | lj_err_callerv(L, LJ_ERR_BADMODN, libname); | ||
73 | lua_pushvalue(L, -1); | ||
74 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ | ||
75 | } | ||
76 | lua_remove(L, -2); /* remove _LOADED table */ | ||
77 | lua_insert(L, -(nup+1)); /* move library table to below upvalues */ | ||
78 | } | ||
79 | for (; l->name; l++) { | ||
80 | int i; | ||
81 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ | ||
82 | lua_pushvalue(L, -nup); | ||
83 | lua_pushcclosure(L, l->func, nup); | ||
84 | lua_setfield(L, -(nup+2), l->name); | ||
85 | } | ||
86 | lua_pop(L, nup); /* remove upvalues */ | ||
87 | } | ||
88 | |||
89 | LUALIB_API void luaL_register(lua_State *L, const char *libname, | ||
90 | const luaL_Reg *l) | ||
91 | { | ||
92 | luaL_openlib(L, libname, l, 0); | ||
93 | } | ||
94 | |||
95 | LUALIB_API const char *luaL_gsub(lua_State *L, const char *s, | ||
96 | const char *p, const char *r) | ||
97 | { | ||
98 | const char *wild; | ||
99 | size_t l = strlen(p); | ||
100 | luaL_Buffer b; | ||
101 | luaL_buffinit(L, &b); | ||
102 | while ((wild = strstr(s, p)) != NULL) { | ||
103 | luaL_addlstring(&b, s, (size_t)(wild - s)); /* push prefix */ | ||
104 | luaL_addstring(&b, r); /* push replacement in place of pattern */ | ||
105 | s = wild + l; /* continue after `p' */ | ||
106 | } | ||
107 | luaL_addstring(&b, s); /* push last suffix */ | ||
108 | luaL_pushresult(&b); | ||
109 | return lua_tostring(L, -1); | ||
110 | } | ||
111 | |||
112 | /* -- Buffer handling ----------------------------------------------------- */ | ||
113 | |||
114 | #define bufflen(B) ((size_t)((B)->p - (B)->buffer)) | ||
115 | #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) | ||
116 | |||
117 | static int emptybuffer(luaL_Buffer *B) | ||
118 | { | ||
119 | size_t l = bufflen(B); | ||
120 | if (l == 0) | ||
121 | return 0; /* put nothing on stack */ | ||
122 | lua_pushlstring(B->L, B->buffer, l); | ||
123 | B->p = B->buffer; | ||
124 | B->lvl++; | ||
125 | return 1; | ||
126 | } | ||
127 | |||
128 | static void adjuststack(luaL_Buffer *B) | ||
129 | { | ||
130 | if (B->lvl > 1) { | ||
131 | lua_State *L = B->L; | ||
132 | int toget = 1; /* number of levels to concat */ | ||
133 | size_t toplen = lua_strlen(L, -1); | ||
134 | do { | ||
135 | size_t l = lua_strlen(L, -(toget+1)); | ||
136 | if (!(B->lvl - toget + 1 >= LUA_MINSTACK/2 || toplen > l)) | ||
137 | break; | ||
138 | toplen += l; | ||
139 | toget++; | ||
140 | } while (toget < B->lvl); | ||
141 | lua_concat(L, toget); | ||
142 | B->lvl = B->lvl - toget + 1; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | LUALIB_API char *luaL_prepbuffer(luaL_Buffer *B) | ||
147 | { | ||
148 | if (emptybuffer(B)) | ||
149 | adjuststack(B); | ||
150 | return B->buffer; | ||
151 | } | ||
152 | |||
153 | LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l) | ||
154 | { | ||
155 | while (l--) | ||
156 | luaL_addchar(B, *s++); | ||
157 | } | ||
158 | |||
159 | LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s) | ||
160 | { | ||
161 | luaL_addlstring(B, s, strlen(s)); | ||
162 | } | ||
163 | |||
164 | LUALIB_API void luaL_pushresult(luaL_Buffer *B) | ||
165 | { | ||
166 | emptybuffer(B); | ||
167 | lua_concat(B->L, B->lvl); | ||
168 | B->lvl = 1; | ||
169 | } | ||
170 | |||
171 | LUALIB_API void luaL_addvalue(luaL_Buffer *B) | ||
172 | { | ||
173 | lua_State *L = B->L; | ||
174 | size_t vl; | ||
175 | const char *s = lua_tolstring(L, -1, &vl); | ||
176 | if (vl <= bufffree(B)) { /* fit into buffer? */ | ||
177 | memcpy(B->p, s, vl); /* put it there */ | ||
178 | B->p += vl; | ||
179 | lua_pop(L, 1); /* remove from stack */ | ||
180 | } else { | ||
181 | if (emptybuffer(B)) | ||
182 | lua_insert(L, -2); /* put buffer before new value */ | ||
183 | B->lvl++; /* add new value into B stack */ | ||
184 | adjuststack(B); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B) | ||
189 | { | ||
190 | B->L = L; | ||
191 | B->p = B->buffer; | ||
192 | B->lvl = 0; | ||
193 | } | ||
194 | |||
195 | /* -- Reference management ------------------------------------------------ */ | ||
196 | |||
197 | #define FREELIST_REF 0 | ||
198 | |||
199 | /* Convert a stack index to an absolute index. */ | ||
200 | #define abs_index(L, i) \ | ||
201 | ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1) | ||
202 | |||
203 | LUALIB_API int luaL_ref(lua_State *L, int t) | ||
204 | { | ||
205 | int ref; | ||
206 | t = abs_index(L, t); | ||
207 | if (lua_isnil(L, -1)) { | ||
208 | lua_pop(L, 1); /* remove from stack */ | ||
209 | return LUA_REFNIL; /* `nil' has a unique fixed reference */ | ||
210 | } | ||
211 | lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ | ||
212 | ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ | ||
213 | lua_pop(L, 1); /* remove it from stack */ | ||
214 | if (ref != 0) { /* any free element? */ | ||
215 | lua_rawgeti(L, t, ref); /* remove it from list */ | ||
216 | lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ | ||
217 | } else { /* no free elements */ | ||
218 | ref = (int)lua_objlen(L, t); | ||
219 | ref++; /* create new reference */ | ||
220 | } | ||
221 | lua_rawseti(L, t, ref); | ||
222 | return ref; | ||
223 | } | ||
224 | |||
225 | LUALIB_API void luaL_unref(lua_State *L, int t, int ref) | ||
226 | { | ||
227 | if (ref >= 0) { | ||
228 | t = abs_index(L, t); | ||
229 | lua_rawgeti(L, t, FREELIST_REF); | ||
230 | lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ | ||
231 | lua_pushinteger(L, ref); | ||
232 | lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /* -- Load Lua code ------------------------------------------------------- */ | ||
237 | |||
238 | typedef struct FileReaderCtx { | ||
239 | FILE *fp; | ||
240 | char buf[LUAL_BUFFERSIZE]; | ||
241 | } FileReaderCtx; | ||
242 | |||
243 | static const char *reader_file(lua_State *L, void *ud, size_t *size) | ||
244 | { | ||
245 | FileReaderCtx *ctx = (FileReaderCtx *)ud; | ||
246 | UNUSED(L); | ||
247 | if (feof(ctx->fp)) return NULL; | ||
248 | *size = fread(ctx->buf, 1, sizeof(ctx->buf), ctx->fp); | ||
249 | return *size > 0 ? ctx->buf : NULL; | ||
250 | } | ||
251 | |||
252 | LUALIB_API int luaL_loadfile(lua_State *L, const char *filename) | ||
253 | { | ||
254 | FileReaderCtx ctx; | ||
255 | int status; | ||
256 | const char *chunkname; | ||
257 | if (filename) { | ||
258 | ctx.fp = fopen(filename, "rb"); | ||
259 | if (ctx.fp == NULL) { | ||
260 | lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno)); | ||
261 | return LUA_ERRFILE; | ||
262 | } | ||
263 | chunkname = lua_pushfstring(L, "@%s", filename); | ||
264 | } else { | ||
265 | ctx.fp = stdin; | ||
266 | chunkname = "=stdin"; | ||
267 | } | ||
268 | status = lua_load(L, reader_file, &ctx, chunkname); | ||
269 | if (ferror(ctx.fp)) { | ||
270 | L->top -= filename ? 2 : 1; | ||
271 | lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(errno)); | ||
272 | if (filename) | ||
273 | fclose(ctx.fp); | ||
274 | return LUA_ERRFILE; | ||
275 | } | ||
276 | if (filename) { | ||
277 | L->top--; | ||
278 | copyTV(L, L->top-1, L->top); | ||
279 | fclose(ctx.fp); | ||
280 | } | ||
281 | return status; | ||
282 | } | ||
283 | |||
284 | typedef struct StringReaderCtx { | ||
285 | const char *str; | ||
286 | size_t size; | ||
287 | } StringReaderCtx; | ||
288 | |||
289 | static const char *reader_string(lua_State *L, void *ud, size_t *size) | ||
290 | { | ||
291 | StringReaderCtx *ctx = (StringReaderCtx *)ud; | ||
292 | UNUSED(L); | ||
293 | if (ctx->size == 0) return NULL; | ||
294 | *size = ctx->size; | ||
295 | ctx->size = 0; | ||
296 | return ctx->str; | ||
297 | } | ||
298 | |||
299 | LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size, | ||
300 | const char *name) | ||
301 | { | ||
302 | StringReaderCtx ctx; | ||
303 | ctx.str = buf; | ||
304 | ctx.size = size; | ||
305 | return lua_load(L, reader_string, &ctx, name); | ||
306 | } | ||
307 | |||
308 | LUALIB_API int luaL_loadstring(lua_State *L, const char *s) | ||
309 | { | ||
310 | return luaL_loadbuffer(L, s, strlen(s), s); | ||
311 | } | ||
312 | |||
313 | /* -- Default allocator and panic function -------------------------------- */ | ||
314 | |||
315 | static int panic(lua_State *L) | ||
316 | { | ||
317 | fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", | ||
318 | lua_tostring(L, -1)); | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | #ifdef LUAJIT_USE_SYSMALLOC | ||
323 | |||
324 | #if LJ_64 | ||
325 | #error "Must use builtin allocator for 64 bit target" | ||
326 | #endif | ||
327 | |||
328 | static void *mem_alloc(void *ud, void *ptr, size_t osize, size_t nsize) | ||
329 | { | ||
330 | (void)ud; | ||
331 | (void)osize; | ||
332 | if (nsize == 0) { | ||
333 | free(ptr); | ||
334 | return NULL; | ||
335 | } else { | ||
336 | return realloc(ptr, nsize); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | LUALIB_API lua_State *luaL_newstate(void) | ||
341 | { | ||
342 | lua_State *L = lua_newstate(mem_alloc, NULL); | ||
343 | if (L) G(L)->panic = panic; | ||
344 | return L; | ||
345 | } | ||
346 | |||
347 | #else | ||
348 | |||
349 | #include "lj_alloc.h" | ||
350 | |||
351 | LUALIB_API lua_State *luaL_newstate(void) | ||
352 | { | ||
353 | lua_State *L; | ||
354 | void *ud = lj_alloc_create(); | ||
355 | if (ud == NULL) return NULL; | ||
356 | #if LJ_64 | ||
357 | L = lj_state_newstate(lj_alloc_f, ud); | ||
358 | #else | ||
359 | L = lua_newstate(lj_alloc_f, ud); | ||
360 | #endif | ||
361 | if (L) G(L)->panic = panic; | ||
362 | return L; | ||
363 | } | ||
364 | |||
365 | #if LJ_64 | ||
366 | LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) | ||
367 | { | ||
368 | UNUSED(f); UNUSED(ud); | ||
369 | fprintf(stderr, "Must use luaL_newstate() for 64 bit target\n"); | ||
370 | return NULL; | ||
371 | } | ||
372 | #endif | ||
373 | |||
374 | #endif | ||
375 | |||