Browse Source

FFI: Auto-detect __stdcall and fix up C function declarations.

Mike Pall 14 years ago
parent
commit
87a6c8a980
7 changed files with 1160 additions and 1123 deletions
  1. 2 1
      src/Makefile.dep
  2. 300 294
      src/buildvm_x64.h
  3. 462 456
      src/buildvm_x64win.h
  4. 6 0
      src/buildvm_x86.dasc
  5. 380 371
      src/buildvm_x86.h
  6. 9 1
      src/lj_ccall.c
  7. 1 0
      src/lj_ctype.h

+ 2 - 1
src/Makefile.dep

@@ -58,7 +58,8 @@ lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
  lj_bcdef.h
  lj_bcdef.h
 lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cconv.h lj_cdata.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cconv.h lj_cdata.h \
- lj_ccall.h
+ lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
+ lj_traceerr.h
 lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h
  lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h
 lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \

File diff suppressed because it is too large
+ 300 - 294
src/buildvm_x64.h


File diff suppressed because it is too large
+ 462 - 456
src/buildvm_x64win.h


+ 6 - 0
src/buildvm_x86.dasc

@@ -3428,6 +3428,9 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
   |  sub rsp, rax
   |  sub rsp, rax
   |.else
   |.else
   |  sub esp, CCSTATE->spadj
   |  sub esp, CCSTATE->spadj
+#if LJ_TARGET_WINDOWS
+  |  mov CCSTATE->spadj, esp
+#endif
   |.endif
   |.endif
   |
   |
   |  // Copy stack slots.
   |  // Copy stack slots.
@@ -3494,6 +3497,9 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
   |6:
   |6:
   |  fstp dword CCSTATE->fpr[0].f[0]
   |  fstp dword CCSTATE->fpr[0].f[0]
   |7:
   |7:
+#if LJ_TARGET_WINDOWS
+  |  sub CCSTATE->spadj, esp
+#endif
   |.endif
   |.endif
   |
   |
   |.if X64
   |.if X64

File diff suppressed because it is too large
+ 380 - 371
src/buildvm_x86.h


+ 9 - 1
src/lj_ccall.c

@@ -14,6 +14,7 @@
 #include "lj_cconv.h"
 #include "lj_cconv.h"
 #include "lj_cdata.h"
 #include "lj_cdata.h"
 #include "lj_ccall.h"
 #include "lj_ccall.h"
+#include "lj_trace.h"
 
 
 /* Target-specific handling of register arguments. */
 /* Target-specific handling of register arguments. */
 #if LJ_TARGET_X86
 #if LJ_TARGET_X86
@@ -127,7 +128,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
 #if LJ_TARGET_X86
 #if LJ_TARGET_X86
   /* x86 has several different calling conventions. */
   /* x86 has several different calling conventions. */
   cc->resx87 = 0;
   cc->resx87 = 0;
-  switch ((ct->info >> CTSHIFT_CCONV) & CTMASK_CCONV) {
+  switch (ctype_cconv(ct->info)) {
   case CTCC_FASTCALL: maxgpr = 2; break;
   case CTCC_FASTCALL: maxgpr = 2; break;
   case CTCC_THISCALL: maxgpr = 1; break;
   case CTCC_THISCALL: maxgpr = 1; break;
   default: maxgpr = 0; break;
   default: maxgpr = 0; break;
@@ -352,6 +353,13 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
     gcsteps = ccall_set_args(L, cts, ct, &cc);
     gcsteps = ccall_set_args(L, cts, ct, &cc);
     lj_vm_ffi_call(&cc);
     lj_vm_ffi_call(&cc);
     gcsteps += ccall_get_results(L, cts, ct, &cc, &ret);
     gcsteps += ccall_get_results(L, cts, ct, &cc, &ret);
+#if LJ_TARGET_X86 && LJ_ABI_WIN
+    /* Automatically detect __stdcall and fix up C function declaration. */
+    if (cc.spadj && ctype_cconv(ct->info) == CTCC_CDECL) {
+      CTF_INSERT(ct->info, CCONV, CTCC_STDCALL);
+      lj_trace_abort(G(L));
+    }
+#endif
     while (gcsteps-- > 0)
     while (gcsteps-- > 0)
       lj_gc_check(L);
       lj_gc_check(L);
     return ret;
     return ret;

+ 1 - 0
src/lj_ctype.h

@@ -173,6 +173,7 @@ typedef struct CTState {
 #define ctype_bitcsz(info)	(((info) >> CTSHIFT_BITCSZ) & CTMASK_BITCSZ)
 #define ctype_bitcsz(info)	(((info) >> CTSHIFT_BITCSZ) & CTMASK_BITCSZ)
 #define ctype_vsizeP(info)	(((info) >> CTSHIFT_VSIZEP) & CTMASK_VSIZEP)
 #define ctype_vsizeP(info)	(((info) >> CTSHIFT_VSIZEP) & CTMASK_VSIZEP)
 #define ctype_msizeP(info)	(((info) >> CTSHIFT_MSIZEP) & CTMASK_MSIZEP)
 #define ctype_msizeP(info)	(((info) >> CTSHIFT_MSIZEP) & CTMASK_MSIZEP)
+#define ctype_cconv(info)	(((info) >> CTSHIFT_CCONV) & CTMASK_CCONV)
 
 
 /* Simple type checks. */
 /* Simple type checks. */
 #define ctype_isnum(info)	(ctype_type((info)) == CT_NUM)
 #define ctype_isnum(info)	(ctype_type((info)) == CT_NUM)

Some files were not shown because too many files changed in this diff