/* Check first argument for a C type and returns its ID. */ static CTypeID ffi_checkctype(lua_State *L, CTState *cts, TValue *param) { TValue *o = L->base; if (!(o < L->top)) { err_argtype: lj_err_argtype(L, 1, "C type"); } if (tvisstr(o)) { /* Parse an abstract C type declaration. */ GCstr *s = strV(o); CPState cp; int errcode; cp.L = L; cp.cts = cts; cp.srcname = strdata(s); cp.p = strdata(s); cp.param = param; cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT; errcode = lj_cparse(&cp); if (errcode) lj_err_throw(L, errcode); /* Propagate errors. */ return cp.val.id; } else { GCcdata *cd; if (!tviscdata(o)) goto err_argtype; if (param && param < L->top) lj_err_arg(L, 1, LJ_ERR_FFI_NUMPARAM); cd = cdataV(o); return cd->ctypeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->ctypeid; } }
TValue *lj_lib_checkany(lua_State *L, int narg) { TValue *o = L->base + narg-1; if (o >= L->top) lj_err_arg(L, narg, LJ_ERR_NOVAL); return o; }
static int setjitmode(lua_State *L, int mode) { int idx = 0; if (L->base == L->top || tvisnil(L->base)) { /* jit.on/off/flush([nil]) */ mode |= LUAJIT_MODE_ENGINE; } else { /* jit.on/off/flush(func|proto, nil|true|false) */ if (tvisfunc(L->base) || tvisproto(L->base)) idx = 1; else if (!tvistrue(L->base)) /* jit.on/off/flush(true, nil|true|false) */ goto err; if (L->base+1 < L->top && tvisbool(L->base+1)) mode |= boolV(L->base+1) ? LUAJIT_MODE_ALLFUNC : LUAJIT_MODE_ALLSUBFUNC; else mode |= LUAJIT_MODE_FUNC; } if (luaJIT_setmode(L, idx, mode) != 1) { err: #if LJ_HASJIT lj_err_arg(L, 1, LJ_ERR_NOLFUNC); #else lj_err_caller(L, LJ_ERR_NOJIT); #endif } return 0; }
/* Convert argument to C pointer. */ static void *ffi_checkptr(lua_State *L, int narg, CTypeID id) { CTState *cts = ctype_cts(L); TValue *o = L->base + narg-1; void *p; if (o >= L->top) lj_err_arg(L, narg, LJ_ERR_NOVAL); lj_cconv_ct_tv(cts, ctype_get(cts, id), (uint8_t *)&p, o, CCF_ARG(narg)); return p; }
/* Convert argument to int32_t. */ static int32_t ffi_checkint(lua_State *L, int narg) { CTState *cts = ctype_cts(L); TValue *o = L->base + narg-1; int32_t i; if (o >= L->top) lj_err_arg(L, narg, LJ_ERR_NOVAL); lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, CCF_ARG(narg)); return i; }
GCtab *lj_lib_checktabornil(lua_State *L, int narg) { TValue *o = L->base + narg-1; if (o < L->top) { if (tvistab(o)) return tabV(o); else if (tvisnil(o)) return NULL; } lj_err_arg(L, narg, LJ_ERR_NOTABN); return NULL; /* unreachable */ }
static int io_file_read(lua_State *L, FILE *fp, int start) { int ok, n, nargs = cast_int(L->top - L->base) - start; clearerr(fp); if (nargs == 0) { ok = io_file_readline(L, fp); n = start+1; /* Return 1 result. */ } else { /* The results plus the buffers go on top of the args. */ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); ok = 1; for (n = start; nargs-- && ok; n++) { if (tvisstr(L->base+n)) { const char *p = strVdata(L->base+n); if (p[0] != '*') lj_err_arg(L, n+1, LJ_ERR_INVOPT); if (p[1] == 'n') ok = io_file_readnum(L, fp); else if (p[1] == 'l') ok = io_file_readline(L, fp); else if (p[1] == 'a') io_file_readchars(L, fp, ~((size_t)0)); else lj_err_arg(L, n+1, LJ_ERR_INVFMT); } else if (tvisnum(L->base+n)) { size_t len = (size_t)lj_lib_checkint(L, n+1); ok = len ? io_file_readchars(L, fp, len) : io_file_testeof(L, fp); } else { lj_err_arg(L, n+1, LJ_ERR_INVOPT); } } } if (ferror(fp)) return io_pushresult(L, 0, NULL); if (!ok) setnilV(L->top-1); /* Replace last result with nil. */ return n - start; }