1 /*
2 ** Library function support.
3 ** Copyright (C) 2005-2021 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 #if LJ_HASFFI
20 #include "lj_ctype.h"
21 #endif
22 #include "lj_vm.h"
23 #include "lj_strscan.h"
24 #include "lj_strfmt.h"
25 #include "lj_lex.h"
26 #include "lj_bcdump.h"
27 #include "lj_lib.h"
28 
29 /* -- Library initialization ---------------------------------------------- */
30 
lib_create_table(lua_State * L,const char * libname,int hsize)31 static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize)
32 {
33   if (libname) {
34     luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
35     lua_getfield(L, -1, libname);
36     if (!tvistab(L->top-1)) {
37       L->top--;
38       if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, hsize) != NULL)
39 	lj_err_callerv(L, LJ_ERR_BADMODN, libname);
40       settabV(L, L->top, tabV(L->top-1));
41       L->top++;
42       lua_setfield(L, -3, libname);  /* _LOADED[libname] = new table */
43     }
44     L->top--;
45     settabV(L, L->top-1, tabV(L->top));
46   } else {
47     lua_createtable(L, 0, hsize);
48   }
49   return tabV(L->top-1);
50 }
51 
lib_read_lfunc(lua_State * L,const uint8_t * p,GCtab * tab)52 static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab)
53 {
54   int len = *p++;
55   GCstr *name = lj_str_new(L, (const char *)p, len);
56   LexState ls;
57   GCproto *pt;
58   GCfunc *fn;
59   memset(&ls, 0, sizeof(ls));
60   ls.L = L;
61   ls.p = (const char *)(p+len);
62   ls.pe = (const char *)~(uintptr_t)0;
63   ls.c = -1;
64   ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE));
65   ls.chunkname = name;
66   pt = lj_bcread_proto(&ls);
67   pt->firstline = ~(BCLine)0;
68   fn = lj_func_newL_empty(L, pt, tabref(L->env));
69   /* NOBARRIER: See below for common barrier. */
70   setfuncV(L, lj_tab_setstr(L, tab, name), fn);
71   return (const uint8_t *)ls.p;
72 }
73 
lj_lib_register(lua_State * L,const char * libname,const uint8_t * p,const lua_CFunction * cf)74 void lj_lib_register(lua_State *L, const char *libname,
75 		     const uint8_t *p, const lua_CFunction *cf)
76 {
77   GCtab *env = tabref(L->env);
78   GCfunc *ofn = NULL;
79   int ffid = *p++;
80   BCIns *bcff = &L2GG(L)->bcff[*p++];
81   GCtab *tab = lib_create_table(L, libname, *p++);
82   ptrdiff_t tpos = L->top - L->base;
83 
84   /* Avoid barriers further down. */
85   lj_gc_anybarriert(L, tab);
86   tab->nomm = 0;
87 
88   for (;;) {
89     uint32_t tag = *p++;
90     MSize len = tag & LIBINIT_LENMASK;
91     tag &= LIBINIT_TAGMASK;
92     if (tag != LIBINIT_STRING) {
93       const char *name;
94       MSize nuv = (MSize)(L->top - L->base - tpos);
95       GCfunc *fn = lj_func_newC(L, nuv, env);
96       if (nuv) {
97 	L->top = L->base + tpos;
98 	memcpy(fn->c.upvalue, L->top, sizeof(TValue)*nuv);
99       }
100       fn->c.ffid = (uint8_t)(ffid++);
101       name = (const char *)p;
102       p += len;
103       if (tag == LIBINIT_CF)
104 	setmref(fn->c.pc, &G(L)->bc_cfunc_int);
105       else
106 	setmref(fn->c.pc, bcff++);
107       if (tag == LIBINIT_ASM_)
108 	fn->c.f = ofn->c.f;  /* Copy handler from previous function. */
109       else
110 	fn->c.f = *cf++;  /* Get cf or handler from C function table. */
111       if (len) {
112 	/* NOBARRIER: See above for common barrier. */
113 	setfuncV(L, lj_tab_setstr(L, tab, lj_str_new(L, name, len)), fn);
114       }
115       ofn = fn;
116     } else {
117       switch (tag | len) {
118       case LIBINIT_LUA:
119 	p = lib_read_lfunc(L, p, tab);
120 	break;
121       case LIBINIT_SET:
122 	L->top -= 2;
123 	if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
124 	  env = tabV(L->top);
125 	else  /* NOBARRIER: See above for common barrier. */
126 	  copyTV(L, lj_tab_set(L, tab, L->top+1), L->top);
127 	break;
128       case LIBINIT_NUMBER:
129 	memcpy(&L->top->n, p, sizeof(double));
130 	L->top++;
131 	p += sizeof(double);
132 	break;
133       case LIBINIT_COPY:
134 	copyTV(L, L->top, L->top - *p++);
135 	L->top++;
136 	break;
137       case LIBINIT_LASTCL:
138 	setfuncV(L, L->top++, ofn);
139 	break;
140       case LIBINIT_FFID:
141 	ffid++;
142 	break;
143       case LIBINIT_END:
144 	return;
145       default:
146 	setstrV(L, L->top++, lj_str_new(L, (const char *)p, len));
147 	p += len;
148 	break;
149       }
150     }
151   }
152 }
153 
154 /* Push internal function on the stack. */
lj_lib_pushcc(lua_State * L,lua_CFunction f,int id,int n)155 GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n)
156 {
157   GCfunc *fn;
158   lua_pushcclosure(L, f, n);
159   fn = funcV(L->top-1);
160   fn->c.ffid = (uint8_t)id;
161   setmref(fn->c.pc, &G(L)->bc_cfunc_int);
162   return fn;
163 }
164 
lj_lib_prereg(lua_State * L,const char * name,lua_CFunction f,GCtab * env)165 void lj_lib_prereg(lua_State *L, const char *name, lua_CFunction f, GCtab *env)
166 {
167   luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
168   lua_pushcfunction(L, f);
169   /* NOBARRIER: The function is new (marked white). */
170   setgcref(funcV(L->top-1)->c.env, obj2gco(env));
171   lua_setfield(L, -2, name);
172   L->top--;
173 }
174 
lj_lib_postreg(lua_State * L,lua_CFunction cf,int id,const char * name)175 int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id, const char *name)
176 {
177   GCfunc *fn = lj_lib_pushcf(L, cf, id);
178   GCtab *t = tabref(curr_func(L)->c.env);  /* Reference to parent table. */
179   setfuncV(L, lj_tab_setstr(L, t, lj_str_newz(L, name)), fn);
180   lj_gc_anybarriert(L, t);
181   setfuncV(L, L->top++, fn);
182   return 1;
183 }
184 
185 /* -- Type checks --------------------------------------------------------- */
186 
lj_lib_checkany(lua_State * L,int narg)187 TValue *lj_lib_checkany(lua_State *L, int narg)
188 {
189   TValue *o = L->base + narg-1;
190   if (o >= L->top)
191     lj_err_arg(L, narg, LJ_ERR_NOVAL);
192   return o;
193 }
194 
lj_lib_checkstr(lua_State * L,int narg)195 GCstr *lj_lib_checkstr(lua_State *L, int narg)
196 {
197   TValue *o = L->base + narg-1;
198   if (o < L->top) {
199     if (LJ_LIKELY(tvisstr(o))) {
200       return strV(o);
201     } else if (tvisnumber(o)) {
202       GCstr *s = lj_strfmt_number(L, o);
203       setstrV(L, o, s);
204       return s;
205     }
206   }
207   lj_err_argt(L, narg, LUA_TSTRING);
208   return NULL;  /* unreachable */
209 }
210 
lj_lib_optstr(lua_State * L,int narg)211 GCstr *lj_lib_optstr(lua_State *L, int narg)
212 {
213   TValue *o = L->base + narg-1;
214   return (o < L->top && !tvisnil(o)) ? lj_lib_checkstr(L, narg) : NULL;
215 }
216 
217 #if LJ_DUALNUM
lj_lib_checknumber(lua_State * L,int narg)218 void lj_lib_checknumber(lua_State *L, int narg)
219 {
220   TValue *o = L->base + narg-1;
221   if (!(o < L->top && lj_strscan_numberobj(o)))
222     lj_err_argt(L, narg, LUA_TNUMBER);
223 }
224 #endif
225 
lj_lib_checknum(lua_State * L,int narg)226 lua_Number lj_lib_checknum(lua_State *L, int narg)
227 {
228   TValue *o = L->base + narg-1;
229   if (!(o < L->top &&
230 	(tvisnumber(o) || (tvisstr(o) && lj_strscan_num(strV(o), o)))))
231     lj_err_argt(L, narg, LUA_TNUMBER);
232   if (LJ_UNLIKELY(tvisint(o))) {
233     lua_Number n = (lua_Number)intV(o);
234     setnumV(o, n);
235     return n;
236   } else {
237     return numV(o);
238   }
239 }
240 
lj_lib_checkint(lua_State * L,int narg)241 int32_t lj_lib_checkint(lua_State *L, int narg)
242 {
243   TValue *o = L->base + narg-1;
244   if (!(o < L->top && lj_strscan_numberobj(o)))
245     lj_err_argt(L, narg, LUA_TNUMBER);
246   if (LJ_LIKELY(tvisint(o))) {
247     return intV(o);
248   } else {
249     int32_t i = lj_num2int(numV(o));
250     if (LJ_DUALNUM) setintV(o, i);
251     return i;
252   }
253 }
254 
lj_lib_optint(lua_State * L,int narg,int32_t def)255 int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
256 {
257   TValue *o = L->base + narg-1;
258   return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
259 }
260 
lj_lib_checkfunc(lua_State * L,int narg)261 GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
262 {
263   TValue *o = L->base + narg-1;
264   if (!(o < L->top && tvisfunc(o)))
265     lj_err_argt(L, narg, LUA_TFUNCTION);
266   return funcV(o);
267 }
268 
lj_lib_checktab(lua_State * L,int narg)269 GCtab *lj_lib_checktab(lua_State *L, int narg)
270 {
271   TValue *o = L->base + narg-1;
272   if (!(o < L->top && tvistab(o)))
273     lj_err_argt(L, narg, LUA_TTABLE);
274   return tabV(o);
275 }
276 
lj_lib_checktabornil(lua_State * L,int narg)277 GCtab *lj_lib_checktabornil(lua_State *L, int narg)
278 {
279   TValue *o = L->base + narg-1;
280   if (o < L->top) {
281     if (tvistab(o))
282       return tabV(o);
283     else if (tvisnil(o))
284       return NULL;
285   }
286   lj_err_arg(L, narg, LJ_ERR_NOTABN);
287   return NULL;  /* unreachable */
288 }
289 
lj_lib_checkopt(lua_State * L,int narg,int def,const char * lst)290 int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst)
291 {
292   GCstr *s = def >= 0 ? lj_lib_optstr(L, narg) : lj_lib_checkstr(L, narg);
293   if (s) {
294     const char *opt = strdata(s);
295     MSize len = s->len;
296     int i;
297     for (i = 0; *(const uint8_t *)lst; i++) {
298       if (*(const uint8_t *)lst == len && memcmp(opt, lst+1, len) == 0)
299 	return i;
300       lst += 1+*(const uint8_t *)lst;
301     }
302     lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
303   }
304   return def;
305 }
306 
lj_lib_checkcdata(lua_State * L,int narg)307 GCcdata *lj_lib_checkcdata(lua_State *L, int narg)
308 {
309   TValue *o = L->base + narg-1;
310   if (!(o < L->top && tviscdata(o)))
311     lj_err_argt(L, narg, LUA_TCDATA);
312   return cdataV(o);
313 }
314 
315 /* -- Strict type checks -------------------------------------------------- */
316 
317 /* The following type checks do not coerce between strings and numbers.
318 ** And they handle plain int64_t/uint64_t FFI numbers, too.
319 */
320 
321 #if LJ_HASBUFFER
lj_lib_checkstrx(lua_State * L,int narg)322 GCstr *lj_lib_checkstrx(lua_State *L, int narg)
323 {
324   TValue *o = L->base + narg-1;
325   if (!(o < L->top && tvisstr(o))) lj_err_argt(L, narg, LUA_TSTRING);
326   return strV(o);
327 }
328 
lj_lib_checkintrange(lua_State * L,int narg,int32_t a,int32_t b)329 int32_t lj_lib_checkintrange(lua_State *L, int narg, int32_t a, int32_t b)
330 {
331   TValue *o = L->base + narg-1;
332   lj_assertL(b >= 0, "expected range must be non-negative");
333   if (o < L->top) {
334     if (LJ_LIKELY(tvisint(o))) {
335       int32_t i = intV(o);
336       if (i >= a && i <= b) return i;
337     } else if (LJ_LIKELY(tvisnum(o))) {
338       /* For performance reasons, this doesn't check for integerness or
339       ** integer overflow. Overflow detection still works, since all FPUs
340       ** return either MININT or MAXINT, which is then out of range.
341       */
342       int32_t i = (int32_t)numV(o);
343       if (i >= a && i <= b) return i;
344 #if LJ_HASFFI
345     } else if (tviscdata(o)) {
346       GCcdata *cd = cdataV(o);
347       if (cd->ctypeid == CTID_INT64) {
348 	int64_t i = *(int64_t *)cdataptr(cd);
349 	if (i >= (int64_t)a && i <= (int64_t)b) return (int32_t)i;
350       } else if (cd->ctypeid == CTID_UINT64) {
351 	uint64_t i = *(uint64_t *)cdataptr(cd);
352 	if ((a < 0 || i >= (uint64_t)a) && i <= (uint64_t)b) return (int32_t)i;
353       } else {
354 	goto badtype;
355       }
356 #endif
357     } else {
358       goto badtype;
359     }
360     lj_err_arg(L, narg, LJ_ERR_NUMRNG);
361   }
362 badtype:
363   lj_err_argt(L, narg, LUA_TNUMBER);
364   return 0;  /* unreachable */
365 }
366 #endif
367