diff options
| author | Mike Pall <mike> | 2011-01-16 18:32:33 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-01-16 18:32:33 +0100 |
| commit | 6f746577d087e39d72d9ce2bc61df27828c6422e (patch) | |
| tree | 4575fd34dbd66f7cce2dd7ab6bf085432d1e0251 | |
| parent | 0fa32e5d3128bbbfc2419a2bd158d5a72f2cd15b (diff) | |
| download | luajit-6f746577d087e39d72d9ce2bc61df27828c6422e.tar.gz luajit-6f746577d087e39d72d9ce2bc61df27828c6422e.tar.bz2 luajit-6f746577d087e39d72d9ce2bc61df27828c6422e.zip | |
FFI: Allow indexing a struct constructor to get constants.
Specialize to the CTypeID held by a constructor in all cases.
| -rw-r--r-- | src/lj_cdata.c | 11 | ||||
| -rw-r--r-- | src/lj_crecord.c | 16 |
2 files changed, 26 insertions, 1 deletions
diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 5bd55237..1d0aea85 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c | |||
| @@ -127,6 +127,17 @@ collect_attrib: | |||
| 127 | return ct; | 127 | return ct; |
| 128 | } | 128 | } |
| 129 | } | 129 | } |
| 130 | } else if (cd->typeid == CTID_CTYPEID) { | ||
| 131 | /* Allow indexing a (pointer to) struct constructor to get constants. */ | ||
| 132 | CType *sct = ct = ctype_raw(cts, *(CTypeID *)p); | ||
| 133 | if (ctype_isptr(sct->info)) | ||
| 134 | sct = ctype_rawchild(cts, sct); | ||
| 135 | if (ctype_isstruct(sct->info)) { | ||
| 136 | CTSize ofs; | ||
| 137 | CType *fct = lj_ctype_getfield(cts, sct, name, &ofs); | ||
| 138 | if (fct && ctype_isconstval(fct->info)) | ||
| 139 | return fct; | ||
| 140 | } | ||
| 130 | } | 141 | } |
| 131 | { | 142 | { |
| 132 | GCstr *s = lj_ctype_repr(cts->L, ctype_typeid(cts, ct), NULL); | 143 | GCstr *s = lj_ctype_repr(cts->L, ctype_typeid(cts, ct), NULL); |
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 | } |
