/* Typecheck error for ordered comparisons. */ LJ_NOINLINE void lj_err_comp(lua_State *L, cTValue *o1, cTValue *o2) { const char *t1 = lj_typename(o1); const char *t2 = lj_typename(o2); err_msgv(L, t1 == t2 ? LJ_ERR_BADCMPV : LJ_ERR_BADCMPT, t1, t2); /* This assumes the two "boolean" entries are commoned by the C compiler. */ }
/* Typecheck error for arguments. */ LJ_NOINLINE void lj_err_argtype(lua_State *L, int narg, const char *xname) { TValue *o = narg < 0 ? L->top + narg : L->base + narg-1; const char *tname = o < L->top ? lj_typename(o) : lj_obj_typename[0]; const char *msg = lj_str_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); err_argmsg(L, narg, msg); }
/* Bad conversion from TValue. */ LJ_NORET static void cconv_err_convtv(CTState *cts, CType *d, TValue *o, CTInfo flags) { const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL)); const char *src = lj_typename(o); if (CCF_GETARG(flags)) lj_err_argv(cts->L, CCF_GETARG(flags), LJ_ERR_FFI_BADCONV, src, dst); else lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst); }
/* Typecheck error for arguments. */ LJ_NOINLINE void lj_err_argtype(lua_State *L, int narg, const char *xname) { const char *tname, *msg; if (narg <= LUA_REGISTRYINDEX) { if (narg >= LUA_GLOBALSINDEX) { tname = lj_obj_itypename[~LJ_TTAB]; } else { GCfunc *fn = curr_func(L); int idx = LUA_GLOBALSINDEX - narg; if (idx <= fn->c.nupvalues) tname = lj_typename(&fn->c.upvalue[idx-1]); else tname = lj_obj_typename[0]; } } else { TValue *o = narg < 0 ? L->top + narg : L->base + narg-1; tname = o < L->top ? lj_typename(o) : lj_obj_typename[0]; } msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); err_argmsg(L, narg, msg); }
/* Typecheck error for operands. */ LJ_NOINLINE void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm) { const char *tname = lj_typename(o); const char *opname = err2msg(opm); if (curr_funcisL(L)) { GCproto *pt = curr_proto(L); const BCIns *pc = cframe_Lpc(L) - 1; const char *oname = NULL; const char *kind = lj_debug_slotname(pt, pc, (BCReg)(o-L->base), &oname); if (kind) err_msgv(L, LJ_ERR_BADOPRT, opname, kind, oname, tname); } err_msgv(L, LJ_ERR_BADOPRV, opname, tname); }
/* Typecheck error for __call. */ LJ_NOINLINE void lj_err_optype_call(lua_State *L, TValue *o) { /* Gross hack if lua_[p]call or pcall/xpcall fail for a non-callable object: ** L->base still points to the caller. So add a dummy frame with L instead ** of a function. See lua_getstack(). */ const BCIns *pc = cframe_Lpc(L); if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) { const char *tname = lj_typename(o); setframe_pc(o, pc); setframe_gc(o, obj2gco(L)); L->top = L->base = o+1; err_msgv(L, LJ_ERR_BADCALL, tname); } lj_err_optype(L, o, LJ_ERR_OPCALL); }
/* Handle ctype __index/__newindex metamethods. */ static int ffi_index_meta(lua_State *L, CTState *cts, CType *ct, MMS mm) { CTypeID id = ctype_typeid(cts, ct); cTValue *tv = lj_ctype_meta(cts, id, mm); TValue *base = L->base; if (!tv) { const char *s; err_index: s = strdata(lj_ctype_repr(L, id, NULL)); if (tvisstr(L->base+1)) { lj_err_callerv(L, LJ_ERR_FFI_BADMEMBER, s, strVdata(L->base+1)); } else { const char *key = tviscdata(L->base+1) ? strdata(lj_ctype_repr(L, cdataV(L->base+1)->ctypeid, NULL)) : lj_typename(L->base+1); lj_err_callerv(L, LJ_ERR_FFI_BADIDXW, s, key); } } if (!tvisfunc(tv)) { if (mm == MM_index) { cTValue *o = lj_meta_tget(L, tv, base+1); if (o) { if (tvisnil(o)) goto err_index; copyTV(L, L->top-1, o); return 1; } } else { TValue *o = lj_meta_tset(L, tv, base+1); if (o) { copyTV(L, o, base+2); return 0; } } copyTV(L, base, L->top); tv = L->top-1; } return lj_meta_tailcall(L, tv); }