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 /src | |
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.
Diffstat (limited to 'src')
-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 | } |