/* 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; } }
static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o) { if (tref_isstr(tr)) { GCstr *s = strV(o); CPState cp; CTypeID oldtop; /* Specialize to the string containing the C type declaration. */ emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, s)); cp.L = J->L; cp.cts = ctype_ctsG(J2G(J)); oldtop = cp.cts->top; cp.srcname = strdata(s); cp.p = strdata(s); cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT; if (lj_cparse(&cp) || cp.cts->top > oldtop) /* Avoid new struct defs. */ lj_trace_err(J, LJ_TRERR_BADTYPE); return cp.val.id; } else { GCcdata *cd = argv2cdata(J, tr, o); return cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->typeid; } }