From 2717623e3acbcd4270303a0445ddd66326bc6d97 Mon Sep 17 00:00:00 2001
From: Mike Pall <mike>
Date: Wed, 8 Aug 2012 21:01:36 +0200
Subject: FFI: Compile ffi.typeof(cdata).

Thanks to Robert G. Jakabosky.
---
 src/lib_ffi.c    |  4 ++--
 src/lj_crecord.c | 12 ++++++++++++
 src/lj_crecord.h |  2 ++
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/lib_ffi.c b/src/lib_ffi.c
index e0951c56..24a6625c 100644
--- a/src/lib_ffi.c
+++ b/src/lib_ffi.c
@@ -522,7 +522,7 @@ LJLIB_CF(ffi_cast)	LJLIB_REC(ffi_new)
   return 1;
 }
 
-LJLIB_CF(ffi_typeof)
+LJLIB_CF(ffi_typeof)	LJLIB_REC(.)
 {
   CTState *cts = ctype_cts(L);
   CTypeID id = ffi_checkctype(L, cts, L->base+1);
@@ -533,7 +533,7 @@ LJLIB_CF(ffi_typeof)
   return 1;
 }
 
-LJLIB_CF(ffi_istype)	LJLIB_REC(ffi_istype)
+LJLIB_CF(ffi_istype)	LJLIB_REC(.)
 {
   CTState *cts = ctype_cts(L);
   CTypeID id1 = ffi_checkctype(L, cts, NULL);
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index dbd0b83b..30d315d5 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -1316,6 +1316,18 @@ void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd)
   }  /* else: interpreter will throw. */
 }
 
+void LJ_FASTCALL recff_ffi_typeof(jit_State *J, RecordFFData *rd)
+{
+  if (tref_iscdata(J->base[0])) {
+    TRef trid = lj_ir_kint(J, argv2ctype(J, J->base[0], &rd->argv[0]));
+    J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA),
+			lj_ir_kint(J, CTID_CTYPEID), trid);
+  } else {
+    setfuncV(J->L, &J->errinfo, J->fn);
+    lj_trace_err_info(J, LJ_TRERR_NYIFFU);
+  }
+}
+
 void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd)
 {
   argv2ctype(J, J->base[0], &rd->argv[0]);
diff --git a/src/lj_crecord.h b/src/lj_crecord.h
index 0f93e145..c2a3758d 100644
--- a/src/lj_crecord.h
+++ b/src/lj_crecord.h
@@ -20,6 +20,7 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_errno(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd);
+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 lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
@@ -33,6 +34,7 @@ LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
 #define recff_ffi_string	recff_nyi
 #define recff_ffi_copy		recff_nyi
 #define recff_ffi_fill		recff_nyi
+#define recff_ffi_typeof	recff_nyi
 #define recff_ffi_istype	recff_nyi
 #define recff_ffi_abi		recff_nyi
 #endif
-- 
cgit v1.2.3-55-g6feb