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