summaryrefslogtreecommitdiff
path: root/src/lj_crecord.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-16 19:42:53 +0100
committerMike Pall <mike>2011-01-16 19:42:53 +0100
commit335232b0f1c173e91ed3f1cad73ee0f5f47bee03 (patch)
tree4cd5967a767d5bc20237947d2775344208f46220 /src/lj_crecord.c
parent2940ab023a2fd9014761db8ae603191074b5ac96 (diff)
downloadluajit-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.c62
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
116static 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. */
117static 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
140static 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);
370doconv: 411doconv:
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)));