]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
FFI: Convert io.* file handle to FILE * pointer (but as a void *).
authorMike Pall <mike>
Tue, 29 May 2012 10:08:21 +0000 (12:08 +0200)
committerMike Pall <mike>
Tue, 29 May 2012 10:09:18 +0000 (12:09 +0200)
doc/ext_ffi_semantics.html
src/lj_cconv.c
src/lj_crecord.c

index 304befa7746bbfe4dcd9385795a679850cddc184..72b465972923ee811d79bcbc3d0e0ac05053d7cd 100644 (file)
@@ -289,22 +289,24 @@ arguments to C&nbsp;calls:
 <tr class="odd separate">
 <td class="convin">nil</td><td class="convop"><tt>NULL</tt> &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
 <tr class="even">
-<td class="convin">userdata</td><td class="convop">userdata payload &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="odd">
 <td class="convin">lightuserdata</td><td class="convop">lightuserdata address &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="even separate">
-<td class="convin">string</td><td class="convop">match against <tt>enum</tt> constant</td><td class="convout"><tt>enum</tt></td></tr>
 <tr class="odd">
-<td class="convin">string</td><td class="convop">copy string data + zero-byte</td><td class="convout"><tt>int8_t[]</tt>, <tt>uint8_t[]</tt></td></tr>
+<td class="convin">userdata</td><td class="convop">userdata payload &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
 <tr class="even">
-<td class="convin">string</td><td class="convop">string data &rarr;</td><td class="convout"><tt>const char[]</tt></td></tr>
+<td class="convin">io.* file</td><td class="convop">get FILE * handle &rarr;</td><td class="convout"><tt>(void *)</tt></td></tr>
 <tr class="odd separate">
-<td class="convin">function</td><td class="convop"><a href="#callback">create callback</a> &rarr;</td><td class="convout">C function type</td></tr>
+<td class="convin">string</td><td class="convop">match against <tt>enum</tt> constant</td><td class="convout"><tt>enum</tt></td></tr>
+<tr class="even">
+<td class="convin">string</td><td class="convop">copy string data + zero-byte</td><td class="convout"><tt>int8_t[]</tt>, <tt>uint8_t[]</tt></td></tr>
+<tr class="odd">
+<td class="convin">string</td><td class="convop">string data &rarr;</td><td class="convout"><tt>const char[]</tt></td></tr>
 <tr class="even separate">
+<td class="convin">function</td><td class="convop"><a href="#callback">create callback</a> &rarr;</td><td class="convout">C function type</td></tr>
+<tr class="odd separate">
 <td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout">Array</td></tr>
-<tr class="odd">
+<tr class="even">
 <td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr>
-<tr class="even separate">
+<tr class="odd separate">
 <td class="convin">cdata</td><td class="convop">cdata payload &rarr;</td><td class="convout">C type</td></tr>
 </table>
 <p>
index 240a8d10d31a4c30b04fe950ba688b2bb0e66ad0..b09c0abeb1e5c74eac647183e929640bd2f44ef0 100644 (file)
@@ -603,7 +603,10 @@ void lj_cconv_ct_tv(CTState *cts, CType *d,
     tmpptr = (void *)0;
     flags |= CCF_FROMTV;
   } else if (tvisudata(o)) {
-    tmpptr = uddata(udataV(o));
+    GCudata *ud = udataV(o);
+    tmpptr = uddata(ud);
+    if (ud->udtype == UDTYPE_IO_FILE)
+      tmpptr = *(void **)tmpptr;
   } else if (tvislightud(o)) {
     tmpptr = lightudV(o);
   } else if (tvisfunc(o)) {
index 74d62d6cd5cbe359ac40c6e7bf52e3476f621eb2..268800e469c3e651eb7e36f18a2e14847f05be58 100644 (file)
@@ -385,7 +385,14 @@ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
   } else if (tref_isnil(sp)) {
     sp = lj_ir_kptr(J, NULL);
   } else if (tref_isudata(sp)) {
-    sp = emitir(IRT(IR_ADD, IRT_P32), sp, lj_ir_kint(J, sizeof(GCudata)));
+    GCudata *ud = udataV(sval);
+    if (ud->udtype == UDTYPE_IO_FILE) {
+      TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), sp, IRFL_UDATA_UDTYPE);
+      emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, UDTYPE_IO_FILE));
+      sp = emitir(IRT(IR_FLOAD, IRT_PTR), sp, IRFL_UDATA_FILE);
+    } else {
+      sp = emitir(IRT(IR_ADD, IRT_P32), sp, lj_ir_kint(J, sizeof(GCudata)));
+    }
   } else if (tref_isstr(sp)) {
     if (ctype_isenum(d->info)) {  /* Match string against enum constant. */
       GCstr *str = strV(sval);