Browse Source

FFI: Always fall back to metamethods for cdata length/concat.

Thanks to Egor Skriptunoff.
Mike Pall 5 years ago
parent
commit
cc4bbec483
4 changed files with 6 additions and 14 deletions
  1. 1 1
      src/lib_ffi.c
  2. 1 10
      src/lj_carith.c
  3. 0 1
      src/lj_carith.h
  4. 4 2
      src/lj_crecord.c

+ 1 - 1
src/lib_ffi.c

@@ -193,7 +193,7 @@ LJLIB_CF(ffi_meta___eq)		LJLIB_REC(cdata_arith MM_eq)
 
 
 LJLIB_CF(ffi_meta___len)	LJLIB_REC(cdata_arith MM_len)
 LJLIB_CF(ffi_meta___len)	LJLIB_REC(cdata_arith MM_len)
 {
 {
-  return lj_carith_len(L);
+  return ffi_arith(L);
 }
 }
 
 
 LJLIB_CF(ffi_meta___lt)		LJLIB_REC(cdata_arith MM_lt)
 LJLIB_CF(ffi_meta___lt)		LJLIB_REC(cdata_arith MM_lt)

+ 1 - 10
src/lj_carith.c

@@ -263,7 +263,7 @@ int lj_carith_op(lua_State *L, MMS mm)
 {
 {
   CTState *cts = ctype_cts(L);
   CTState *cts = ctype_cts(L);
   CDArith ca;
   CDArith ca;
-  if (carith_checkarg(L, cts, &ca)) {
+  if (carith_checkarg(L, cts, &ca) && mm != MM_len && mm != MM_concat) {
     if (carith_int64(L, cts, &ca, mm) || carith_ptr(L, cts, &ca, mm)) {
     if (carith_int64(L, cts, &ca, mm) || carith_ptr(L, cts, &ca, mm)) {
       copyTV(L, &G(L)->tmptv2, L->top-1);  /* Remember for trace recorder. */
       copyTV(L, &G(L)->tmptv2, L->top-1);  /* Remember for trace recorder. */
       return 1;
       return 1;
@@ -272,15 +272,6 @@ int lj_carith_op(lua_State *L, MMS mm)
   return lj_carith_meta(L, cts, &ca, mm);
   return lj_carith_meta(L, cts, &ca, mm);
 }
 }
 
 
-/* No built-in functionality for length of cdata. */
-int lj_carith_len(lua_State *L)
-{
-  CTState *cts = ctype_cts(L);
-  CDArith ca;
-  carith_checkarg(L, cts, &ca);
-  return lj_carith_meta(L, cts, &ca, MM_len);
-}
-
 /* -- 64 bit integer arithmetic helpers ----------------------------------- */
 /* -- 64 bit integer arithmetic helpers ----------------------------------- */
 
 
 #if LJ_32 && LJ_HASJIT
 #if LJ_32 && LJ_HASJIT

+ 0 - 1
src/lj_carith.h

@@ -11,7 +11,6 @@
 #if LJ_HASFFI
 #if LJ_HASFFI
 
 
 LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
 LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
-LJ_FUNC int lj_carith_len(lua_State *L);
 
 
 #if LJ_32 && LJ_HASJIT
 #if LJ_32 && LJ_HASJIT
 LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k);
 LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k);

+ 4 - 2
src/lj_crecord.c

@@ -1443,8 +1443,10 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
   }
   }
   {
   {
     TRef tr;
     TRef tr;
-    if (!(tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) &&
-	!(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data)) &&
+    MMS mm = (MMS)rd->data;
+    if ((mm == MM_len || mm == MM_concat ||
+	 (!(tr = crec_arith_int64(J, sp, s, mm)) &&
+	  !(tr = crec_arith_ptr(J, sp, s, mm)))) &&
 	!(tr = crec_arith_meta(J, sp, s, cts, rd)))
 	!(tr = crec_arith_meta(J, sp, s, cts, rd)))
       return;
       return;
     J->base[0] = tr;
     J->base[0] = tr;