Commits

Anonymous committed 887dae2 Merge

merge default into branch

  • Participants
  • Parent commits 97ac078, 40049c1
  • Branches windows

Comments (0)

Files changed (5)

File c/_cffi_backend.c

         }
         assert(cf == NULL);
 
-#ifdef USE_C_LIBFFI_MSVC
-        /* MSVC returns small structures in registers.  Pretend int32 or
-           int64 return type.  This is needed as a workaround for what
-           is really a bug of libffi_msvc seen as an independent library
-           (ctypes has a similar workaround). */
-        if (is_result_type) {
-            if (ct->ct_size <= 4)
-                return &ffi_type_sint32;
-            if (ct->ct_size <= 8)
-                return &ffi_type_sint64;
-        }
-#endif
-
         /* next, allocate and fill the flattened list */
         elements = fb_alloc(fb, (nflat + 1) * sizeof(ffi_type*));
         nflat = 0;

File c/libffi_msvc/ffi.c

   register ffi_type **p_arg;
 
   argp = stack;
-  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
+  if (ecif->cif->flags == FFI_TYPE_STRUCT)
     {
       *(void **) argp = ecif->rvalue;
       argp += sizeof(void *);
 	      FFI_ASSERT(0);
 	    }
 	}
+#ifdef _WIN64
+      else if (z > 8)
+        {
+          /* On Win64, if a single argument takes more than 8 bytes,
+             then it is always passed by reference. */
+          *(void **)argp = *p_argv;
+          z = 8;
+        }
+#endif
       else
 	{
 	  memcpy(argp, *p_argv, z);
   switch (cif->rtype->type)
     {
     case FFI_TYPE_VOID:
-    case FFI_TYPE_STRUCT:
     case FFI_TYPE_SINT64:
     case FFI_TYPE_FLOAT:
     case FFI_TYPE_DOUBLE:
       cif->flags = (unsigned) cif->rtype->type;
       break;
 
+    case FFI_TYPE_STRUCT:
+      /* MSVC returns small structures in registers.  Put in cif->flags
+         the value FFI_TYPE_STRUCT only if the structure is big enough;
+         otherwise, put the 4- or 8-bytes integer type. */
+      if (cif->rtype->size <= 4)
+        cif->flags = FFI_TYPE_INT;
+      else if (cif->rtype->size <= 8)
+        cif->flags = FFI_TYPE_SINT64;
+      else
+        cif->flags = FFI_TYPE_STRUCT;
+      break;
+
     case FFI_TYPE_UINT64:
 #ifdef _WIN64
     case FFI_TYPE_POINTER:
   /* value address then we need to make one		        */
 
   if ((rvalue == NULL) && 
-      (cif->rtype->type == FFI_TYPE_STRUCT))
+      (cif->flags == FFI_TYPE_STRUCT))
     {
       /*@-sysunrecog@*/
       ecif.rvalue = alloca(cif->rtype->size);
 
   argp = stack;
 
-  if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
+  if ( cif->flags == FFI_TYPE_STRUCT ) {
     *rvalue = *(void **) argp;
     argp += 4;
   }

File c/libffi_msvc/prep_cif.c

 #if !defined M68K && !defined __x86_64__ && !defined S390
   /* Make space for the return structure pointer */
   if (cif->rtype->type == FFI_TYPE_STRUCT
-      /* MSVC returns small structures in registers.  But we have a different
-      workaround: pretend int32 or int64 return type, and converting to
-      structure afterwards. */
+#ifdef _WIN32
+      && (cif->rtype->size > 8)  /* MSVC returns small structs in registers */
+#endif
 #ifdef SPARC
       && (cif->abi != FFI_V9 || cif->rtype->size > 32)
 #endif

File c/libffi_msvc/win64.obj

Binary file added.
     libraries[:] = []
     _filenames = [filename.lower() for filename in os.listdir(COMPILE_LIBFFI)]
     _filenames = [filename for filename in _filenames
-                           if filename.endswith('.c') or
-                              filename.endswith('.asm')]
-    if sys.maxsize <= 2**32:
-        _filenames.remove('win64.asm')
-    else:
+                           if filename.endswith('.c')]
+    if sys.maxsize > 2**32:
+        # 64-bit: unlist win32.c, and add instead win64.obj.  If the obj
+        # happens to get outdated at some point in the future, you need to
+        # rebuild it manually from win64.asm.
         _filenames.remove('win32.c')
+        extra_link_args.append(os.path.join(COMPILE_LIBFFI, 'win64.obj'))
     sources.extend(os.path.join(COMPILE_LIBFFI, filename)
                    for filename in _filenames)
-    define_macros.append(('USE_C_LIBFFI_MSVC', '1'))
 else:
     use_pkg_config()