Browse Source

FFI: Support __tostring metamethod for pointers to structs, too.

Mike Pall 14 years ago
parent
commit
287de611a2
1 changed files with 14 additions and 9 deletions
  1. 14 9
      src/lib_ffi.c

+ 14 - 9
src/lib_ffi.c

@@ -273,7 +273,9 @@ LJLIB_CF(ffi_meta___tostring)
     msg = "ctype<%s>";
     id = *(CTypeID *)p;
   } else {
-    CType *ct = ctype_raw(ctype_cts(L), id);
+    CTState *cts = ctype_cts(L);
+    CType *ct = ctype_raw(cts, id);
+    if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
     if (ctype_iscomplex(ct->info)) {
       setstrV(L, L->top-1, lj_ctype_repr_complex(L, cdataptr(cd), ct->size));
       goto checkgc;
@@ -281,16 +283,19 @@ LJLIB_CF(ffi_meta___tostring)
       setstrV(L, L->top-1, lj_ctype_repr_int64(L, *(uint64_t *)cdataptr(cd),
 					       (ct->info & CTF_UNSIGNED)));
       goto checkgc;
-    } else if (ctype_isstruct(ct->info) || ctype_isvector(ct->info)) {
-      /* Handle ctype __tostring metamethod. */
-      CTState *cts = ctype_cts(L);
-      cTValue *tv = lj_ctype_meta(cts, id, MM_tostring);
-      if (tv)
-	return lj_meta_tailcall(L, tv);
-    } else if (ctype_isptr(ct->info)) {
-      p = cdata_getptr(p, ct->size);
     } else if (ctype_isfunc(ct->info)) {
       p = *(void **)p;
+    } else {
+      if (ctype_isptr(ct->info)) {
+	p = cdata_getptr(p, ct->size);
+	ct = ctype_rawchild(cts, ct);
+      }
+      if (ctype_isstruct(ct->info) || ctype_isvector(ct->info)) {
+	/* Handle ctype __tostring metamethod. */
+	cTValue *tv = lj_ctype_meta(cts, ctype_typeid(cts, ct), MM_tostring);
+	if (tv)
+	  return lj_meta_tailcall(L, tv);
+      }
     }
   }
   lj_str_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), p);