diff options
author | Mike Pall <mike> | 2011-01-16 19:42:53 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-01-16 19:42:53 +0100 |
commit | 335232b0f1c173e91ed3f1cad73ee0f5f47bee03 (patch) | |
tree | 4cd5967a767d5bc20237947d2775344208f46220 /src/lj_crecord.c | |
parent | 2940ab023a2fd9014761db8ae603191074b5ac96 (diff) | |
download | luajit-335232b0f1c173e91ed3f1cad73ee0f5f47bee03.tar.gz luajit-335232b0f1c173e91ed3f1cad73ee0f5f47bee03.tar.bz2 luajit-335232b0f1c173e91ed3f1cad73ee0f5f47bee03.zip |
FFI: Record conversions to bool ctype.
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 95c32222..d4dc9ef9 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -113,7 +113,32 @@ static IRType crec_ct2irt(CType *ct) | |||
113 | return IRT_CDATA; | 113 | return IRT_CDATA; |
114 | } | 114 | } |
115 | 115 | ||
116 | static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp) | 116 | /* Determine whether a passed number or cdata number is non-zero. */ |
117 | static int crec_isnonzero(CType *s, void *p) | ||
118 | { | ||
119 | if (p == (void *)0) | ||
120 | return 0; | ||
121 | if (p == (void *)1) | ||
122 | return 1; | ||
123 | if ((s->info & CTF_FP)) { | ||
124 | if (s->size == sizeof(float)) | ||
125 | return (*(float *)p != 0); | ||
126 | else | ||
127 | return (*(double *)p != 0); | ||
128 | } else { | ||
129 | if (s->size == 1) | ||
130 | return (*(uint8_t *)p != 0); | ||
131 | else if (s->size == 2) | ||
132 | return (*(uint16_t *)p != 0); | ||
133 | else if (s->size == 4) | ||
134 | return (*(uint32_t *)p != 0); | ||
135 | else | ||
136 | return (*(uint64_t *)p != 0); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, | ||
141 | void *svisnz) | ||
117 | { | 142 | { |
118 | CTSize dsize = d->size, ssize = s->size; | 143 | CTSize dsize = d->size, ssize = s->size; |
119 | CTInfo dinfo = d->info, sinfo = s->info; | 144 | CTInfo dinfo = d->info, sinfo = s->info; |
@@ -134,7 +159,16 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp) | |||
134 | goto xstore; /* Source operand is already normalized. */ | 159 | goto xstore; /* Source operand is already normalized. */ |
135 | case CCX(B, I): | 160 | case CCX(B, I): |
136 | case CCX(B, F): | 161 | case CCX(B, F): |
137 | /* NYI: specialize to the result of a comparison against 0. */ | 162 | if (st != IRT_CDATA) { |
163 | /* Specialize to the result of a comparison against 0. */ | ||
164 | TRef zero = (st == IRT_NUM || st == IRT_FLOAT) ? lj_ir_knum(J, 0) : | ||
165 | (st == IRT_I64 || st == IRT_U64) ? lj_ir_kint64(J, 0) : | ||
166 | lj_ir_kint(J, 0); | ||
167 | int isnz = crec_isnonzero(s, svisnz); | ||
168 | emitir(IRTG(isnz ? IR_NE : IR_EQ, st), sp, zero); | ||
169 | sp = lj_ir_kint(J, isnz); | ||
170 | goto xstore; | ||
171 | } | ||
138 | goto err_nyi; | 172 | goto err_nyi; |
139 | 173 | ||
140 | /* Destination is an integer. */ | 174 | /* Destination is an integer. */ |
@@ -316,11 +350,14 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | |||
316 | { | 350 | { |
317 | CTState *cts = ctype_ctsG(J2G(J)); | 351 | CTState *cts = ctype_ctsG(J2G(J)); |
318 | CTypeID sid = CTID_P_VOID; | 352 | CTypeID sid = CTID_P_VOID; |
353 | void *svisnz = 0; | ||
319 | CType *s; | 354 | CType *s; |
320 | if (LJ_LIKELY(tref_isinteger(sp))) { | 355 | if (LJ_LIKELY(tref_isinteger(sp))) { |
321 | sid = CTID_INT32; | 356 | sid = CTID_INT32; |
357 | svisnz = (void *)(intptr_t)(numV(sval) != 0); | ||
322 | } else if (tref_isnum(sp)) { | 358 | } else if (tref_isnum(sp)) { |
323 | sid = CTID_DOUBLE; | 359 | sid = CTID_DOUBLE; |
360 | svisnz = (void *)(intptr_t)(numV(sval) != 0); | ||
324 | } else if (tref_isbool(sp)) { | 361 | } else if (tref_isbool(sp)) { |
325 | sp = lj_ir_kint(J, tref_istrue(sp) ? 1 : 0); | 362 | sp = lj_ir_kint(J, tref_istrue(sp) ? 1 : 0); |
326 | sid = CTID_BOOL; | 363 | sid = CTID_BOOL; |
@@ -337,6 +374,7 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | |||
337 | emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str)); | 374 | emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str)); |
338 | if (cct && ctype_isconstval(cct->info)) { | 375 | if (cct && ctype_isconstval(cct->info)) { |
339 | lua_assert(ctype_child(cts, cct)->size == 4); | 376 | lua_assert(ctype_child(cts, cct)->size == 4); |
377 | svisnz = (void *)(intptr_t)(cct->size != 0); | ||
340 | sp = lj_ir_kint(J, (int32_t)cct->size); | 378 | sp = lj_ir_kint(J, (int32_t)cct->size); |
341 | sid = ctype_cid(cct->info); | 379 | sid = ctype_cid(cct->info); |
342 | } /* else: interpreter will throw. */ | 380 | } /* else: interpreter will throw. */ |
@@ -346,16 +384,19 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | |||
346 | sp = emitir(IRT(IR_STRREF, IRT_P32), sp, lj_ir_kint(J, 0)); | 384 | sp = emitir(IRT(IR_STRREF, IRT_P32), sp, lj_ir_kint(J, 0)); |
347 | sid = CTID_A_CCHAR; | 385 | sid = CTID_A_CCHAR; |
348 | } | 386 | } |
349 | } else { /* NYI: tref_isstr(sp), tref_istab(sp), tref_islightud(sp). */ | 387 | } else { /* NYI: tref_istab(sp), tref_islightud(sp). */ |
350 | sid = argv2cdata(J, sp, sval)->typeid; | 388 | sid = argv2cdata(J, sp, sval)->typeid; |
351 | s = ctype_raw(cts, sid); | 389 | s = ctype_raw(cts, sid); |
390 | svisnz = cdataptr(cdataV(sval)); | ||
352 | if (ctype_isptr(s->info)) { | 391 | if (ctype_isptr(s->info)) { |
353 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; | 392 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; |
354 | sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR); | 393 | sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR); |
355 | if (ctype_isref(s->info)) | 394 | if (ctype_isref(s->info)) { |
395 | svisnz = *(void **)svisnz; | ||
356 | s = ctype_rawchild(cts, s); | 396 | s = ctype_rawchild(cts, s); |
357 | else | 397 | } else { |
358 | goto doconv; /* The pointer value was loaded, don't load number. */ | 398 | goto doconv; /* The pointer value was loaded, don't load number. */ |
399 | } | ||
359 | } else { | 400 | } else { |
360 | sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata))); | 401 | sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata))); |
361 | } | 402 | } |
@@ -369,7 +410,7 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | |||
369 | s = ctype_get(cts, sid); | 410 | s = ctype_get(cts, sid); |
370 | doconv: | 411 | doconv: |
371 | if (ctype_isenum(d->info)) d = ctype_child(cts, d); | 412 | if (ctype_isenum(d->info)) d = ctype_child(cts, d); |
372 | crec_ct_ct(J, d, s, dp, sp); | 413 | crec_ct_ct(J, d, s, dp, sp, svisnz); |
373 | } | 414 | } |
374 | 415 | ||
375 | /* -- C data metamethods -------------------------------------------------- */ | 416 | /* -- C data metamethods -------------------------------------------------- */ |
@@ -529,8 +570,10 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) | |||
529 | CType *dc = ctype_rawchild(cts, d); /* Array element type. */ | 570 | CType *dc = ctype_rawchild(cts, d); /* Array element type. */ |
530 | CTSize ofs, esize = dc->size; | 571 | CTSize ofs, esize = dc->size; |
531 | TRef sp = 0; | 572 | TRef sp = 0; |
532 | TValue *sval = NULL; | 573 | TValue tv; |
574 | TValue *sval = &tv; | ||
533 | MSize i; | 575 | MSize i; |
576 | setnumV(&tv, 0); | ||
534 | if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) | 577 | if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) |
535 | lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */ | 578 | lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */ |
536 | for (i = 1, ofs = 0; ofs < sz; ofs += esize) { | 579 | for (i = 1, ofs = 0; ofs < sz; ofs += esize) { |
@@ -554,7 +597,9 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) | |||
554 | if (ctype_isfield(df->info)) { | 597 | if (ctype_isfield(df->info)) { |
555 | CType *dc; | 598 | CType *dc; |
556 | TRef sp, dp; | 599 | TRef sp, dp; |
557 | TValue *sval; | 600 | TValue tv; |
601 | TValue *sval = &tv; | ||
602 | setnumV(&tv, 0); | ||
558 | if (!gcref(df->name)) continue; /* Ignore unnamed fields. */ | 603 | if (!gcref(df->name)) continue; /* Ignore unnamed fields. */ |
559 | dc = ctype_rawchild(cts, df); /* Field type. */ | 604 | dc = ctype_rawchild(cts, df); /* Field type. */ |
560 | if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) | 605 | if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) |
@@ -565,7 +610,6 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) | |||
565 | i++; | 610 | i++; |
566 | } else { | 611 | } else { |
567 | sp = ctype_isnum(dc->info) ? lj_ir_kint(J, 0) : TREF_NIL; | 612 | sp = ctype_isnum(dc->info) ? lj_ir_kint(J, 0) : TREF_NIL; |
568 | sval = NULL; | ||
569 | } | 613 | } |
570 | dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, | 614 | dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, |
571 | lj_ir_kintp(J, df->size + sizeof(GCcdata))); | 615 | lj_ir_kintp(J, df->size + sizeof(GCcdata))); |