2 ** Library function support.
3 ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
18 #include "lj_dispatch.h"
23 #include "lj_strscan.h"
24 #include "lj_strfmt.h"
26 #include "lj_bcdump.h"
29 /* -- Library initialization ---------------------------------------------- */
31 static GCtab
*lib_create_table(lua_State
*L
, const char *libname
, int hsize
)
34 luaL_findtable(L
, LUA_REGISTRYINDEX
, "_LOADED", 16);
35 lua_getfield(L
, -1, libname
);
36 if (!tvistab(L
->top
-1)) {
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));
42 lua_setfield(L
, -3, libname
); /* _LOADED[libname] = new table */
45 settabV(L
, L
->top
-1, tabV(L
->top
));
47 lua_createtable(L
, 0, hsize
);
49 return tabV(L
->top
-1);
52 static const uint8_t *lib_read_lfunc(lua_State
*L
, const uint8_t *p
, GCtab
*tab
)
55 GCstr
*name
= lj_str_new(L
, (const char *)p
, len
);
59 memset(&ls
, 0, sizeof(ls
));
61 ls
.p
= (const char *)(p
+len
);
62 ls
.pe
= (const char *)~(uintptr_t)0;
64 ls
.level
= (BCDUMP_F_STRIP
|(LJ_BE
*BCDUMP_F_BE
));
67 pt
= lj_bcread_proto(&ls
);
68 pt
->firstline
= ~(BCLine
)0;
69 fn
= lj_func_newL_empty(L
, pt
, tabref(L
->env
));
70 /* NOBARRIER: See below for common barrier. */
71 setfuncV(L
, lj_tab_setstr(L
, tab
, name
), fn
);
72 return (const uint8_t *)ls
.p
;
75 void lj_lib_register(lua_State
*L
, const char *libname
,
76 const uint8_t *p
, const lua_CFunction
*cf
)
78 GCtab
*env
= tabref(L
->env
);
81 BCIns
*bcff
= &L2GG(L
)->bcff
[*p
++];
82 GCtab
*tab
= lib_create_table(L
, libname
, *p
++);
83 ptrdiff_t tpos
= L
->top
- L
->base
;
85 /* Avoid barriers further down. */
86 lj_gc_anybarriert(L
, tab
);
91 MSize len
= tag
& LIBINIT_LENMASK
;
92 tag
&= LIBINIT_TAGMASK
;
93 if (tag
!= LIBINIT_STRING
) {
95 MSize nuv
= (MSize
)(L
->top
- L
->base
- tpos
);
96 GCfunc
*fn
= lj_func_newC(L
, nuv
, env
);
98 L
->top
= L
->base
+ tpos
;
99 memcpy(fn
->c
.upvalue
, L
->top
, sizeof(TValue
)*nuv
);
101 fn
->c
.ffid
= (uint8_t)(ffid
++);
102 name
= (const char *)p
;
104 if (tag
== LIBINIT_CF
)
105 setmref(fn
->c
.pc
, &G(L
)->bc_cfunc_int
);
107 setmref(fn
->c
.pc
, bcff
++);
108 if (tag
== LIBINIT_ASM_
)
109 fn
->c
.f
= ofn
->c
.f
; /* Copy handler from previous function. */
111 fn
->c
.f
= *cf
++; /* Get cf or handler from C function table. */
113 /* NOBARRIER: See above for common barrier. */
114 setfuncV(L
, lj_tab_setstr(L
, tab
, lj_str_new(L
, name
, len
)), fn
);
120 p
= lib_read_lfunc(L
, p
, tab
);
124 if (tvisstr(L
->top
+1) && strV(L
->top
+1)->len
== 0)
126 else /* NOBARRIER: See above for common barrier. */
127 copyTV(L
, lj_tab_set(L
, tab
, L
->top
+1), L
->top
);
130 memcpy(&L
->top
->n
, p
, sizeof(double));
135 copyTV(L
, L
->top
, L
->top
- *p
++);
139 setfuncV(L
, L
->top
++, ofn
);
147 setstrV(L
, L
->top
++, lj_str_new(L
, (const char *)p
, len
));
155 /* Push internal function on the stack. */
156 GCfunc
*lj_lib_pushcc(lua_State
*L
, lua_CFunction f
, int id
, int n
)
159 lua_pushcclosure(L
, f
, n
);
160 fn
= funcV(L
->top
-1);
161 fn
->c
.ffid
= (uint8_t)id
;
162 setmref(fn
->c
.pc
, &G(L
)->bc_cfunc_int
);
166 void lj_lib_prereg(lua_State
*L
, const char *name
, lua_CFunction f
, GCtab
*env
)
168 luaL_findtable(L
, LUA_REGISTRYINDEX
, "_PRELOAD", 4);
169 lua_pushcfunction(L
, f
);
170 /* NOBARRIER: The function is new (marked white). */
171 setgcref(funcV(L
->top
-1)->c
.env
, obj2gco(env
));
172 lua_setfield(L
, -2, name
);
176 int lj_lib_postreg(lua_State
*L
, lua_CFunction cf
, int id
, const char *name
)
178 GCfunc
*fn
= lj_lib_pushcf(L
, cf
, id
);
179 GCtab
*t
= tabref(curr_func(L
)->c
.env
); /* Reference to parent table. */
180 setfuncV(L
, lj_tab_setstr(L
, t
, lj_str_newz(L
, name
)), fn
);
181 lj_gc_anybarriert(L
, t
);
182 setfuncV(L
, L
->top
++, fn
);
186 /* -- Type checks --------------------------------------------------------- */
188 TValue
*lj_lib_checkany(lua_State
*L
, int narg
)
190 TValue
*o
= L
->base
+ narg
-1;
192 lj_err_arg(L
, narg
, LJ_ERR_NOVAL
);
196 GCstr
*lj_lib_checkstr(lua_State
*L
, int narg
)
198 TValue
*o
= L
->base
+ narg
-1;
200 if (LJ_LIKELY(tvisstr(o
))) {
202 } else if (tvisnumber(o
)) {
203 GCstr
*s
= lj_strfmt_number(L
, o
);
208 lj_err_argt(L
, narg
, LUA_TSTRING
);
209 return NULL
; /* unreachable */
212 GCstr
*lj_lib_optstr(lua_State
*L
, int narg
)
214 TValue
*o
= L
->base
+ narg
-1;
215 return (o
< L
->top
&& !tvisnil(o
)) ? lj_lib_checkstr(L
, narg
) : NULL
;
219 void lj_lib_checknumber(lua_State
*L
, int narg
)
221 TValue
*o
= L
->base
+ narg
-1;
222 if (!(o
< L
->top
&& lj_strscan_numberobj(o
)))
223 lj_err_argt(L
, narg
, LUA_TNUMBER
);
227 lua_Number
lj_lib_checknum(lua_State
*L
, int narg
)
229 TValue
*o
= L
->base
+ narg
-1;
231 (tvisnumber(o
) || (tvisstr(o
) && lj_strscan_num(strV(o
), o
)))))
232 lj_err_argt(L
, narg
, LUA_TNUMBER
);
233 if (LJ_UNLIKELY(tvisint(o
))) {
234 lua_Number n
= (lua_Number
)intV(o
);
242 int32_t lj_lib_checkint(lua_State
*L
, int narg
)
244 TValue
*o
= L
->base
+ narg
-1;
245 if (!(o
< L
->top
&& lj_strscan_numberobj(o
)))
246 lj_err_argt(L
, narg
, LUA_TNUMBER
);
247 if (LJ_LIKELY(tvisint(o
))) {
250 int32_t i
= lj_num2int(numV(o
));
251 if (LJ_DUALNUM
) setintV(o
, i
);
256 int32_t lj_lib_optint(lua_State
*L
, int narg
, int32_t def
)
258 TValue
*o
= L
->base
+ narg
-1;
259 return (o
< L
->top
&& !tvisnil(o
)) ? lj_lib_checkint(L
, narg
) : def
;
262 GCfunc
*lj_lib_checkfunc(lua_State
*L
, int narg
)
264 TValue
*o
= L
->base
+ narg
-1;
265 if (!(o
< L
->top
&& tvisfunc(o
)))
266 lj_err_argt(L
, narg
, LUA_TFUNCTION
);
270 GCproto
*lj_lib_checkLproto(lua_State
*L
, int narg
, int nolua
)
272 TValue
*o
= L
->base
+ narg
-1;
276 } else if (tvisfunc(o
)) {
277 if (isluafunc(funcV(o
)))
278 return funcproto(funcV(o
));
283 lj_err_argt(L
, narg
, LUA_TFUNCTION
);
284 return NULL
; /* unreachable */
287 GCtab
*lj_lib_checktab(lua_State
*L
, int narg
)
289 TValue
*o
= L
->base
+ narg
-1;
290 if (!(o
< L
->top
&& tvistab(o
)))
291 lj_err_argt(L
, narg
, LUA_TTABLE
);
295 GCtab
*lj_lib_checktabornil(lua_State
*L
, int narg
)
297 TValue
*o
= L
->base
+ narg
-1;
304 lj_err_arg(L
, narg
, LJ_ERR_NOTABN
);
305 return NULL
; /* unreachable */
308 int lj_lib_checkopt(lua_State
*L
, int narg
, int def
, const char *lst
)
310 GCstr
*s
= def
>= 0 ? lj_lib_optstr(L
, narg
) : lj_lib_checkstr(L
, narg
);
312 const char *opt
= strdata(s
);
315 for (i
= 0; *(const uint8_t *)lst
; i
++) {
316 if (*(const uint8_t *)lst
== len
&& memcmp(opt
, lst
+1, len
) == 0)
318 lst
+= 1+*(const uint8_t *)lst
;
320 lj_err_argv(L
, narg
, LJ_ERR_INVOPTM
, opt
);
325 /* -- Strict type checks -------------------------------------------------- */
327 /* The following type checks do not coerce between strings and numbers.
328 ** And they handle plain int64_t/uint64_t FFI numbers, too.
332 GCstr
*lj_lib_checkstrx(lua_State
*L
, int narg
)
334 TValue
*o
= L
->base
+ narg
-1;
335 if (!(o
< L
->top
&& tvisstr(o
))) lj_err_argt(L
, narg
, LUA_TSTRING
);
339 int32_t lj_lib_checkintrange(lua_State
*L
, int narg
, int32_t a
, int32_t b
)
341 TValue
*o
= L
->base
+ narg
-1;
342 lj_assertL(b
>= 0, "expected range must be non-negative");
344 if (LJ_LIKELY(tvisint(o
))) {
346 if (i
>= a
&& i
<= b
) return i
;
347 } else if (LJ_LIKELY(tvisnum(o
))) {
348 /* For performance reasons, this doesn't check for integerness or
349 ** integer overflow. Overflow detection still works, since all FPUs
350 ** return either MININT or MAXINT, which is then out of range.
352 int32_t i
= (int32_t)numV(o
);
353 if (i
>= a
&& i
<= b
) return i
;
355 } else if (tviscdata(o
)) {
356 GCcdata
*cd
= cdataV(o
);
357 if (cd
->ctypeid
== CTID_INT64
) {
358 int64_t i
= *(int64_t *)cdataptr(cd
);
359 if (i
>= (int64_t)a
&& i
<= (int64_t)b
) return (int32_t)i
;
360 } else if (cd
->ctypeid
== CTID_UINT64
) {
361 uint64_t i
= *(uint64_t *)cdataptr(cd
);
362 if ((a
< 0 || i
>= (uint64_t)a
) && i
<= (uint64_t)b
) return (int32_t)i
;
370 lj_err_arg(L
, narg
, LJ_ERR_NUMRNG
);
373 lj_err_argt(L
, narg
, LUA_TNUMBER
);
374 return 0; /* unreachable */