aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-02-19 12:56:12 +0100
committerMike Pall <mike>2011-02-19 12:56:12 +0100
commitbd29d16141d07ca4e436fe457fd6cbefd638ad15 (patch)
treefe4095b299e394d22cfc80e8995ef0d615c2f7f4 /src
parent3e2a7a2d7fcb763b39df1f17b440b16896bec0e7 (diff)
downloadluajit-bd29d16141d07ca4e436fe457fd6cbefd638ad15.tar.gz
luajit-bd29d16141d07ca4e436fe457fd6cbefd638ad15.tar.bz2
luajit-bd29d16141d07ca4e436fe457fd6cbefd638ad15.zip
FFI: Improve conversion error messages.
Diffstat (limited to 'src')
-rw-r--r--src/lib_ffi.c11
-rw-r--r--src/lj_ccall.c13
-rw-r--r--src/lj_cconv.c20
-rw-r--r--src/lj_cconv.h3
4 files changed, 32 insertions, 15 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c
index 361c3ba1..e88b6f54 100644
--- a/src/lib_ffi.c
+++ b/src/lib_ffi.c
@@ -74,7 +74,7 @@ static void *ffi_checkptr(lua_State *L, int narg, CTypeID id)
74 void *p; 74 void *p;
75 if (o >= L->top) 75 if (o >= L->top)
76 lj_err_arg(L, narg, LJ_ERR_NOVAL); 76 lj_err_arg(L, narg, LJ_ERR_NOVAL);
77 lj_cconv_ct_tv(cts, ctype_get(cts, id), (uint8_t *)&p, o, 0); 77 lj_cconv_ct_tv(cts, ctype_get(cts, id), (uint8_t *)&p, o, CCF_ARG(narg));
78 return p; 78 return p;
79} 79}
80 80
@@ -86,7 +86,8 @@ static int32_t ffi_checkint(lua_State *L, int narg)
86 int32_t i; 86 int32_t i;
87 if (o >= L->top) 87 if (o >= L->top)
88 lj_err_arg(L, narg, LJ_ERR_NOVAL); 88 lj_err_arg(L, narg, LJ_ERR_NOVAL);
89 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0); 89 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o,
90 CCF_ARG(narg));
90 return i; 91 return i;
91} 92}
92 93
@@ -444,9 +445,11 @@ LJLIB_CF(ffi_string) LJLIB_REC(.)
444 size_t len; 445 size_t len;
445 if (o+1 < L->top) { 446 if (o+1 < L->top) {
446 len = (size_t)ffi_checkint(L, 2); 447 len = (size_t)ffi_checkint(L, 2);
447 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o, 0); 448 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o,
449 CCF_ARG(1));
448 } else { 450 } else {
449 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o, 0); 451 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o,
452 CCF_ARG(1));
450 len = strlen(p); 453 len = strlen(p);
451 } 454 }
452 L->top = o+1; /* Make sure this is the last item on the stack. */ 455 L->top = o+1; /* Make sure this is the last item on the stack. */
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index f2eceb6d..3f548c30 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -140,7 +140,7 @@
140 int rcl[2]; rcl[0] = rcl[1] = 0; \ 140 int rcl[2]; rcl[0] = rcl[1] = 0; \
141 if (!ccall_classify_struct(cts, d, rcl, 0)) { \ 141 if (!ccall_classify_struct(cts, d, rcl, 0)) { \
142 cc->nsp = nsp; cc->ngpr = ngpr; cc->nfpr = nfpr; \ 142 cc->nsp = nsp; cc->ngpr = ngpr; cc->nfpr = nfpr; \
143 if (ccall_struct_arg(cc, cts, d, rcl, o)) goto err_nyi; \ 143 if (ccall_struct_arg(cc, cts, d, rcl, o, narg)) goto err_nyi; \
144 nsp = cc->nsp; ngpr = cc->ngpr; nfpr = cc->nfpr; \ 144 nsp = cc->nsp; ngpr = cc->ngpr; nfpr = cc->nfpr; \
145 continue; \ 145 continue; \
146 } /* Pass all other structs by value on stack. */ 146 } /* Pass all other structs by value on stack. */
@@ -278,11 +278,12 @@ static int ccall_struct_reg(CCallState *cc, GPRArg *dp, int *rcl)
278 278
279/* Pass a small struct argument. */ 279/* Pass a small struct argument. */
280static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl, 280static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl,
281 TValue *o) 281 TValue *o, int narg)
282{ 282{
283 GPRArg dp[2]; 283 GPRArg dp[2];
284 dp[0] = dp[1] = 0; 284 dp[0] = dp[1] = 0;
285 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, 0); /* Convert to temp. struct. */ 285 /* Convert to temp. struct. */
286 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
286 if (!ccall_struct_reg(cc, dp, rcl)) { /* Register overflow? Pass on stack. */ 287 if (!ccall_struct_reg(cc, dp, rcl)) { /* Register overflow? Pass on stack. */
287 MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1; 288 MSize nsp = cc->nsp, n = rcl[1] ? 2 : 1;
288 if (nsp + n > CCALL_MAXSTACK) return 1; /* Too many arguments. */ 289 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,
347 TValue *o, *top = L->top; 348 TValue *o, *top = L->top;
348 CTypeID fid; 349 CTypeID fid;
349 CType *ctr; 350 CType *ctr;
350 MSize maxgpr, ngpr = 0, nsp = 0; 351 MSize maxgpr, ngpr = 0, nsp = 0, narg;
351#if CCALL_NARG_FPR 352#if CCALL_NARG_FPR
352 MSize nfpr = 0; 353 MSize nfpr = 0;
353#endif 354#endif
@@ -401,7 +402,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
401 } 402 }
402 403
403 /* Walk through all passed arguments. */ 404 /* Walk through all passed arguments. */
404 for (o = L->base+1; o < top; o++) { 405 for (o = L->base+1, narg = 1; o < top; o++, narg++) {
405 CTypeID did; 406 CTypeID did;
406 CType *d; 407 CType *d;
407 CTSize sz; 408 CTSize sz;
@@ -466,7 +467,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
466 *(void **)dp = rp; 467 *(void **)dp = rp;
467 dp = rp; 468 dp = rp;
468 } 469 }
469 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, 0); 470 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
470#if LJ_TARGET_X64 && LJ_ABI_WIN 471#if LJ_TARGET_X64 && LJ_ABI_WIN
471 if (isva) { /* Windows/x64 mirrors varargs in both register sets. */ 472 if (isva) { /* Windows/x64 mirrors varargs in both register sets. */
472 if (nfpr == ngpr) 473 if (nfpr == ngpr)
diff --git a/src/lj_cconv.c b/src/lj_cconv.c
index 1e6df8d8..94a9895f 100644
--- a/src/lj_cconv.c
+++ b/src/lj_cconv.c
@@ -22,17 +22,26 @@ LJ_NORET static void cconv_err_conv(CTState *cts, CType *d, CType *s,
22 const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL)); 22 const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
23 const char *src; 23 const char *src;
24 if ((flags & CCF_FROMTV)) 24 if ((flags & CCF_FROMTV))
25 src = lj_obj_typename[1+(ctype_isnum(s->info) ? LUA_TNUMBER : LUA_TSTRING)]; 25 src = lj_obj_typename[1+(ctype_isnum(s->info) ? LUA_TNUMBER :
26 ctype_isarray(s->info) ? LUA_TSTRING : LUA_TNIL)];
26 else 27 else
27 src = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, s), NULL)); 28 src = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, s), NULL));
28 lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst); 29 if (CCF_GETARG(flags))
30 lj_err_argv(cts->L, CCF_GETARG(flags), LJ_ERR_FFI_BADCONV, src, dst);
31 else
32 lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst);
29} 33}
30 34
31/* Bad conversion from TValue. */ 35/* Bad conversion from TValue. */
32LJ_NORET static void cconv_err_convtv(CTState *cts, CType *d, TValue *o) 36LJ_NORET static void cconv_err_convtv(CTState *cts, CType *d, TValue *o,
37 CTInfo flags)
33{ 38{
34 const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL)); 39 const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
35 lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, typename(o), dst); 40 const char *src = typename(o);
41 if (CCF_GETARG(flags))
42 lj_err_argv(cts->L, CCF_GETARG(flags), LJ_ERR_FFI_BADCONV, src, dst);
43 else
44 lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst);
36} 45}
37 46
38/* Initializer overflow. */ 47/* Initializer overflow. */
@@ -570,13 +579,14 @@ void lj_cconv_ct_tv(CTState *cts, CType *d,
570 sid = CTID_BOOL; 579 sid = CTID_BOOL;
571 } else if (tvisnil(o)) { 580 } else if (tvisnil(o)) {
572 tmpptr = (void *)0; 581 tmpptr = (void *)0;
582 flags |= CCF_FROMTV;
573 } else if (tvisudata(o)) { 583 } else if (tvisudata(o)) {
574 tmpptr = uddata(udataV(o)); 584 tmpptr = uddata(udataV(o));
575 } else if (tvislightud(o)) { 585 } else if (tvislightud(o)) {
576 tmpptr = lightudV(o); 586 tmpptr = lightudV(o);
577 } else { 587 } else {
578 err_conv: 588 err_conv:
579 cconv_err_convtv(cts, d, o); 589 cconv_err_convtv(cts, d, o, flags);
580 } 590 }
581 s = ctype_get(cts, sid); 591 s = ctype_get(cts, sid);
582doconv: 592doconv:
diff --git a/src/lj_cconv.h b/src/lj_cconv.h
index 494f9d4e..47c14596 100644
--- a/src/lj_cconv.h
+++ b/src/lj_cconv.h
@@ -48,6 +48,9 @@ static LJ_AINLINE uint32_t cconv_idx(CTInfo info)
48#define CCF_SAME 0x00000004u 48#define CCF_SAME 0x00000004u
49#define CCF_IGNQUAL 0x00000008u 49#define CCF_IGNQUAL 0x00000008u
50 50
51#define CCF_ARG_SHIFT 8
52#define CCF_ARG(n) ((n) << CCF_ARG_SHIFT)
53#define CCF_GETARG(f) ((f) >> CCF_ARG_SHIFT)
51 54
52LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags); 55LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags);
53LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, 56LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,