From fbcc925a2d0f64e352d359626c1cb410b2cb5883 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Wed, 15 Dec 2010 19:47:01 +0100 Subject: [PATCH] FFI: Fix auto-deref of pointers to structs. --- src/lj_cdata.c | 12 +++++------- src/lj_crecord.c | 12 ++++++++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 29380cbc..a763908d 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c @@ -78,6 +78,7 @@ CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, uint8_t **pp, ct = ctype_child(cts, ct); } +collect_attrib: /* Skip attributes and collect qualifiers. */ while (ctype_isattrib(ct->info)) { if (ctype_attrib(ct->info) == CTA_QUAL) *qual |= ct->size; @@ -102,17 +103,14 @@ CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, uint8_t **pp, } else if (tvisstr(key)) { /* String key. */ GCstr *name = strV(key); if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */ - CType *cct = ctype_child(cts, ct); - if (ctype_isstruct(cct->info)) { + if (ctype_isstruct(ctype_rawchild(cts, ct)->info)) { p = (uint8_t *)cdata_getptr(p, ct->size); - ct = cct; - goto index_struct; + ct = ctype_child(cts, ct); + goto collect_attrib; } } if (ctype_isstruct(ct->info)) { CTSize ofs; - CType *fct; - index_struct: - fct = lj_ctype_getfield(cts, ct, name, &ofs); + CType *fct = lj_ctype_getfield(cts, ct, name, &ofs); if (fct) { *pp = p + ofs; return fct; diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 0d8c02a5..3ee39ece 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -363,9 +363,17 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) GCstr *name = strV(&rd->argv[1]); /* Always specialize to the field name. */ emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name)); - if (ctype_isstruct(ct->info)) { + if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */ + CType *cct = ctype_rawchild(cts, ct); + if (ctype_isstruct(cct->info)) { + ct = cct; + goto index_struct; + } + } else if (ctype_isstruct(ct->info)) { CTSize fofs; - CType *fct = lj_ctype_getfield(cts, ct, name, &fofs); + CType *fct; +index_struct: + fct = lj_ctype_getfield(cts, ct, name, &fofs); if (fct) { if (ctype_isconstval(fct->info)) { if (fct->size >= 0x80000000u &&