Browse Source

FFI: Fix auto-deref of pointers to structs.

Mike Pall 14 years ago
parent
commit
fbcc925a2d
2 changed files with 15 additions and 9 deletions
  1. 5 7
      src/lj_cdata.c
  2. 10 2
      src/lj_crecord.c

+ 5 - 7
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;

+ 10 - 2
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 &&