summaryrefslogtreecommitdiff
path: root/src/lj_crecord.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-13 17:20:29 +0100
committerMike Pall <mike>2011-01-13 17:20:29 +0100
commit0fa32e5d3128bbbfc2419a2bd158d5a72f2cd15b (patch)
treedc2d28b307823f955b027126bffc7527c88833f4 /src/lj_crecord.c
parent59643c86fb9cfa01f69b52893d0da97d3e0ac298 (diff)
downloadluajit-0fa32e5d3128bbbfc2419a2bd158d5a72f2cd15b.tar.gz
luajit-0fa32e5d3128bbbfc2419a2bd158d5a72f2cd15b.tar.bz2
luajit-0fa32e5d3128bbbfc2419a2bd158d5a72f2cd15b.zip
FFI: Record conversions from strings to enums or pointers.
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r--src/lj_crecord.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 0f48f213..6027f5a5 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -328,6 +328,24 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval)
328 sp = lj_ir_kptr(J, NULL); 328 sp = lj_ir_kptr(J, NULL);
329 } else if (tref_isudata(sp)) { 329 } else if (tref_isudata(sp)) {
330 sp = emitir(IRT(IR_ADD, IRT_P32), sp, lj_ir_kint(J, sizeof(GCcdata))); 330 sp = emitir(IRT(IR_ADD, IRT_P32), sp, lj_ir_kint(J, sizeof(GCcdata)));
331 } else if (tref_isstr(sp)) {
332 if (ctype_isenum(d->info)) { /* Match string against enum constant. */
333 GCstr *str = strV(sval);
334 CTSize ofs;
335 CType *cct = lj_ctype_getfield(cts, d, str, &ofs);
336 /* Specialize to the name of the enum constant. */
337 emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str));
338 if (cct && ctype_isconstval(cct->info)) {
339 lua_assert(ctype_child(cts, cct)->size == 4);
340 sp = lj_ir_kint(J, (int32_t)cct->size);
341 sid = ctype_cid(cct->info);
342 } /* else: interpreter will throw. */
343 } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */
344 lj_trace_err(J, LJ_TRERR_BADTYPE); /* NYI */
345 } else { /* Otherwise pass the string data as a const char[]. */
346 sp = emitir(IRT(IR_STRREF, IRT_P32), sp, lj_ir_kint(J, 0));
347 sid = CTID_A_CCHAR;
348 }
331 } else { /* NYI: tref_isstr(sp), tref_istab(sp), tref_islightud(sp). */ 349 } else { /* NYI: tref_isstr(sp), tref_istab(sp), tref_islightud(sp). */
332 sid = argv2cdata(J, sp, sval)->typeid; 350 sid = argv2cdata(J, sp, sval)->typeid;
333 s = ctype_raw(cts, sid); 351 s = ctype_raw(cts, sid);
@@ -350,6 +368,7 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval)
350 } 368 }
351 s = ctype_get(cts, sid); 369 s = ctype_get(cts, sid);
352doconv: 370doconv:
371 if (ctype_isenum(d->info)) d = ctype_child(cts, d);
353 crec_ct_ct(J, d, s, dp, sp); 372 crec_ct_ct(J, d, s, dp, sp);
354} 373}
355 374
@@ -459,11 +478,11 @@ index_struct:
459 if (ctype_isref(ct->info)) 478 if (ctype_isref(ct->info))
460 ptr = emitir(IRT(IR_XLOAD, IRT_PTR), ptr, 0); 479 ptr = emitir(IRT(IR_XLOAD, IRT_PTR), ptr, 0);
461 480
462 /* Skip attributes and enums. */ 481 while (ctype_isattrib(ct->info))
463 while (ctype_isattrib(ct->info) || ctype_isenum(ct->info)) 482 ct = ctype_child(cts, ct); /* Skip attributes. */
464 ct = ctype_child(cts, ct);
465 483
466 if (rd->data == 0) { /* __index metamethod. */ 484 if (rd->data == 0) { /* __index metamethod. */
485 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); /* Skip enums. */
467 J->base[0] = crec_tv_ct(J, ct, sid, ptr); 486 J->base[0] = crec_tv_ct(J, ct, sid, ptr);
468 } else { /* __newindex metamethod. */ 487 } else { /* __newindex metamethod. */
469 rd->nres = 0; 488 rd->nres = 0;