Jelajahi Sumber

FFI: Record ffi.string().

Mike Pall 14 tahun lalu
induk
melakukan
c29ed4dbbf
4 mengubah file dengan 31 tambahan dan 7 penghapusan
  1. 10 6
      src/lib_ffi.c
  2. 17 0
      src/lj_crecord.c
  3. 2 0
      src/lj_crecord.h
  4. 2 1
      src/lj_ir.h

+ 10 - 6
src/lib_ffi.c

@@ -425,17 +425,21 @@ LJLIB_CF(ffi_cast)
   return 1;
 }
 
-LJLIB_CF(ffi_string)
+LJLIB_CF(ffi_string)	LJLIB_REC(.)
 {
   CTState *cts = ctype_cts(L);
   TValue *o = lj_lib_checkany(L, 1);
-  size_t sz = (size_t)(CTSize)lj_lib_optint(L, 2, (int32_t)CTSIZE_INVALID);
-  CType *ct = ctype_get(cts, sz==CTSIZE_INVALID ? CTID_P_CVOID : CTID_P_CCHAR);
   const char *p;
+  size_t len;
+  if (o+1 < L->top) {
+    len = (size_t)lj_lib_checkint(L, 2);
+    lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o, 0);
+  } else {
+    lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o, 0);
+    len = strlen(p);
+  }
   L->top = o+1;  /* Make sure this is the last item on the stack. */
-  lj_cconv_ct_tv(cts, ct, (uint8_t *)&p, o, 0);
-  if (sz == CTSIZE_INVALID) sz = strlen(p);
-  setstrV(L, o, lj_str_new(L, p, sz));
+  setstrV(L, o, lj_str_new(L, p, len));
   lj_gc_check(L);
   return 1;
 }

+ 17 - 0
src/lj_crecord.c

@@ -844,6 +844,23 @@ void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd)
   crec_alloc(J, rd, argv2ctype(J, J->base[0], &rd->argv[0]));
 }
 
+void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd)
+{
+  CTState *cts = ctype_ctsG(J2G(J));
+  TRef tr = J->base[0];
+  if (tr) {
+    TRef trlen = J->base[1];
+    if (trlen) {
+      trlen = lj_ir_toint(J, trlen);
+      tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, tr, &rd->argv[0]);
+    } else {
+      tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CCHAR), 0, tr, &rd->argv[0]);
+      trlen = lj_ir_call(J, IRCALL_strlen, tr);
+    }
+    J->base[0] = emitir(IRT(IR_SNEW, IRT_STR), tr, trlen);
+  }  /* else: interpreter will throw. */
+}
+
 /* -- Miscellaneous library functions ------------------------------------- */
 
 void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)

+ 2 - 0
src/lj_crecord.h

@@ -15,12 +15,14 @@ LJ_FUNC void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd);
+LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
 #else
 #define recff_cdata_index	recff_nyi
 #define recff_cdata_call	recff_nyi
 #define recff_cdata_arith	recff_nyi
 #define recff_ffi_new		recff_nyi
+#define recff_ffi_string	recff_nyi
 #endif
 
 #endif

+ 2 - 1
src/lj_ir.h

@@ -273,7 +273,8 @@ typedef struct CCallInfo {
   _(lj_carith_modi64,	ARG2_64,   N, I64, CCI_NOFPRCLOBBER) \
   _(lj_carith_modu64,	ARG2_64,   N, U64, CCI_NOFPRCLOBBER) \
   _(lj_carith_powi64,	ARG2_64,   N, I64, CCI_NOFPRCLOBBER) \
-  _(lj_carith_powu64,	ARG2_64,   N, U64, CCI_NOFPRCLOBBER)
+  _(lj_carith_powu64,	ARG2_64,   N, U64, CCI_NOFPRCLOBBER) \
+  _(strlen,		1,         N, INT, 0)
 #else
 #define IRCALLDEF_FFI(_)
 #endif