diff options
Diffstat (limited to 'src/lj_lib.c')
-rw-r--r-- | src/lj_lib.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/lj_lib.c b/src/lj_lib.c index a962ddc1..21e6a61d 100644 --- a/src/lj_lib.c +++ b/src/lj_lib.c | |||
@@ -16,6 +16,9 @@ | |||
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" |
21 | #include "lj_strfmt.h" | 24 | #include "lj_strfmt.h" |
@@ -301,3 +304,54 @@ int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst) | |||
301 | return def; | 304 | return def; |
302 | } | 305 | } |
303 | 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 | } | ||
346 | #endif | ||
347 | } else { | ||
348 | goto badtype; | ||
349 | } | ||
350 | lj_err_arg(L, narg, LJ_ERR_NUMRNG); | ||
351 | } | ||
352 | badtype: | ||
353 | lj_err_argt(L, narg, LUA_TNUMBER); | ||
354 | return 0; /* unreachable */ | ||
355 | } | ||
356 | #endif | ||
357 | |||