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#include "lj_vm.h"
20#include "lj_strscan.h"
21#include "lj_strfmt.h"
22#include "lj_lex.h"
23#include "lj_bcdump.h"
24#include "lj_lib.h"
25
26/* -- Library initialization ---------------------------------------------- */
27
28static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize)
29{
30 if (libname) {
31 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
32 lua_getfield(L, -1, libname);
33 if (!tvistab(L->top-1)) {
34 L->top--;
35 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, hsize) != NULL)
36 lj_err_callerv(L, LJ_ERR_BADMODN, libname);
37 settabV(L, L->top, tabV(L->top-1));
38 L->top++;
39 lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
40 }
41 L->top--;
42 settabV(L, L->top-1, tabV(L->top));
43 } else {
44 lua_createtable(L, 0, hsize);
45 }
46 return tabV(L->top-1);
47}
48
49static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab)
50{
51 int len = *p++;
52 GCstr *name = lj_str_new(L, (const char *)p, len);
53 LexState ls;
54 GCproto *pt;
55 GCfunc *fn;
56 memset(&ls, 0, sizeof(ls));
57 ls.L = L;
58 ls.p = (const char *)(p+len);
59 ls.pe = (const char *)~(uintptr_t)0;
60 ls.c = -1;
61 ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE));
62 ls.chunkname = name;
63 pt = lj_bcread_proto(&ls);
64 pt->firstline = ~(BCLine)0;
65 fn = lj_func_newL_empty(L, pt, tabref(L->env));
66 /* NOBARRIER: See below for common barrier. */
67 setfuncV(L, lj_tab_setstr(L, tab, name), fn);
68 return (const uint8_t *)ls.p;
69}
70
71void lj_lib_register(lua_State *L, const char *libname,
72 const uint8_t *p, const lua_CFunction *cf)
73{
74 GCtab *env = tabref(L->env);
75 GCfunc *ofn = NULL;
76 int ffid = *p++;
77 BCIns *bcff = &L2GG(L)->bcff[*p++];
78 GCtab *tab = lib_create_table(L, libname, *p++);
79 ptrdiff_t tpos = L->top - L->base;
80
81 /* Avoid barriers further down. */
82 lj_gc_anybarriert(L, tab);
83 tab->nomm = 0;
84
85 for (;;) {
86 uint32_t tag = *p++;
87 MSize len = tag & LIBINIT_LENMASK;
88 tag &= LIBINIT_TAGMASK;
89 if (tag != LIBINIT_STRING) {
90 const char *name;
91 MSize nuv = (MSize)(L->top - L->base - tpos);
92 GCfunc *fn = lj_func_newC(L, nuv, env);
93 if (nuv) {
94 L->top = L->base + tpos;
95 memcpy(fn->c.upvalue, L->top, sizeof(TValue)*nuv);
96 }
97 fn->c.ffid = (uint8_t)(ffid++);
98 name = (const char *)p;
99 p += len;
100 if (tag == LIBINIT_CF)
101 setmref(fn->c.pc, &G(L)->bc_cfunc_int);
102 else
103 setmref(fn->c.pc, bcff++);
104 if (tag == LIBINIT_ASM_)
105 fn->c.f = ofn->c.f; /* Copy handler from previous function. */
106 else
107 fn->c.f = *cf++; /* Get cf or handler from C function table. */
108 if (len) {
109 /* NOBARRIER: See above for common barrier. */
110 setfuncV(L, lj_tab_setstr(L, tab, lj_str_new(L, name, len)), fn);
111 }
112 ofn = fn;
113 } else {
114 switch (tag | len) {
115 case LIBINIT_LUA:
116 p = lib_read_lfunc(L, p, tab);
117 break;
118 case LIBINIT_SET:
119 L->top -= 2;
120 if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
121 env = tabV(L->top);
122 else /* NOBARRIER: See above for common barrier. */
123 copyTV(L, lj_tab_set(L, tab, L->top+1), L->top);
124 break;
125 case LIBINIT_NUMBER:
126 memcpy(&L->top->n, p, sizeof(double));
127 L->top++;
128 p += sizeof(double);
129 break;
130 case LIBINIT_COPY:
131 copyTV(L, L->top, L->top - *p++);
132 L->top++;
133 break;
134 case LIBINIT_LASTCL:
135 setfuncV(L, L->top++, ofn);
136 break;
137 case LIBINIT_FFID:
138 ffid++;
139 break;
140 case LIBINIT_END:
141 return;
142 default:
143 setstrV(L, L->top++, lj_str_new(L, (const char *)p, len));
144 p += len;
145 break;
146 }
147 }
148 }
149}
150
151/* Push internal function on the stack. */
152GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n)
153{
154 GCfunc *fn;
155 lua_pushcclosure(L, f, n);
156 fn = funcV(L->top-1);
157 fn->c.ffid = (uint8_t)id;
158 setmref(fn->c.pc, &G(L)->bc_cfunc_int);
159 return fn;
160}
161
162void lj_lib_prereg(lua_State *L, const char *name, lua_CFunction f, GCtab *env)
163{
164 luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
165 lua_pushcfunction(L, f);
166 /* NOBARRIER: The function is new (marked white). */
167 setgcref(funcV(L->top-1)->c.env, obj2gco(env));
168 lua_setfield(L, -2, name);
169 L->top--;
170}
171
172int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id, const char *name)
173{
174 GCfunc *fn = lj_lib_pushcf(L, cf, id);
175 GCtab *t = tabref(curr_func(L)->c.env); /* Reference to parent table. */
176 setfuncV(L, lj_tab_setstr(L, t, lj_str_newz(L, name)), fn);
177 lj_gc_anybarriert(L, t);
178 setfuncV(L, L->top++, fn);
179 return 1;
180}
181
182/* -- Type checks --------------------------------------------------------- */
183
184TValue *lj_lib_checkany(lua_State *L, int narg)
185{
186 TValue *o = L->base + narg-1;
187 if (o >= L->top)
188 lj_err_arg(L, narg, LJ_ERR_NOVAL);
189 return o;
190}
191
192GCstr *lj_lib_checkstr(lua_State *L, int narg)
193{
194 TValue *o = L->base + narg-1;
195 if (o < L->top) {
196 if (LJ_LIKELY(tvisstr(o))) {
197 return strV(o);
198 } else if (tvisnumber(o)) {
199 GCstr *s = lj_strfmt_number(L, o);
200 setstrV(L, o, s);
201 return s;
202 }
203 }
204 lj_err_argt(L, narg, LUA_TSTRING);
205 return NULL; /* unreachable */
206}
207
208GCstr *lj_lib_optstr(lua_State *L, int narg)
209{
210 TValue *o = L->base + narg-1;
211 return (o < L->top && !tvisnil(o)) ? lj_lib_checkstr(L, narg) : NULL;
212}
213
214#if LJ_DUALNUM
215void lj_lib_checknumber(lua_State *L, int narg)
216{
217 TValue *o = L->base + narg-1;
218 if (!(o < L->top && lj_strscan_numberobj(o)))
219 lj_err_argt(L, narg, LUA_TNUMBER);
220}
221#endif
222
223lua_Number lj_lib_checknum(lua_State *L, int narg)
224{
225 TValue *o = L->base + narg-1;
226 if (!(o < L->top &&
227 (tvisnumber(o) || (tvisstr(o) && lj_strscan_num(strV(o), o)))))
228 lj_err_argt(L, narg, LUA_TNUMBER);
229 if (LJ_UNLIKELY(tvisint(o))) {
230 lua_Number n = (lua_Number)intV(o);
231 setnumV(o, n);
232 return n;
233 } else {
234 return numV(o);
235 }
236}
237
238int32_t lj_lib_checkint(lua_State *L, int narg)
239{
240 TValue *o = L->base + narg-1;
241 if (!(o < L->top && lj_strscan_numberobj(o)))
242 lj_err_argt(L, narg, LUA_TNUMBER);
243 if (LJ_LIKELY(tvisint(o))) {
244 return intV(o);
245 } else {
246 int32_t i = lj_num2int(numV(o));
247 if (LJ_DUALNUM) setintV(o, i);
248 return i;
249 }
250}
251
252int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
253{
254 TValue *o = L->base + narg-1;
255 return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
256}
257
258GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
259{
260 TValue *o = L->base + narg-1;
261 if (!(o < L->top && tvisfunc(o)))
262 lj_err_argt(L, narg, LUA_TFUNCTION);
263 return funcV(o);
264}
265
266GCtab *lj_lib_checktab(lua_State *L, int narg)
267{
268 TValue *o = L->base + narg-1;
269 if (!(o < L->top && tvistab(o)))
270 lj_err_argt(L, narg, LUA_TTABLE);
271 return tabV(o);
272}
273
274GCtab *lj_lib_checktabornil(lua_State *L, int narg)
275{
276 TValue *o = L->base + narg-1;
277 if (o < L->top) {
278 if (tvistab(o))
279 return tabV(o);
280 else if (tvisnil(o))
281 return NULL;
282 }
283 lj_err_arg(L, narg, LJ_ERR_NOTABN);
284 return NULL; /* unreachable */
285}
286
287int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst)
288{
289 GCstr *s = def >= 0 ? lj_lib_optstr(L, narg) : lj_lib_checkstr(L, narg);
290 if (s) {
291 const char *opt = strdata(s);
292 MSize len = s->len;
293 int i;
294 for (i = 0; *(const uint8_t *)lst; i++) {
295 if (*(const uint8_t *)lst == len && memcmp(opt, lst+1, len) == 0)
296 return i;
297 lst += 1+*(const uint8_t *)lst;
298 }
299 lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
300 }
301 return def;
302}
303
304