diff options
| -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; |
