aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/luajit-2.0/src/lj_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/luajit-2.0/src/lj_lib.c')
-rw-r--r--libraries/luajit-2.0/src/lj_lib.c260
1 files changed, 260 insertions, 0 deletions
diff --git a/libraries/luajit-2.0/src/lj_lib.c b/libraries/luajit-2.0/src/lj_lib.c
new file mode 100644
index 0000000..655ad08
--- /dev/null
+++ b/libraries/luajit-2.0/src/lj_lib.c
@@ -0,0 +1,260 @@
1/*
2** Library function support.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_lib_c
7#define LUA_CORE
8
9#include "lauxlib.h"
10
11#include "lj_obj.h"
12#include "lj_gc.h"
13#include "lj_err.h"
14#include "lj_str.h"
15#include "lj_tab.h"
16#include "lj_func.h"
17#include "lj_bc.h"
18#include "lj_dispatch.h"
19#include "lj_vm.h"
20#include "lj_lib.h"
21
22/* -- Library initialization ---------------------------------------------- */
23
24static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize)
25{
26 if (libname) {
27 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
28 lua_getfield(L, -1, libname);
29 if (!tvistab(L->top-1)) {
30 L->top--;
31 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, hsize) != NULL)
32 lj_err_callerv(L, LJ_ERR_BADMODN, libname);
33 settabV(L, L->top, tabV(L->top-1));
34 L->top++;
35 lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
36 }
37 L->top--;
38 settabV(L, L->top-1, tabV(L->top));
39 } else {
40 lua_createtable(L, 0, hsize);
41 }
42 return tabV(L->top-1);
43}
44
45void lj_lib_register(lua_State *L, const char *libname,
46 const uint8_t *p, const lua_CFunction *cf)
47{
48 GCtab *env = tabref(L->env);
49 GCfunc *ofn = NULL;
50 int ffid = *p++;
51 BCIns *bcff = &L2GG(L)->bcff[*p++];
52 GCtab *tab = lib_create_table(L, libname, *p++);
53 ptrdiff_t tpos = L->top - L->base;
54
55 /* Avoid barriers further down. */
56 lj_gc_anybarriert(L, tab);
57 tab->nomm = 0;
58
59 for (;;) {
60 uint32_t tag = *p++;
61 MSize len = tag & LIBINIT_LENMASK;
62 tag &= LIBINIT_TAGMASK;
63 if (tag != LIBINIT_STRING) {
64 const char *name;
65 MSize nuv = (MSize)(L->top - L->base - tpos);
66 GCfunc *fn = lj_func_newC(L, nuv, env);
67 if (nuv) {
68 L->top = L->base + tpos;
69 memcpy(fn->c.upvalue, L->top, sizeof(TValue)*nuv);
70 }
71 fn->c.ffid = (uint8_t)(ffid++);
72 name = (const char *)p;
73 p += len;
74 if (tag == LIBINIT_CF)
75 setmref(fn->c.pc, &G(L)->bc_cfunc_int);
76 else
77 setmref(fn->c.pc, bcff++);
78 if (tag == LIBINIT_ASM_)
79 fn->c.f = ofn->c.f; /* Copy handler from previous function. */
80 else
81 fn->c.f = *cf++; /* Get cf or handler from C function table. */
82 if (len) {
83 /* NOBARRIER: See above for common barrier. */
84 setfuncV(L, lj_tab_setstr(L, tab, lj_str_new(L, name, len)), fn);
85 }
86 ofn = fn;
87 } else {
88 switch (tag | len) {
89 case LIBINIT_SET:
90 L->top -= 2;
91 if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
92 env = tabV(L->top);
93 else /* NOBARRIER: See above for common barrier. */
94 copyTV(L, lj_tab_set(L, tab, L->top+1), L->top);
95 break;
96 case LIBINIT_NUMBER:
97 memcpy(&L->top->n, p, sizeof(double));
98 L->top++;
99 p += sizeof(double);
100 break;
101 case LIBINIT_COPY:
102 copyTV(L, L->top, L->top - *p++);
103 L->top++;
104 break;
105 case LIBINIT_LASTCL:
106 setfuncV(L, L->top++, ofn);
107 break;
108 case LIBINIT_FFID:
109 ffid++;
110 break;
111 case LIBINIT_END:
112 return;
113 default:
114 setstrV(L, L->top++, lj_str_new(L, (const char *)p, len));
115 p += len;
116 break;
117 }
118 }
119 }
120}
121
122/* -- Type checks --------------------------------------------------------- */
123
124TValue *lj_lib_checkany(lua_State *L, int narg)
125{
126 TValue *o = L->base + narg-1;
127 if (o >= L->top)
128 lj_err_arg(L, narg, LJ_ERR_NOVAL);
129 return o;
130}
131
132GCstr *lj_lib_checkstr(lua_State *L, int narg)
133{
134 TValue *o = L->base + narg-1;
135 if (o < L->top) {
136 if (LJ_LIKELY(tvisstr(o))) {
137 return strV(o);
138 } else if (tvisnumber(o)) {
139 GCstr *s = lj_str_fromnumber(L, o);
140 setstrV(L, o, s);
141 return s;
142 }
143 }
144 lj_err_argt(L, narg, LUA_TSTRING);
145 return NULL; /* unreachable */
146}
147
148GCstr *lj_lib_optstr(lua_State *L, int narg)
149{
150 TValue *o = L->base + narg-1;
151 return (o < L->top && !tvisnil(o)) ? lj_lib_checkstr(L, narg) : NULL;
152}
153
154#if LJ_DUALNUM
155void lj_lib_checknumber(lua_State *L, int narg)
156{
157 TValue *o = L->base + narg-1;
158 if (!(o < L->top &&
159 (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
160 lj_err_argt(L, narg, LUA_TNUMBER);
161}
162#endif
163
164lua_Number lj_lib_checknum(lua_State *L, int narg)
165{
166 TValue *o = L->base + narg-1;
167 if (!(o < L->top &&
168 (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
169 lj_err_argt(L, narg, LUA_TNUMBER);
170 if (LJ_UNLIKELY(tvisint(o))) {
171 lua_Number n = (lua_Number)intV(o);
172 setnumV(o, n);
173 return n;
174 } else {
175 return numV(o);
176 }
177}
178
179int32_t lj_lib_checkint(lua_State *L, int narg)
180{
181 TValue *o = L->base + narg-1;
182 if (!(o < L->top &&
183 (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
184 lj_err_argt(L, narg, LUA_TNUMBER);
185 if (LJ_LIKELY(tvisint(o))) {
186 return intV(o);
187 } else {
188 int32_t i = lj_num2int(numV(o));
189 if (LJ_DUALNUM) setintV(o, i);
190 return i;
191 }
192}
193
194int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
195{
196 TValue *o = L->base + narg-1;
197 return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
198}
199
200int32_t lj_lib_checkbit(lua_State *L, int narg)
201{
202 TValue *o = L->base + narg-1;
203 if (!(o < L->top &&
204 (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
205 lj_err_argt(L, narg, LUA_TNUMBER);
206 if (LJ_LIKELY(tvisint(o))) {
207 return intV(o);
208 } else {
209 int32_t i = lj_num2bit(numV(o));
210 if (LJ_DUALNUM) setintV(o, i);
211 return i;
212 }
213}
214
215GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
216{
217 TValue *o = L->base + narg-1;
218 if (!(o < L->top && tvisfunc(o)))
219 lj_err_argt(L, narg, LUA_TFUNCTION);
220 return funcV(o);
221}
222
223GCtab *lj_lib_checktab(lua_State *L, int narg)
224{
225 TValue *o = L->base + narg-1;
226 if (!(o < L->top && tvistab(o)))
227 lj_err_argt(L, narg, LUA_TTABLE);
228 return tabV(o);
229}
230
231GCtab *lj_lib_checktabornil(lua_State *L, int narg)
232{
233 TValue *o = L->base + narg-1;
234 if (o < L->top) {
235 if (tvistab(o))
236 return tabV(o);
237 else if (tvisnil(o))
238 return NULL;
239 }
240 lj_err_arg(L, narg, LJ_ERR_NOTABN);
241 return NULL; /* unreachable */
242}
243
244int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst)
245{
246 GCstr *s = def >= 0 ? lj_lib_optstr(L, narg) : lj_lib_checkstr(L, narg);
247 if (s) {
248 const char *opt = strdata(s);
249 MSize len = s->len;
250 int i;
251 for (i = 0; *(const uint8_t *)lst; i++) {
252 if (*(const uint8_t *)lst == len && memcmp(opt, lst+1, len) == 0)
253 return i;
254 lst += 1+*(const uint8_t *)lst;
255 }
256 lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
257 }
258 return def;
259}
260