aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-16 18:32:33 +0100
committerMike Pall <mike>2011-01-16 18:32:33 +0100
commit6f746577d087e39d72d9ce2bc61df27828c6422e (patch)
tree4575fd34dbd66f7cce2dd7ab6bf085432d1e0251 /src
parent0fa32e5d3128bbbfc2419a2bd158d5a72f2cd15b (diff)
downloadluajit-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.c11
-rw-r--r--src/lj_crecord.c16
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. */
378static 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 }