mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
FFI: Improve conversion error messages.
This commit is contained in:
parent
3e2a7a2d7f
commit
bd29d16141
@ -74,7 +74,7 @@ static void *ffi_checkptr(lua_State *L, int narg, CTypeID id)
|
|||||||
void *p;
|
void *p;
|
||||||
if (o >= L->top)
|
if (o >= L->top)
|
||||||
lj_err_arg(L, narg, LJ_ERR_NOVAL);
|
lj_err_arg(L, narg, LJ_ERR_NOVAL);
|
||||||
lj_cconv_ct_tv(cts, ctype_get(cts, id), (uint8_t *)&p, o, 0);
|
lj_cconv_ct_tv(cts, ctype_get(cts, id), (uint8_t *)&p, o, CCF_ARG(narg));
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,8 @@ static int32_t ffi_checkint(lua_State *L, int narg)
|
|||||||
int32_t i;
|
int32_t i;
|
||||||
if (o >= L->top)
|
if (o >= L->top)
|
||||||
lj_err_arg(L, narg, LJ_ERR_NOVAL);
|
lj_err_arg(L, narg, LJ_ERR_NOVAL);
|
||||||
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0);
|
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o,
|
||||||
|
CCF_ARG(narg));
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,9 +445,11 @@ LJLIB_CF(ffi_string) LJLIB_REC(.)
|
|||||||
size_t len;
|
size_t len;
|
||||||
if (o+1 < L->top) {
|
if (o+1 < L->top) {
|
||||||
len = (size_t)ffi_checkint(L, 2);
|
len = (size_t)ffi_checkint(L, 2);
|
||||||
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o, 0);
|
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o,
|
||||||
|
CCF_ARG(1));
|
||||||
} else {
|
} else {
|
||||||
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o, 0);
|
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o,
|
||||||
|
CCF_ARG(1));
|
||||||
len = strlen(p);
|
len = strlen(p);
|
||||||
}
|
}
|
||||||
L->top = o+1; /* Make sure this is the last item on the stack. */
|
L->top = o+1; /* Make sure this is the last item on the stack. */
|
||||||
|
@ -140,7 +140,7 @@
|
|||||||
int rcl[2]; rcl[0] = rcl[1] = 0; \
|
int rcl[2]; rcl[0] = rcl[1] = 0; \
|
||||||
if (!ccall_classify_struct(cts, d, rcl, 0)) { \
|
if (!ccall_classify_struct(cts, d, rcl, 0)) { \
|
||||||
cc->nsp = nsp; cc->ngpr = ngpr; cc->nfpr = nfpr; \
|
cc->nsp = nsp; cc->ngpr = ngpr; cc->nfpr = nfpr; \
|
||||||
if (ccall_struct_arg(cc, cts, d, rcl, o)) goto err_nyi; \
|
if (ccall_struct_arg(cc, cts, d, rcl, o, narg)) goto err_nyi; \
|
||||||
nsp = cc->nsp; ngpr = cc->ngpr; nfpr = cc->nfpr; \
|
nsp = cc->nsp; ngpr = cc->ngpr; nfpr = cc->nfpr; \
|
||||||
continue; \
|
continue; \
|
||||||
} /* Pass all other structs by value on stack. */
|
} /* Pass all other structs by value on stack. */
|
||||||
@ -278,11 +278,12 @@ static int ccall_struct_reg(CCallState *cc, GPRArg *dp, int *rcl)
|
|||||||
|
|
||||||
/* Pass a small struct argument. */
|
/* Pass a small struct argument. */
|
||||||
static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl,
|
static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl,
|
||||||
TValue *o)
|
TValue *o, int narg)
|
||||||
{
|
{
|
||||||
GPRArg dp[2];
|
GPRArg dp[2];
|
||||||
dp[0] = dp[1] = 0;
|
dp[0] = dp[1] = 0;
|
||||||
lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, 0); /* Convert to temp. struct. */
|
/* Convert to temp. struct. */
|
||||||
|
lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
|
||||||
if (!ccall_struct_reg(cc, dp, rcl)) { /* Register overflow? Pass on stack. */
|
if (!ccall_struct_reg(cc, dp, rcl)) { /* Register overflow? Pass on stack. */
|
||||||
MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1;
|
MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1;
|
||||||
if (nsp + n > CCALL_MAXSTACK) return 1; /* Too many arguments. */
|
if (nsp + n > CCALL_MAXSTACK) return 1; /* Too many arguments. */
|
||||||
@ -347,7 +348,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
|||||||
TValue *o, *top = L->top;
|
TValue *o, *top = L->top;
|
||||||
CTypeID fid;
|
CTypeID fid;
|
||||||
CType *ctr;
|
CType *ctr;
|
||||||
MSize maxgpr, ngpr = 0, nsp = 0;
|
MSize maxgpr, ngpr = 0, nsp = 0, narg;
|
||||||
#if CCALL_NARG_FPR
|
#if CCALL_NARG_FPR
|
||||||
MSize nfpr = 0;
|
MSize nfpr = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -401,7 +402,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Walk through all passed arguments. */
|
/* Walk through all passed arguments. */
|
||||||
for (o = L->base+1; o < top; o++) {
|
for (o = L->base+1, narg = 1; o < top; o++, narg++) {
|
||||||
CTypeID did;
|
CTypeID did;
|
||||||
CType *d;
|
CType *d;
|
||||||
CTSize sz;
|
CTSize sz;
|
||||||
@ -466,7 +467,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
|||||||
*(void **)dp = rp;
|
*(void **)dp = rp;
|
||||||
dp = rp;
|
dp = rp;
|
||||||
}
|
}
|
||||||
lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, 0);
|
lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
|
||||||
#if LJ_TARGET_X64 && LJ_ABI_WIN
|
#if LJ_TARGET_X64 && LJ_ABI_WIN
|
||||||
if (isva) { /* Windows/x64 mirrors varargs in both register sets. */
|
if (isva) { /* Windows/x64 mirrors varargs in both register sets. */
|
||||||
if (nfpr == ngpr)
|
if (nfpr == ngpr)
|
||||||
|
@ -22,17 +22,26 @@ LJ_NORET static void cconv_err_conv(CTState *cts, CType *d, CType *s,
|
|||||||
const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
|
const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
|
||||||
const char *src;
|
const char *src;
|
||||||
if ((flags & CCF_FROMTV))
|
if ((flags & CCF_FROMTV))
|
||||||
src = lj_obj_typename[1+(ctype_isnum(s->info) ? LUA_TNUMBER : LUA_TSTRING)];
|
src = lj_obj_typename[1+(ctype_isnum(s->info) ? LUA_TNUMBER :
|
||||||
|
ctype_isarray(s->info) ? LUA_TSTRING : LUA_TNIL)];
|
||||||
else
|
else
|
||||||
src = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, s), NULL));
|
src = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, s), NULL));
|
||||||
|
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);
|
lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bad conversion from TValue. */
|
/* Bad conversion from TValue. */
|
||||||
LJ_NORET static void cconv_err_convtv(CTState *cts, CType *d, TValue *o)
|
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 *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
|
||||||
lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, typename(o), dst);
|
const char *src = 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initializer overflow. */
|
/* Initializer overflow. */
|
||||||
@ -570,13 +579,14 @@ void lj_cconv_ct_tv(CTState *cts, CType *d,
|
|||||||
sid = CTID_BOOL;
|
sid = CTID_BOOL;
|
||||||
} else if (tvisnil(o)) {
|
} else if (tvisnil(o)) {
|
||||||
tmpptr = (void *)0;
|
tmpptr = (void *)0;
|
||||||
|
flags |= CCF_FROMTV;
|
||||||
} else if (tvisudata(o)) {
|
} else if (tvisudata(o)) {
|
||||||
tmpptr = uddata(udataV(o));
|
tmpptr = uddata(udataV(o));
|
||||||
} else if (tvislightud(o)) {
|
} else if (tvislightud(o)) {
|
||||||
tmpptr = lightudV(o);
|
tmpptr = lightudV(o);
|
||||||
} else {
|
} else {
|
||||||
err_conv:
|
err_conv:
|
||||||
cconv_err_convtv(cts, d, o);
|
cconv_err_convtv(cts, d, o, flags);
|
||||||
}
|
}
|
||||||
s = ctype_get(cts, sid);
|
s = ctype_get(cts, sid);
|
||||||
doconv:
|
doconv:
|
||||||
|
@ -48,6 +48,9 @@ static LJ_AINLINE uint32_t cconv_idx(CTInfo info)
|
|||||||
#define CCF_SAME 0x00000004u
|
#define CCF_SAME 0x00000004u
|
||||||
#define CCF_IGNQUAL 0x00000008u
|
#define CCF_IGNQUAL 0x00000008u
|
||||||
|
|
||||||
|
#define CCF_ARG_SHIFT 8
|
||||||
|
#define CCF_ARG(n) ((n) << CCF_ARG_SHIFT)
|
||||||
|
#define CCF_GETARG(f) ((f) >> CCF_ARG_SHIFT)
|
||||||
|
|
||||||
LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags);
|
LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags);
|
||||||
LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
|
LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
|
||||||
|
Loading…
Reference in New Issue
Block a user