aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/luajit-2.0/src/lib_aux.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/luajit-2.0/src/lib_aux.c')
-rw-r--r--libraries/luajit-2.0/src/lib_aux.c375
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
26LUALIB_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
52static int libsize(const luaL_Reg *l)
53{
54 int size = 0;
55 for (; l->name; l++) size++;
56 return size;
57}
58
59LUALIB_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
89LUALIB_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
95LUALIB_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
117static 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
128static 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
146LUALIB_API char *luaL_prepbuffer(luaL_Buffer *B)
147{
148 if (emptybuffer(B))
149 adjuststack(B);
150 return B->buffer;
151}
152
153LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l)
154{
155 while (l--)
156 luaL_addchar(B, *s++);
157}
158
159LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s)
160{
161 luaL_addlstring(B, s, strlen(s));
162}
163
164LUALIB_API void luaL_pushresult(luaL_Buffer *B)
165{
166 emptybuffer(B);
167 lua_concat(B->L, B->lvl);
168 B->lvl = 1;
169}
170
171LUALIB_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
188LUALIB_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
203LUALIB_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
225LUALIB_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
238typedef struct FileReaderCtx {
239 FILE *fp;
240 char buf[LUAL_BUFFERSIZE];
241} FileReaderCtx;
242
243static 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
252LUALIB_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
284typedef struct StringReaderCtx {
285 const char *str;
286 size_t size;
287} StringReaderCtx;
288
289static 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
299LUALIB_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
308LUALIB_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
315static 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
328static 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
340LUALIB_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
351LUALIB_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
366LUA_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