Forráskód Böngészése

FFI: Compile ffi.gc().

Mike Pall 13 éve
szülő
commit
0b55e05d06
3 módosított fájl, 29 hozzáadás és 17 törlés
  1. 1 1
      src/lib_ffi.c
  2. 27 16
      src/lj_crecord.c
  3. 1 0
      src/lj_crecord.h

+ 1 - 1
src/lib_ffi.c

@@ -762,7 +762,7 @@ LJLIB_CF(ffi_metatype)
 
 LJLIB_PUSH(top-7) LJLIB_SET(!)  /* Store reference to finalizer table. */
 
-LJLIB_CF(ffi_gc)
+LJLIB_CF(ffi_gc)	LJLIB_REC(.)
 {
   GCcdata *cd = ffi_checkcdata(L, 1);
   TValue *fin = lj_lib_checkany(L, 2);

+ 27 - 16
src/lj_crecord.c

@@ -862,6 +862,25 @@ again:
   }
 }
 
+/* Record setting a finalizer. */
+static void crec_finalizer(jit_State *J, TRef trcd, cTValue *fin)
+{
+  TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd);
+  TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4));
+  if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; }
+  if (tvisfunc(fin)) {
+    emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin)));
+    emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC));
+  } else if (tviscdata(fin)) {
+    emitir(IRT(IR_XSTORE, IRT_P32), trlo,
+	   lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA));
+    emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA));
+  } else {
+    lj_trace_err(J, LJ_TRERR_BADTYPE);
+  }
+  J->needsnap = 1;
+}
+
 /* Record cdata allocation. */
 static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
 {
@@ -955,22 +974,8 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
     }
     /* Handle __gc metamethod. */
     fin = lj_ctype_meta(cts, id, MM_gc);
-    if (fin) {
-      TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd);
-      TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4));
-      if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; }
-      if (tvisfunc(fin)) {
-	emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin)));
-	emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC));
-      } else if (tviscdata(fin)) {
-	emitir(IRT(IR_XSTORE, IRT_P32), trlo,
-	       lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA));
-	emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA));
-      } else {
-	lj_trace_err(J, LJ_TRERR_BADTYPE);
-      }
-      J->needsnap = 1;
-    }
+    if (fin)
+      crec_finalizer(J, trcd, fin);
   }
 }
 
@@ -1611,6 +1616,12 @@ void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd)
   J->base[0] = J->base[1] = J->base[2] = TREF_NIL;
 }
 
+void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd)
+{
+  argv2cdata(J, J->base[0], &rd->argv[0]);
+  crec_finalizer(J, J->base[0], &rd->argv[1]);
+}
+
 /* -- Miscellaneous library functions ------------------------------------- */
 
 void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)

+ 1 - 0
src/lj_crecord.h

@@ -24,6 +24,7 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_typeof(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd);
+LJ_FUNC void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
 #endif