2 ** Auxiliary library for the Lua/C API.
3 ** Copyright (C) 2005-2013 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
29 /* -- I/O error handling -------------------------------------------------- */
31 LUALIB_API
int luaL_fileresult(lua_State
*L
, int stat
, const char *fname
)
34 setboolV(L
->top
++, 1);
37 int en
= errno
; /* Lua API calls may change this value. */
40 lua_pushfstring(L
, "%s: %s", fname
, strerror(en
));
42 lua_pushfstring(L
, "%s", strerror(en
));
43 setintV(L
->top
++, en
);
49 LUALIB_API
int luaL_execresult(lua_State
*L
, int stat
)
53 if (WIFSIGNALED(stat
)) {
54 stat
= WTERMSIG(stat
);
56 lua_pushliteral(L
, "signal");
59 stat
= WEXITSTATUS(stat
);
61 setboolV(L
->top
++, 1);
64 lua_pushliteral(L
, "exit");
68 setboolV(L
->top
++, 1);
71 lua_pushliteral(L
, "exit");
73 setintV(L
->top
++, stat
);
76 return luaL_fileresult(L
, 0, NULL
);
79 /* -- Module registration ------------------------------------------------- */
81 LUALIB_API
const char *luaL_findtable(lua_State
*L
, int idx
,
82 const char *fname
, int szhint
)
85 lua_pushvalue(L
, idx
);
87 e
= strchr(fname
, '.');
88 if (e
== NULL
) e
= fname
+ strlen(fname
);
89 lua_pushlstring(L
, fname
, (size_t)(e
- fname
));
91 if (lua_isnil(L
, -1)) { /* no such field? */
92 lua_pop(L
, 1); /* remove this nil */
93 lua_createtable(L
, 0, (*e
== '.' ? 1 : szhint
)); /* new table for field */
94 lua_pushlstring(L
, fname
, (size_t)(e
- fname
));
96 lua_settable(L
, -4); /* set new table into field */
97 } else if (!lua_istable(L
, -1)) { /* field has a non-table value? */
98 lua_pop(L
, 2); /* remove table and value */
99 return fname
; /* return problematic part of the name */
101 lua_remove(L
, -2); /* remove previous table */
107 static int libsize(const luaL_Reg
*l
)
110 for (; l
->name
; l
++) size
++;
114 LUALIB_API
void luaL_openlib(lua_State
*L
, const char *libname
,
115 const luaL_Reg
*l
, int nup
)
119 int size
= libsize(l
);
120 /* check whether lib already exists */
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 */
131 lua_remove(L
, -2); /* remove _LOADED table */
132 lua_insert(L
, -(nup
+1)); /* move library table to below upvalues */
134 for (; l
->name
; l
++) {
136 for (i
= 0; i
< nup
; i
++) /* copy upvalues to the top */
137 lua_pushvalue(L
, -nup
);
138 lua_pushcclosure(L
, l
->func
, nup
);
139 lua_setfield(L
, -(nup
+2), l
->name
);
141 lua_pop(L
, nup
); /* remove upvalues */
144 LUALIB_API
void luaL_register(lua_State
*L
, const char *libname
,
147 luaL_openlib(L
, libname
, l
, 0);
150 LUALIB_API
const char *luaL_gsub(lua_State
*L
, const char *s
,
151 const char *p
, const char *r
)
154 size_t l
= strlen(p
);
156 luaL_buffinit(L
, &b
);
157 while ((wild
= strstr(s
, p
)) != NULL
) {
158 luaL_addlstring(&b
, s
, (size_t)(wild
- s
)); /* push prefix */
159 luaL_addstring(&b
, r
); /* push replacement in place of pattern */
160 s
= wild
+ l
; /* continue after `p' */
162 luaL_addstring(&b
, s
); /* push last suffix */
164 return lua_tostring(L
, -1);
167 /* -- Buffer handling ----------------------------------------------------- */
169 #define bufflen(B) ((size_t)((B)->p - (B)->buffer))
170 #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
172 static int emptybuffer(luaL_Buffer
*B
)
174 size_t l
= bufflen(B
);
176 return 0; /* put nothing on stack */
177 lua_pushlstring(B
->L
, B
->buffer
, l
);
183 static void adjuststack(luaL_Buffer
*B
)
187 int toget
= 1; /* number of levels to concat */
188 size_t toplen
= lua_strlen(L
, -1);
190 size_t l
= lua_strlen(L
, -(toget
+1));
191 if (!(B
->lvl
- toget
+ 1 >= LUA_MINSTACK
/2 || toplen
> l
))
195 } while (toget
< B
->lvl
);
196 lua_concat(L
, toget
);
197 B
->lvl
= B
->lvl
- toget
+ 1;
201 LUALIB_API
char *luaL_prepbuffer(luaL_Buffer
*B
)
208 LUALIB_API
void luaL_addlstring(luaL_Buffer
*B
, const char *s
, size_t l
)
211 luaL_addchar(B
, *s
++);
214 LUALIB_API
void luaL_addstring(luaL_Buffer
*B
, const char *s
)
216 luaL_addlstring(B
, s
, strlen(s
));
219 LUALIB_API
void luaL_pushresult(luaL_Buffer
*B
)
222 lua_concat(B
->L
, B
->lvl
);
226 LUALIB_API
void luaL_addvalue(luaL_Buffer
*B
)
230 const char *s
= lua_tolstring(L
, -1, &vl
);
231 if (vl
<= bufffree(B
)) { /* fit into buffer? */
232 memcpy(B
->p
, s
, vl
); /* put it there */
234 lua_pop(L
, 1); /* remove from stack */
237 lua_insert(L
, -2); /* put buffer before new value */
238 B
->lvl
++; /* add new value into B stack */
243 LUALIB_API
void luaL_buffinit(lua_State
*L
, luaL_Buffer
*B
)
250 /* -- Reference management ------------------------------------------------ */
252 #define FREELIST_REF 0
254 /* Convert a stack index to an absolute index. */
255 #define abs_index(L, i) \
256 ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
258 LUALIB_API
int luaL_ref(lua_State
*L
, int t
)
262 if (lua_isnil(L
, -1)) {
263 lua_pop(L
, 1); /* remove from stack */
264 return LUA_REFNIL
; /* `nil' has a unique fixed reference */
266 lua_rawgeti(L
, t
, FREELIST_REF
); /* get first free element */
267 ref
= (int)lua_tointeger(L
, -1); /* ref = t[FREELIST_REF] */
268 lua_pop(L
, 1); /* remove it from stack */
269 if (ref
!= 0) { /* any free element? */
270 lua_rawgeti(L
, t
, ref
); /* remove it from list */
271 lua_rawseti(L
, t
, FREELIST_REF
); /* (t[FREELIST_REF] = t[ref]) */
272 } else { /* no free elements */
273 ref
= (int)lua_objlen(L
, t
);
274 ref
++; /* create new reference */
276 lua_rawseti(L
, t
, ref
);
280 LUALIB_API
void luaL_unref(lua_State
*L
, int t
, int ref
)
284 lua_rawgeti(L
, t
, FREELIST_REF
);
285 lua_rawseti(L
, t
, ref
); /* t[ref] = t[FREELIST_REF] */
286 lua_pushinteger(L
, ref
);
287 lua_rawseti(L
, t
, FREELIST_REF
); /* t[FREELIST_REF] = ref */
291 /* -- Default allocator and panic function -------------------------------- */
293 static int panic(lua_State
*L
)
295 const char *s
= lua_tostring(L
, -1);
296 fputs("PANIC: unprotected error in call to Lua API (", stderr
);
297 fputs(s
? s
: "?", stderr
);
298 fputc(')', stderr
); fputc('\n', stderr
);
303 #ifdef LUAJIT_USE_SYSMALLOC
306 #error "Must use builtin allocator for 64 bit target"
309 static void *mem_alloc(void *ud
, void *ptr
, size_t osize
, size_t nsize
)
317 return realloc(ptr
, nsize
);
321 LUALIB_API lua_State
*luaL_newstate(void)
323 lua_State
*L
= lua_newstate(mem_alloc
, NULL
);
324 if (L
) G(L
)->panic
= panic
;
330 #include "lj_alloc.h"
332 LUALIB_API lua_State
*luaL_newstate(void)
335 void *ud
= lj_alloc_create();
336 if (ud
== NULL
) return NULL
;
338 L
= lj_state_newstate(lj_alloc_f
, ud
);
340 L
= lua_newstate(lj_alloc_f
, ud
);
342 if (L
) G(L
)->panic
= panic
;
347 LUA_API lua_State
*lua_newstate(lua_Alloc f
, void *ud
)
349 UNUSED(f
); UNUSED(ud
);
350 fputs("Must use luaL_newstate() for 64 bit target\n", stderr
);