diff options
author | Mike Pall <mike> | 2011-01-13 17:20:29 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-01-13 17:20:29 +0100 |
commit | 0fa32e5d3128bbbfc2419a2bd158d5a72f2cd15b (patch) | |
tree | dc2d28b307823f955b027126bffc7527c88833f4 /src/lj_crecord.c | |
parent | 59643c86fb9cfa01f69b52893d0da97d3e0ac298 (diff) | |
download | luajit-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.c | 25 |
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); |
352 | doconv: | 370 | doconv: |
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; |