From c29ed4dbbf9089c6a7ba22c785e342c12862cbd8 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Sat, 5 Feb 2011 01:05:56 +0100 Subject: [PATCH] FFI: Record ffi.string(). --- src/lib_ffi.c | 16 ++++++++++------ src/lj_crecord.c | 17 +++++++++++++++++ src/lj_crecord.h | 2 ++ src/lj_ir.h | 3 ++- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 85a4e9c1..72128574 100644 --- a/src/lib_ffi.c +++ b/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; } diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 1223eb8e..80f00e18 100644 --- a/src/lj_crecord.c +++ b/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) diff --git a/src/lj_crecord.h b/src/lj_crecord.h index 3b2249c5..4ac5b3e2 100644 --- a/src/lj_crecord.h +++ b/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 diff --git a/src/lj_ir.h b/src/lj_ir.h index bde0ac04..bedb4c2b 100644 --- a/src/lj_ir.h +++ b/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