diff options
author | Mike Pall <mike> | 2011-02-19 12:56:12 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-02-19 12:56:12 +0100 |
commit | bd29d16141d07ca4e436fe457fd6cbefd638ad15 (patch) | |
tree | fe4095b299e394d22cfc80e8995ef0d615c2f7f4 /src | |
parent | 3e2a7a2d7fcb763b39df1f17b440b16896bec0e7 (diff) | |
download | luajit-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.c | 11 | ||||
-rw-r--r-- | src/lj_ccall.c | 13 | ||||
-rw-r--r-- | src/lj_cconv.c | 20 | ||||
-rw-r--r-- | src/lj_cconv.h | 3 |
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. */ |
280 | static int ccall_struct_arg(CCallState *cc, CTState *cts, CType *d, int *rcl, | 280 | static 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. */ |
32 | LJ_NORET static void cconv_err_convtv(CTState *cts, CType *d, TValue *o) | 36 | LJ_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); |
582 | doconv: | 592 | doconv: |
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 | ||
52 | LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags); | 55 | LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags); |
53 | LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, | 56 | LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, |