2 ** Library function support.
3 ** Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h
20 /* -- Library initialization ---------------------------------------------- */
22 static GCtab
*lib_create_table(lua_State
*L
, const char *libname
, int hsize
)
25 luaL_findtable(L
, LUA_REGISTRYINDEX
, "_LOADED", 16);
26 lua_getfield(L
, -1, libname
);
27 if (!tvistab(L
->top
-1)) {
29 if (luaL_findtable(L
, LUA_GLOBALSINDEX
, libname
, hsize
) != NULL
)
30 lj_err_callerv(L
, LJ_ERR_BADMODN
, libname
);
31 settabV(L
, L
->top
, tabV(L
->top
-1));
33 lua_setfield(L
, -3, libname
); /* _LOADED[libname] = new table */
36 settabV(L
, L
->top
-1, tabV(L
->top
));
38 lua_createtable(L
, 0, hsize
);
40 return tabV(L
->top
-1);
43 void lj_lib_register(lua_State
*L
, const char *libname
,
44 const uint8_t *p
, const lua_CFunction
*cf
)
46 GCtab
*env
= tabref(L
->env
);
49 GCtab
*tab
= lib_create_table(L
, libname
, *p
++);
50 ptrdiff_t tpos
= L
->top
- L
->base
;
52 /* Avoid barriers further down. */
53 if (isblack(obj2gco(tab
))) lj_gc_barrierback(G(L
), tab
);
58 MSize len
= tag
& LIBINIT_LENMASK
;
59 tag
&= LIBINIT_TAGMASK
;
60 if (tag
!= LIBINIT_STRING
) {
62 MSize nuv
= (MSize
)(L
->top
- L
->base
- tpos
);
63 GCfunc
*fn
= lj_func_newC(L
, nuv
, env
);
65 L
->top
= L
->base
+ tpos
;
66 memcpy(fn
->c
.upvalue
, L
->top
, sizeof(TValue
)*nuv
);
68 fn
->c
.ffid
= (uint8_t)(ffid
++);
69 name
= (const char *)p
;
71 if (tag
!= LIBINIT_CF
) {
72 fn
->c
.gate
= makeasmfunc(p
[0] + (p
[1] << 8));
75 if (tag
== LIBINIT_ASM_
)
76 fn
->c
.f
= ofn
->c
.f
; /* Copy handler from previous function. */
78 fn
->c
.f
= *cf
++; /* Get cf or handler from C function table. */
80 /* NOBARRIER: See above for common barrier. */
81 setfuncV(L
, lj_tab_setstr(L
, tab
, lj_str_new(L
, name
, len
)), fn
);
88 if (tvisstr(L
->top
+1) && strV(L
->top
+1)->len
== 0)
90 else /* NOBARRIER: See above for common barrier. */
91 copyTV(L
, lj_tab_set(L
, tab
, L
->top
+1), L
->top
);
94 memcpy(&L
->top
->n
, p
, sizeof(double));
99 copyTV(L
, L
->top
, L
->top
- *p
++);
103 setfuncV(L
, L
->top
++, ofn
);
111 setstrV(L
, L
->top
++, lj_str_new(L
, (const char *)p
, len
));
119 /* -- Type checks --------------------------------------------------------- */
121 TValue
*lj_lib_checkany(lua_State
*L
, int narg
)
123 TValue
*o
= L
->base
+ narg
-1;
125 lj_err_arg(L
, narg
, LJ_ERR_NOVAL
);
129 GCstr
*lj_lib_checkstr(lua_State
*L
, int narg
)
131 TValue
*o
= L
->base
+ narg
-1;
133 if (LJ_LIKELY(tvisstr(o
))) {
135 } else if (tvisnum(o
)) {
136 GCstr
*s
= lj_str_fromnum(L
, &o
->n
);
141 lj_err_argt(L
, narg
, LUA_TSTRING
);
142 return NULL
; /* unreachable */
145 GCstr
*lj_lib_optstr(lua_State
*L
, int narg
)
147 TValue
*o
= L
->base
+ narg
-1;
148 return (o
< L
->top
&& !tvisnil(o
)) ? lj_lib_checkstr(L
, narg
) : NULL
;
151 lua_Number
lj_lib_checknum(lua_State
*L
, int narg
)
153 TValue
*o
= L
->base
+ narg
-1;
155 (tvisnum(o
) || (tvisstr(o
) && lj_str_tonum(strV(o
), o
)))))
156 lj_err_argt(L
, narg
, LUA_TNUMBER
);
160 int32_t lj_lib_checkint(lua_State
*L
, int narg
)
162 return lj_num2int(lj_lib_checknum(L
, narg
));
165 int32_t lj_lib_optint(lua_State
*L
, int narg
, int32_t def
)
167 TValue
*o
= L
->base
+ narg
-1;
168 return (o
< L
->top
&& !tvisnil(o
)) ? lj_lib_checkint(L
, narg
) : def
;
171 GCfunc
*lj_lib_checkfunc(lua_State
*L
, int narg
)
173 TValue
*o
= L
->base
+ narg
-1;
174 if (!(o
< L
->top
&& tvisfunc(o
)))
175 lj_err_argt(L
, narg
, LUA_TFUNCTION
);
179 GCtab
*lj_lib_checktab(lua_State
*L
, int narg
)
181 TValue
*o
= L
->base
+ narg
-1;
182 if (!(o
< L
->top
&& tvistab(o
)))
183 lj_err_argt(L
, narg
, LUA_TTABLE
);
187 GCtab
*lj_lib_checktabornil(lua_State
*L
, int narg
)
189 TValue
*o
= L
->base
+ narg
-1;
196 lj_err_arg(L
, narg
, LJ_ERR_NOTABN
);
197 return NULL
; /* unreachable */
200 int lj_lib_checkopt(lua_State
*L
, int narg
, int def
, const char *lst
)
202 GCstr
*s
= def
>= 0 ? lj_lib_optstr(L
, narg
) : lj_lib_checkstr(L
, narg
);
204 const char *opt
= strdata(s
);
207 for (i
= 0; *(const uint8_t *)lst
; i
++) {
208 if (*(const uint8_t *)lst
== len
&& memcmp(opt
, lst
+1, len
) == 0)
210 lst
+= 1+*(const uint8_t *)lst
;
212 lj_err_argv(L
, narg
, LJ_ERR_INVOPTM
, opt
);