2 ** Library function support.
3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
18 #include "lj_dispatch.h"
20 #include "lj_strscan.h"
23 /* -- Library initialization ---------------------------------------------- */
25 static GCtab
*lib_create_table(lua_State
*L
, const char *libname
, int hsize
)
28 luaL_findtable(L
, LUA_REGISTRYINDEX
, "_LOADED", 16);
29 lua_getfield(L
, -1, libname
);
30 if (!tvistab(L
->top
-1)) {
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));
36 lua_setfield(L
, -3, libname
); /* _LOADED[libname] = new table */
39 settabV(L
, L
->top
-1, tabV(L
->top
));
41 lua_createtable(L
, 0, hsize
);
43 return tabV(L
->top
-1);
46 void lj_lib_register(lua_State
*L
, const char *libname
,
47 const uint8_t *p
, const lua_CFunction
*cf
)
49 GCtab
*env
= tabref(L
->env
);
52 BCIns
*bcff
= &L2GG(L
)->bcff
[*p
++];
53 GCtab
*tab
= lib_create_table(L
, libname
, *p
++);
54 ptrdiff_t tpos
= L
->top
- L
->base
;
56 /* Avoid barriers further down. */
57 lj_gc_anybarriert(L
, tab
);
62 MSize len
= tag
& LIBINIT_LENMASK
;
63 tag
&= LIBINIT_TAGMASK
;
64 if (tag
!= LIBINIT_STRING
) {
66 MSize nuv
= (MSize
)(L
->top
- L
->base
- tpos
);
67 GCfunc
*fn
= lj_func_newC(L
, nuv
, env
);
69 L
->top
= L
->base
+ tpos
;
70 memcpy(fn
->c
.upvalue
, L
->top
, sizeof(TValue
)*nuv
);
72 fn
->c
.ffid
= (uint8_t)(ffid
++);
73 name
= (const char *)p
;
75 if (tag
== LIBINIT_CF
)
76 setmref(fn
->c
.pc
, &G(L
)->bc_cfunc_int
);
78 setmref(fn
->c
.pc
, bcff
++);
79 if (tag
== LIBINIT_ASM_
)
80 fn
->c
.f
= ofn
->c
.f
; /* Copy handler from previous function. */
82 fn
->c
.f
= *cf
++; /* Get cf or handler from C function table. */
84 /* NOBARRIER: See above for common barrier. */
85 setfuncV(L
, lj_tab_setstr(L
, tab
, lj_str_new(L
, name
, len
)), fn
);
92 if (tvisstr(L
->top
+1) && strV(L
->top
+1)->len
== 0)
94 else /* NOBARRIER: See above for common barrier. */
95 copyTV(L
, lj_tab_set(L
, tab
, L
->top
+1), L
->top
);
98 memcpy(&L
->top
->n
, p
, sizeof(double));
103 copyTV(L
, L
->top
, L
->top
- *p
++);
107 setfuncV(L
, L
->top
++, ofn
);
115 setstrV(L
, L
->top
++, lj_str_new(L
, (const char *)p
, len
));
123 /* -- Type checks --------------------------------------------------------- */
125 TValue
*lj_lib_checkany(lua_State
*L
, int narg
)
127 TValue
*o
= L
->base
+ narg
-1;
129 lj_err_arg(L
, narg
, LJ_ERR_NOVAL
);
133 GCstr
*lj_lib_checkstr(lua_State
*L
, int narg
)
135 TValue
*o
= L
->base
+ narg
-1;
137 if (LJ_LIKELY(tvisstr(o
))) {
139 } else if (tvisnumber(o
)) {
140 GCstr
*s
= lj_str_fromnumber(L
, o
);
145 lj_err_argt(L
, narg
, LUA_TSTRING
);
146 return NULL
; /* unreachable */
149 GCstr
*lj_lib_optstr(lua_State
*L
, int narg
)
151 TValue
*o
= L
->base
+ narg
-1;
152 return (o
< L
->top
&& !tvisnil(o
)) ? lj_lib_checkstr(L
, narg
) : NULL
;
156 void lj_lib_checknumber(lua_State
*L
, int narg
)
158 TValue
*o
= L
->base
+ narg
-1;
159 if (!(o
< L
->top
&& lj_strscan_numberobj(o
)))
160 lj_err_argt(L
, narg
, LUA_TNUMBER
);
164 lua_Number
lj_lib_checknum(lua_State
*L
, int narg
)
166 TValue
*o
= L
->base
+ narg
-1;
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
);
179 int32_t lj_lib_checkint(lua_State
*L
, int narg
)
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
))) {
187 int32_t i
= lj_num2int(numV(o
));
188 if (LJ_DUALNUM
) setintV(o
, i
);
193 int32_t lj_lib_optint(lua_State
*L
, int narg
, int32_t def
)
195 TValue
*o
= L
->base
+ narg
-1;
196 return (o
< L
->top
&& !tvisnil(o
)) ? lj_lib_checkint(L
, narg
) : def
;
199 int32_t lj_lib_checkbit(lua_State
*L
, int narg
)
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
))) {
207 int32_t i
= lj_num2bit(numV(o
));
208 if (LJ_DUALNUM
) setintV(o
, i
);
213 GCfunc
*lj_lib_checkfunc(lua_State
*L
, int narg
)
215 TValue
*o
= L
->base
+ narg
-1;
216 if (!(o
< L
->top
&& tvisfunc(o
)))
217 lj_err_argt(L
, narg
, LUA_TFUNCTION
);
221 GCtab
*lj_lib_checktab(lua_State
*L
, int narg
)
223 TValue
*o
= L
->base
+ narg
-1;
224 if (!(o
< L
->top
&& tvistab(o
)))
225 lj_err_argt(L
, narg
, LUA_TTABLE
);
229 GCtab
*lj_lib_checktabornil(lua_State
*L
, int narg
)
231 TValue
*o
= L
->base
+ narg
-1;
238 lj_err_arg(L
, narg
, LJ_ERR_NOTABN
);
239 return NULL
; /* unreachable */
242 int lj_lib_checkopt(lua_State
*L
, int narg
, int def
, const char *lst
)
244 GCstr
*s
= def
>= 0 ? lj_lib_optstr(L
, narg
) : lj_lib_checkstr(L
, narg
);
246 const char *opt
= strdata(s
);
249 for (i
= 0; *(const uint8_t *)lst
; i
++) {
250 if (*(const uint8_t *)lst
== len
&& memcmp(opt
, lst
+1, len
) == 0)
252 lst
+= 1+*(const uint8_t *)lst
;
254 lj_err_argv(L
, narg
, LJ_ERR_INVOPTM
, opt
);