summaryrefslogtreecommitdiff
path: root/src/lj_carith.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r--src/lj_carith.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c
index c5275f70..8c76abe9 100644
--- a/src/lj_carith.c
+++ b/src/lj_carith.c
@@ -46,6 +46,7 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca)
46 ct = ctype_get(cts, 46 ct = ctype_get(cts,
47 lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR)); 47 lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
48 } 48 }
49 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
49 ca->ct[i] = ct; 50 ca->ct[i] = ct;
50 ca->p[i] = p; 51 ca->p[i] = p;
51 } else if (tvisint(o)) { 52 } else if (tvisint(o)) {
@@ -57,6 +58,25 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca)
57 } else if (tvisnil(o)) { 58 } else if (tvisnil(o)) {
58 ca->ct[i] = ctype_get(cts, CTID_P_VOID); 59 ca->ct[i] = ctype_get(cts, CTID_P_VOID);
59 ca->p[i] = (uint8_t *)0; 60 ca->p[i] = (uint8_t *)0;
61 } else if (tvisstr(o)) {
62 TValue *o2 = i == 0 ? o+1 : o-1;
63 CType *ct = ctype_raw(cts, cdataV(o2)->ctypeid);
64 ca->ct[i] = NULL;
65 ca->p[i] = NULL;
66 ok = 0;
67 if (ctype_isenum(ct->info)) {
68 CTSize ofs;
69 CType *cct = lj_ctype_getfield(cts, ct, strV(o), &ofs);
70 if (cct && ctype_isconstval(cct->info)) {
71 ca->ct[i] = ctype_child(cts, cct);
72 ca->p[i] = (uint8_t *)&cct->size; /* Assumes ct does not grow. */
73 ok = 1;
74 } else {
75 ca->ct[1-i] = ct; /* Use enum to improve error message. */
76 ca->p[1-i] = NULL;
77 break;
78 }
79 }
60 } else { 80 } else {
61 ca->ct[i] = NULL; 81 ca->ct[i] = NULL;
62 ca->p[i] = NULL; 82 ca->p[i] = NULL;
@@ -204,17 +224,22 @@ static int lj_carith_meta(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
204 tv = lj_ctype_meta(cts, cdataV(L->base+1)->ctypeid, mm); 224 tv = lj_ctype_meta(cts, cdataV(L->base+1)->ctypeid, mm);
205 if (!tv) { 225 if (!tv) {
206 const char *repr[2]; 226 const char *repr[2];
207 int i; 227 int i, isenum = -1, isstr = -1;
208 if (mm == MM_eq) { /* Equality checks never raise an error. */ 228 if (mm == MM_eq) { /* Equality checks never raise an error. */
209 setboolV(L->top-1, 0); 229 setboolV(L->top-1, 0);
210 return 1; 230 return 1;
211 } 231 }
212 for (i = 0; i < 2; i++) { 232 for (i = 0; i < 2; i++) {
213 if (ca->ct[i]) 233 if (ca->ct[i]) {
234 if (ctype_isenum(ca->ct[i]->info)) isenum = i;
214 repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca->ct[i]), NULL)); 235 repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca->ct[i]), NULL));
215 else 236 } else {
237 if (tvisstr(&L->base[i])) isstr = i;
216 repr[i] = lj_typename(&L->base[i]); 238 repr[i] = lj_typename(&L->base[i]);
239 }
217 } 240 }
241 if ((isenum ^ isstr) == 1)
242 lj_err_callerv(L, LJ_ERR_FFI_BADCONV, repr[isstr], repr[isenum]);
218 lj_err_callerv(L, mm == MM_len ? LJ_ERR_FFI_BADLEN : 243 lj_err_callerv(L, mm == MM_len ? LJ_ERR_FFI_BADLEN :
219 mm == MM_concat ? LJ_ERR_FFI_BADCONCAT : 244 mm == MM_concat ? LJ_ERR_FFI_BADCONCAT :
220 mm < MM_add ? LJ_ERR_FFI_BADCOMP : LJ_ERR_FFI_BADARITH, 245 mm < MM_add ? LJ_ERR_FFI_BADCOMP : LJ_ERR_FFI_BADARITH,