diff options
Diffstat (limited to 'src/lj_lib.c')
-rw-r--r-- | src/lj_lib.c | 131 |
1 files changed, 116 insertions, 15 deletions
diff --git a/src/lj_lib.c b/src/lj_lib.c index 5796766a..82a9e256 100644 --- a/src/lj_lib.c +++ b/src/lj_lib.c | |||
@@ -16,8 +16,14 @@ | |||
16 | #include "lj_func.h" | 16 | #include "lj_func.h" |
17 | #include "lj_bc.h" | 17 | #include "lj_bc.h" |
18 | #include "lj_dispatch.h" | 18 | #include "lj_dispatch.h" |
19 | #if LJ_HASFFI | ||
20 | #include "lj_ctype.h" | ||
21 | #endif | ||
19 | #include "lj_vm.h" | 22 | #include "lj_vm.h" |
20 | #include "lj_strscan.h" | 23 | #include "lj_strscan.h" |
24 | #include "lj_strfmt.h" | ||
25 | #include "lj_lex.h" | ||
26 | #include "lj_bcdump.h" | ||
21 | #include "lj_lib.h" | 27 | #include "lj_lib.h" |
22 | 28 | ||
23 | /* -- Library initialization ---------------------------------------------- */ | 29 | /* -- Library initialization ---------------------------------------------- */ |
@@ -43,6 +49,28 @@ static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize) | |||
43 | return tabV(L->top-1); | 49 | return tabV(L->top-1); |
44 | } | 50 | } |
45 | 51 | ||
52 | static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab) | ||
53 | { | ||
54 | int len = *p++; | ||
55 | GCstr *name = lj_str_new(L, (const char *)p, len); | ||
56 | LexState ls; | ||
57 | GCproto *pt; | ||
58 | GCfunc *fn; | ||
59 | memset(&ls, 0, sizeof(ls)); | ||
60 | ls.L = L; | ||
61 | ls.p = (const char *)(p+len); | ||
62 | ls.pe = (const char *)~(uintptr_t)0; | ||
63 | ls.c = -1; | ||
64 | ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE)); | ||
65 | ls.chunkname = name; | ||
66 | pt = lj_bcread_proto(&ls); | ||
67 | pt->firstline = ~(BCLine)0; | ||
68 | fn = lj_func_newL_empty(L, pt, tabref(L->env)); | ||
69 | /* NOBARRIER: See below for common barrier. */ | ||
70 | setfuncV(L, lj_tab_setstr(L, tab, name), fn); | ||
71 | return (const uint8_t *)ls.p; | ||
72 | } | ||
73 | |||
46 | void lj_lib_register(lua_State *L, const char *libname, | 74 | void lj_lib_register(lua_State *L, const char *libname, |
47 | const uint8_t *p, const lua_CFunction *cf) | 75 | const uint8_t *p, const lua_CFunction *cf) |
48 | { | 76 | { |
@@ -87,6 +115,9 @@ void lj_lib_register(lua_State *L, const char *libname, | |||
87 | ofn = fn; | 115 | ofn = fn; |
88 | } else { | 116 | } else { |
89 | switch (tag | len) { | 117 | switch (tag | len) { |
118 | case LIBINIT_LUA: | ||
119 | p = lib_read_lfunc(L, p, tab); | ||
120 | break; | ||
90 | case LIBINIT_SET: | 121 | case LIBINIT_SET: |
91 | L->top -= 2; | 122 | L->top -= 2; |
92 | if (tvisstr(L->top+1) && strV(L->top+1)->len == 0) | 123 | if (tvisstr(L->top+1) && strV(L->top+1)->len == 0) |
@@ -120,6 +151,37 @@ void lj_lib_register(lua_State *L, const char *libname, | |||
120 | } | 151 | } |
121 | } | 152 | } |
122 | 153 | ||
154 | /* Push internal function on the stack. */ | ||
155 | GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n) | ||
156 | { | ||
157 | GCfunc *fn; | ||
158 | lua_pushcclosure(L, f, n); | ||
159 | fn = funcV(L->top-1); | ||
160 | fn->c.ffid = (uint8_t)id; | ||
161 | setmref(fn->c.pc, &G(L)->bc_cfunc_int); | ||
162 | return fn; | ||
163 | } | ||
164 | |||
165 | void lj_lib_prereg(lua_State *L, const char *name, lua_CFunction f, GCtab *env) | ||
166 | { | ||
167 | luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4); | ||
168 | lua_pushcfunction(L, f); | ||
169 | /* NOBARRIER: The function is new (marked white). */ | ||
170 | setgcref(funcV(L->top-1)->c.env, obj2gco(env)); | ||
171 | lua_setfield(L, -2, name); | ||
172 | L->top--; | ||
173 | } | ||
174 | |||
175 | int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id, const char *name) | ||
176 | { | ||
177 | GCfunc *fn = lj_lib_pushcf(L, cf, id); | ||
178 | GCtab *t = tabref(curr_func(L)->c.env); /* Reference to parent table. */ | ||
179 | setfuncV(L, lj_tab_setstr(L, t, lj_str_newz(L, name)), fn); | ||
180 | lj_gc_anybarriert(L, t); | ||
181 | setfuncV(L, L->top++, fn); | ||
182 | return 1; | ||
183 | } | ||
184 | |||
123 | /* -- Type checks --------------------------------------------------------- */ | 185 | /* -- Type checks --------------------------------------------------------- */ |
124 | 186 | ||
125 | TValue *lj_lib_checkany(lua_State *L, int narg) | 187 | TValue *lj_lib_checkany(lua_State *L, int narg) |
@@ -137,7 +199,7 @@ GCstr *lj_lib_checkstr(lua_State *L, int narg) | |||
137 | if (LJ_LIKELY(tvisstr(o))) { | 199 | if (LJ_LIKELY(tvisstr(o))) { |
138 | return strV(o); | 200 | return strV(o); |
139 | } else if (tvisnumber(o)) { | 201 | } else if (tvisnumber(o)) { |
140 | GCstr *s = lj_str_fromnumber(L, o); | 202 | GCstr *s = lj_strfmt_number(L, o); |
141 | setstrV(L, o, s); | 203 | setstrV(L, o, s); |
142 | return s; | 204 | return s; |
143 | } | 205 | } |
@@ -196,20 +258,6 @@ int32_t lj_lib_optint(lua_State *L, int narg, int32_t def) | |||
196 | return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def; | 258 | return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def; |
197 | } | 259 | } |
198 | 260 | ||
199 | int32_t lj_lib_checkbit(lua_State *L, int narg) | ||
200 | { | ||
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))) { | ||
205 | return intV(o); | ||
206 | } else { | ||
207 | int32_t i = lj_num2bit(numV(o)); | ||
208 | if (LJ_DUALNUM) setintV(o, i); | ||
209 | return i; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | GCfunc *lj_lib_checkfunc(lua_State *L, int narg) | 261 | GCfunc *lj_lib_checkfunc(lua_State *L, int narg) |
214 | { | 262 | { |
215 | TValue *o = L->base + narg-1; | 263 | TValue *o = L->base + narg-1; |
@@ -256,3 +304,56 @@ int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst) | |||
256 | return def; | 304 | return def; |
257 | } | 305 | } |
258 | 306 | ||
307 | /* -- Strict type checks -------------------------------------------------- */ | ||
308 | |||
309 | /* The following type checks do not coerce between strings and numbers. | ||
310 | ** And they handle plain int64_t/uint64_t FFI numbers, too. | ||
311 | */ | ||
312 | |||
313 | #if LJ_HASBUFFER | ||
314 | GCstr *lj_lib_checkstrx(lua_State *L, int narg) | ||
315 | { | ||
316 | TValue *o = L->base + narg-1; | ||
317 | if (!(o < L->top && tvisstr(o))) lj_err_argt(L, narg, LUA_TSTRING); | ||
318 | return strV(o); | ||
319 | } | ||
320 | |||
321 | int32_t lj_lib_checkintrange(lua_State *L, int narg, int32_t a, int32_t b) | ||
322 | { | ||
323 | TValue *o = L->base + narg-1; | ||
324 | lj_assertL(b >= 0, "expected range must be non-negative"); | ||
325 | if (o < L->top) { | ||
326 | if (LJ_LIKELY(tvisint(o))) { | ||
327 | int32_t i = intV(o); | ||
328 | if (i >= a && i <= b) return i; | ||
329 | } else if (LJ_LIKELY(tvisnum(o))) { | ||
330 | /* For performance reasons, this doesn't check for integerness or | ||
331 | ** integer overflow. Overflow detection still works, since all FPUs | ||
332 | ** return either MININT or MAXINT, which is then out of range. | ||
333 | */ | ||
334 | int32_t i = (int32_t)numV(o); | ||
335 | if (i >= a && i <= b) return i; | ||
336 | #if LJ_HASFFI | ||
337 | } else if (tviscdata(o)) { | ||
338 | GCcdata *cd = cdataV(o); | ||
339 | if (cd->ctypeid == CTID_INT64) { | ||
340 | int64_t i = *(int64_t *)cdataptr(cd); | ||
341 | if (i >= (int64_t)a && i <= (int64_t)b) return (int32_t)i; | ||
342 | } else if (cd->ctypeid == CTID_UINT64) { | ||
343 | uint64_t i = *(uint64_t *)cdataptr(cd); | ||
344 | if ((a < 0 || i >= (uint64_t)a) && i <= (uint64_t)b) return (int32_t)i; | ||
345 | } else { | ||
346 | goto badtype; | ||
347 | } | ||
348 | #endif | ||
349 | } else { | ||
350 | goto badtype; | ||
351 | } | ||
352 | lj_err_arg(L, narg, LJ_ERR_NUMRNG); | ||
353 | } | ||
354 | badtype: | ||
355 | lj_err_argt(L, narg, LUA_TNUMBER); | ||
356 | return 0; /* unreachable */ | ||
357 | } | ||
358 | #endif | ||
359 | |||