diff options
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 6027f5a5..95c32222 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -374,6 +374,18 @@ doconv: | |||
374 | 374 | ||
375 | /* -- C data metamethods -------------------------------------------------- */ | 375 | /* -- C data metamethods -------------------------------------------------- */ |
376 | 376 | ||
377 | /* Specialize to the CTypeID held by a cdata constructor. */ | ||
378 | static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr) | ||
379 | { | ||
380 | CTypeID id; | ||
381 | lua_assert(tref_iscdata(tr) && cd->typeid == CTID_CTYPEID); | ||
382 | id = *(CTypeID *)cdataptr(cd); | ||
383 | tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata))); | ||
384 | tr = emitir(IRT(IR_XLOAD, IRT_INT), tr, 0); | ||
385 | emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id)); | ||
386 | return id; | ||
387 | } | ||
388 | |||
377 | /* This would be rather difficult in FOLD, so do it here: | 389 | /* This would be rather difficult in FOLD, so do it here: |
378 | ** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k) | 390 | ** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k) |
379 | ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz) | 391 | ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz) |
@@ -435,6 +447,8 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) | |||
435 | GCstr *name = strV(&rd->argv[1]); | 447 | GCstr *name = strV(&rd->argv[1]); |
436 | /* Always specialize to the field name. */ | 448 | /* Always specialize to the field name. */ |
437 | emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name)); | 449 | emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name)); |
450 | if (cd->typeid == CTID_CTYPEID) | ||
451 | ct = ctype_raw(cts, crec_constructor(J, cd, ptr)); | ||
438 | if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */ | 452 | if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */ |
439 | CType *cct = ctype_rawchild(cts, ct); | 453 | CType *cct = ctype_rawchild(cts, ct); |
440 | if (ctype_isstruct(cct->info)) { | 454 | if (ctype_isstruct(cct->info)) { |
@@ -575,7 +589,7 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd) | |||
575 | { | 589 | { |
576 | GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]); | 590 | GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]); |
577 | if (cd->typeid == CTID_CTYPEID) { | 591 | if (cd->typeid == CTID_CTYPEID) { |
578 | crec_alloc(J, rd, *(CTypeID *)cdataptr(cd)); | 592 | crec_alloc(J, rd, crec_constructor(J, cd, J->base[0])); |
579 | } else { | 593 | } else { |
580 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 594 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
581 | } | 595 | } |