2 ** Auxiliary library for the Lua/C API.
3 ** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
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
24 /* -- Module registration ------------------------------------------------- */
26 LUALIB_API
const char *luaL_findtable(lua_State
*L
, int idx
,
27 const char *fname
, int szhint
)
30 lua_pushvalue(L
, idx
);
32 e
= strchr(fname
, '.');
33 if (e
== NULL
) e
= fname
+ strlen(fname
);
34 lua_pushlstring(L
, fname
, (size_t)(e
- fname
));
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
));
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 */
46 lua_remove(L
, -2); /* remove previous table */
52 static int libsize(const luaL_Reg
*l
)
55 for (; l
->name
; l
++) size
++;
59 LUALIB_API
void luaL_openlib(lua_State
*L
, const char *libname
,
60 const luaL_Reg
*l
, int nup
)
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
);
74 lua_setfield(L
, -3, libname
); /* _LOADED[libname] = new table */
76 lua_remove(L
, -2); /* remove _LOADED table */
77 lua_insert(L
, -(nup
+1)); /* move library table to below upvalues */
79 for (; l
->name
; l
++) {
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
);
86 lua_pop(L
, nup
); /* remove upvalues */
89 LUALIB_API
void luaL_register(lua_State
*L
, const char *libname
,
92 luaL_openlib(L
, libname
, l
, 0);
95 LUALIB_API
const char *luaL_gsub(lua_State
*L
, const char *s
,
96 const char *p
, const char *r
)
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' */
107 luaL_addstring(&b
, s
); /* push last suffix */
109 return lua_tostring(L
, -1);
112 /* -- Buffer handling ----------------------------------------------------- */
114 #define bufflen(B) ((size_t)((B)->p - (B)->buffer))
115 #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
117 static int emptybuffer(luaL_Buffer
*B
)
119 size_t l
= bufflen(B
);
121 return 0; /* put nothing on stack */
122 lua_pushlstring(B
->L
, B
->buffer
, l
);
128 static void adjuststack(luaL_Buffer
*B
)
132 int toget
= 1; /* number of levels to concat */
133 size_t toplen
= lua_strlen(L
, -1);
135 size_t l
= lua_strlen(L
, -(toget
+1));
136 if (!(B
->lvl
- toget
+ 1 >= LUA_MINSTACK
/2 || toplen
> l
))
140 } while (toget
< B
->lvl
);
141 lua_concat(L
, toget
);
142 B
->lvl
= B
->lvl
- toget
+ 1;
146 LUALIB_API
char *luaL_prepbuffer(luaL_Buffer
*B
)
153 LUALIB_API
void luaL_addlstring(luaL_Buffer
*B
, const char *s
, size_t l
)
156 luaL_addchar(B
, *s
++);
159 LUALIB_API
void luaL_addstring(luaL_Buffer
*B
, const char *s
)
161 luaL_addlstring(B
, s
, strlen(s
));
164 LUALIB_API
void luaL_pushresult(luaL_Buffer
*B
)
167 lua_concat(B
->L
, B
->lvl
);
171 LUALIB_API
void luaL_addvalue(luaL_Buffer
*B
)
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 */
179 lua_pop(L
, 1); /* remove from stack */
182 lua_insert(L
, -2); /* put buffer before new value */
183 B
->lvl
++; /* add new value into B stack */
188 LUALIB_API
void luaL_buffinit(lua_State
*L
, luaL_Buffer
*B
)
195 /* -- Reference management ------------------------------------------------ */
197 #define FREELIST_REF 0
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)
203 LUALIB_API
int luaL_ref(lua_State
*L
, int 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 */
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 */
221 lua_rawseti(L
, t
, ref
);
225 LUALIB_API
void luaL_unref(lua_State
*L
, int t
, int ref
)
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 */
236 /* -- Load Lua code ------------------------------------------------------- */
238 typedef struct FileReaderCtx
{
240 char buf
[LUAL_BUFFERSIZE
];
243 static const char *reader_file(lua_State
*L
, void *ud
, size_t *size
)
245 FileReaderCtx
*ctx
= (FileReaderCtx
*)ud
;
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
;
252 LUALIB_API
int luaL_loadfile(lua_State
*L
, const char *filename
)
256 const char *chunkname
;
258 ctx
.fp
= fopen(filename
, "rb");
259 if (ctx
.fp
== NULL
) {
260 lua_pushfstring(L
, "cannot open %s: %s", filename
, strerror(errno
));
263 chunkname
= lua_pushfstring(L
, "@%s", filename
);
266 chunkname
= "=stdin";
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
));
278 copyTV(L
, L
->top
-1, L
->top
);
284 typedef struct StringReaderCtx
{
289 static const char *reader_string(lua_State
*L
, void *ud
, size_t *size
)
291 StringReaderCtx
*ctx
= (StringReaderCtx
*)ud
;
293 if (ctx
->size
== 0) return NULL
;
299 LUALIB_API
int luaL_loadbuffer(lua_State
*L
, const char *buf
, size_t size
,
305 return lua_load(L
, reader_string
, &ctx
, name
);
308 LUALIB_API
int luaL_loadstring(lua_State
*L
, const char *s
)
310 return luaL_loadbuffer(L
, s
, strlen(s
), s
);
313 /* -- Default allocator and panic function -------------------------------- */
315 static int panic(lua_State
*L
)
317 fprintf(stderr
, "PANIC: unprotected error in call to Lua API (%s)\n",
318 lua_tostring(L
, -1));
322 #ifdef LUAJIT_USE_SYSMALLOC
325 #error "Must use builtin allocator for 64 bit target"
328 static void *mem_alloc(void *ud
, void *ptr
, size_t osize
, size_t nsize
)
336 return realloc(ptr
, nsize
);
340 LUALIB_API lua_State
*luaL_newstate(void)
342 lua_State
*L
= lua_newstate(mem_alloc
, NULL
);
343 if (L
) G(L
)->panic
= panic
;
349 #include "lj_alloc.h"
351 LUALIB_API lua_State
*luaL_newstate(void)
354 void *ud
= lj_alloc_create();
355 if (ud
== NULL
) return NULL
;
357 L
= lj_state_newstate(lj_alloc_f
, ud
);
359 L
= lua_newstate(lj_alloc_f
, ud
);
361 if (L
) G(L
)->panic
= panic
;
366 LUA_API lua_State
*lua_newstate(lua_Alloc f
, void *ud
)
368 UNUSED(f
); UNUSED(ud
);
369 fprintf(stderr
, "Must use luaL_newstate() for 64 bit target\n");