2 ** Library function support.
3 ** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
18 #include "lj_dispatch.h"
22 /* -- Library initialization ---------------------------------------------- */
24 static GCtab
*lib_create_table(lua_State
*L
, const char *libname
, int hsize
)
27 luaL_findtable(L
, LUA_REGISTRYINDEX
, "_LOADED", 16);
28 lua_getfield(L
, -1, libname
);
29 if (!tvistab(L
->top
-1)) {
31 if (luaL_findtable(L
, LUA_GLOBALSINDEX
, libname
, hsize
) != NULL
)
32 lj_err_callerv(L
, LJ_ERR_BADMODN
, libname
);
33 settabV(L
, L
->top
, tabV(L
->top
-1));
35 lua_setfield(L
, -3, libname
); /* _LOADED[libname] = new table */
38 settabV(L
, L
->top
-1, tabV(L
->top
));
40 lua_createtable(L
, 0, hsize
);
42 return tabV(L
->top
-1);
45 void lj_lib_register(lua_State
*L
, const char *libname
,
46 const uint8_t *p
, const lua_CFunction
*cf
)
48 GCtab
*env
= tabref(L
->env
);
51 BCIns
*bcff
= &L2GG(L
)->bcff
[*p
++];
52 GCtab
*tab
= lib_create_table(L
, libname
, *p
++);
53 ptrdiff_t tpos
= L
->top
- L
->base
;
55 /* Avoid barriers further down. */
56 lj_gc_anybarriert(L
, tab
);
61 MSize len
= tag
& LIBINIT_LENMASK
;
62 tag
&= LIBINIT_TAGMASK
;
63 if (tag
!= LIBINIT_STRING
) {
65 MSize nuv
= (MSize
)(L
->top
- L
->base
- tpos
);
66 GCfunc
*fn
= lj_func_newC(L
, nuv
, env
);
68 L
->top
= L
->base
+ tpos
;
69 memcpy(fn
->c
.upvalue
, L
->top
, sizeof(TValue
)*nuv
);
71 fn
->c
.ffid
= (uint8_t)(ffid
++);
72 name
= (const char *)p
;
74 if (tag
== LIBINIT_CF
)
75 setmref(fn
->c
.pc
, &G(L
)->bc_cfunc_int
);
77 setmref(fn
->c
.pc
, bcff
++);
78 if (tag
== LIBINIT_ASM_
)
79 fn
->c
.f
= ofn
->c
.f
; /* Copy handler from previous function. */
81 fn
->c
.f
= *cf
++; /* Get cf or handler from C function table. */
83 /* NOBARRIER: See above for common barrier. */
84 setfuncV(L
, lj_tab_setstr(L
, tab
, lj_str_new(L
, name
, len
)), fn
);
91 if (tvisstr(L
->top
+1) && strV(L
->top
+1)->len
== 0)
93 else /* NOBARRIER: See above for common barrier. */
94 copyTV(L
, lj_tab_set(L
, tab
, L
->top
+1), L
->top
);
97 memcpy(&L
->top
->n
, p
, sizeof(double));
102 copyTV(L
, L
->top
, L
->top
- *p
++);
106 setfuncV(L
, L
->top
++, ofn
);
114 setstrV(L
, L
->top
++, lj_str_new(L
, (const char *)p
, len
));
122 /* -- Type checks --------------------------------------------------------- */
124 TValue
*lj_lib_checkany(lua_State
*L
, int narg
)
126 TValue
*o
= L
->base
+ narg
-1;
128 lj_err_arg(L
, narg
, LJ_ERR_NOVAL
);
132 GCstr
*lj_lib_checkstr(lua_State
*L
, int narg
)
134 TValue
*o
= L
->base
+ narg
-1;
136 if (LJ_LIKELY(tvisstr(o
))) {
138 } else if (tvisnumber(o
)) {
139 GCstr
*s
= lj_str_fromnumber(L
, o
);
144 lj_err_argt(L
, narg
, LUA_TSTRING
);
145 return NULL
; /* unreachable */
148 GCstr
*lj_lib_optstr(lua_State
*L
, int narg
)
150 TValue
*o
= L
->base
+ narg
-1;
151 return (o
< L
->top
&& !tvisnil(o
)) ? lj_lib_checkstr(L
, narg
) : NULL
;
155 void lj_lib_checknumber(lua_State
*L
, int narg
)
157 TValue
*o
= L
->base
+ narg
-1;
159 (tvisnumber(o
) || (tvisstr(o
) && lj_str_tonumber(strV(o
), 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_str_tonumber(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;
183 (tvisnumber(o
) || (tvisstr(o
) && lj_str_tonumber(strV(o
), o
)))))
184 lj_err_argt(L
, narg
, LUA_TNUMBER
);
185 if (LJ_LIKELY(tvisint(o
))) {
188 int32_t i
= lj_num2int(numV(o
));
189 if (LJ_DUALNUM
) setintV(o
, i
);
194 int32_t lj_lib_optint(lua_State
*L
, int narg
, int32_t def
)
196 TValue
*o
= L
->base
+ narg
-1;
197 return (o
< L
->top
&& !tvisnil(o
)) ? lj_lib_checkint(L
, narg
) : def
;
200 int32_t lj_lib_checkbit(lua_State
*L
, int narg
)
202 TValue
*o
= L
->base
+ narg
-1;
204 (tvisnumber(o
) || (tvisstr(o
) && lj_str_tonumber(strV(o
), o
)))))
205 lj_err_argt(L
, narg
, LUA_TNUMBER
);
206 if (LJ_LIKELY(tvisint(o
))) {
209 int32_t i
= lj_num2bit(numV(o
));
210 if (LJ_DUALNUM
) setintV(o
, i
);
215 GCfunc
*lj_lib_checkfunc(lua_State
*L
, int narg
)
217 TValue
*o
= L
->base
+ narg
-1;
218 if (!(o
< L
->top
&& tvisfunc(o
)))
219 lj_err_argt(L
, narg
, LUA_TFUNCTION
);
223 GCtab
*lj_lib_checktab(lua_State
*L
, int narg
)
225 TValue
*o
= L
->base
+ narg
-1;
226 if (!(o
< L
->top
&& tvistab(o
)))
227 lj_err_argt(L
, narg
, LUA_TTABLE
);
231 GCtab
*lj_lib_checktabornil(lua_State
*L
, int narg
)
233 TValue
*o
= L
->base
+ narg
-1;
240 lj_err_arg(L
, narg
, LJ_ERR_NOTABN
);
241 return NULL
; /* unreachable */
244 int lj_lib_checkopt(lua_State
*L
, int narg
, int def
, const char *lst
)
246 GCstr
*s
= def
>= 0 ? lj_lib_optstr(L
, narg
) : lj_lib_checkstr(L
, narg
);
248 const char *opt
= strdata(s
);
251 for (i
= 0; *(const uint8_t *)lst
; i
++) {
252 if (*(const uint8_t *)lst
== len
&& memcmp(opt
, lst
+1, len
) == 0)
254 lst
+= 1+*(const uint8_t *)lst
;
256 lj_err_argv(L
, narg
, LJ_ERR_INVOPTM
, opt
);