Quellcode durchsuchen

FFI: Treat function ctypes like pointers in comparisons.

Mike Pall vor 14 Jahren
Ursprung
Commit
d001d7b7ce
2 geänderte Dateien mit 10 neuen und 1 gelöschten Zeilen
  1. 6 1
      src/lj_carith.c
  2. 4 0
      src/lj_crecord.c

+ 6 - 1
src/lj_carith.c

@@ -35,11 +35,16 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca)
   for (i = 0; i < 2; i++, o++) {
     if (tviscdata(o)) {
       GCcdata *cd = cdataV(o);
-      CType *ct = ctype_raw(cts, (CTypeID)cd->typeid);
+      CTypeID id = (CTypeID)cd->typeid;
+      CType *ct = ctype_raw(cts, id);
       uint8_t *p = (uint8_t *)cdataptr(cd);
       if (ctype_isptr(ct->info)) {
 	p = (uint8_t *)cdata_getptr(p, ct->size);
 	if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
+      } else if (ctype_isfunc(ct->info)) {
+	p = (uint8_t *)*(void **)p;
+	ct = ctype_get(cts,
+	  lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
       }
       ca->ct[i] = ct;
       ca->p[i] = p;

+ 4 - 0
src/lj_crecord.c

@@ -969,6 +969,10 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
 	tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64);
 	lj_needsplit(J);
 	goto ok;
+      } else if (ctype_isfunc(ct->info)) {
+	tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
+	ct = ctype_get(cts,
+	  lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
       } else {
 	tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
       }