[plt-dev] First patch for MzScheme on Win64/x86_64

From: Gabriel Cuvillier (gabriel.cuvillier at laposte.net)
Date: Wed Jan 13 10:22:29 EST 2010

Here is the patch that allows MzScheme to compile and run on 
Win64/x86_64 architecture, with Visual Studio 2005.

I made 'diff -Naur between the 'plt-4.2.3 folder from the source zip and 
my modified one (which I have cleaned up just before). the result is 
called win64.patch, and is attached to this email.

Here is an overview of the changes:

-> mzscheme/sconfig.h
+ Added a _WIN64 check to adjust SCHEME_PLATFORM_LIBRARY_SUBPATH, 
deactivate USE_MZ_SETJMP, and deactivate the JIT

-> mzscheme/mzjs86.c
+ Added a _WIN64 check to not generate scheme_mz_setjmp & 
scheme_mz_longjmp functions (since inline assembly is not possible with 
MSVC 64bits). maybe it could be better to use directly the USE_MZ_SETJMP 
define to enable/disable these functions

-> Solution & project files : mzscheme.sln, mzscheme.vcproj, 
libmzgc.vcproj, libmzsch.vcproj
+ Added the new platform 'x64' to solution & project files (with 
parameters copied from the Win32 platform)
+ In all configurations of this new platform (debug/release), added the 
/Wp64 switch (under Properties>C/C++>General)
+ In all configurations of this new platform (debug/release) removed the 
/MACHINE:I386 from command line of the Linker (under Linker\Command Line)
+ In libmzsch.vcproj, somes files from the new libffi have been added 
(win64.S and ffi64.c), which are included with the x64 platform and 
excluded from Win32 platform. The file win64.S is an assembly file which 
have a specific build rule (see later). The file win32.c have been 
excluded from the x64 platform (but still included with the win32 platform).

-> foreign\libffi_msvc\*
+ There is a lot of changes here, since I have replaced most of the 
files with the ones from the latest libffi version (3.0.9):
  - replaced: ffi.c, ffi.h, ffi_common.h, ffitarget.h, prep_cif.c, 
LICENSE, README, types.c, win32.S
  - added: win64.S, ffi64.c
  - skipped: fficonfig.h (since the configure script of libffi is not 
really MSVC aware, I kept the one from PLT since it was already ported 
for MSVC, and added a few lines from the newer one about the FFI_HIDDEN 
stuff).
  - no changes: win32.c
+ I made a small modification on the new ffi.h: a swith between 
X86_WIN32 and X86_WIN64 depending the the target platform (simply a 
_WIN64 check)

As you may have noticed, the file win64.S have been added to the 
solution, with a new build rule in the project. It is an assembly file 
specific for the win64 ABI and implements the convention ffi_call_win64. 
Since MSVC compiler does not handle inline assembly in C code, it is 
mandatory to use the Microsoft Assembler (ml64.exe) to generate this 
one. Hopefully the file have both gas syntax and ml64 syntax (switched 
by a #ifdef on _MSC_VER), plus a few #defines.

Since ML64 does not support neither preprocessor directives nor C style 
comments in assembly files, I kept only the assembly code with ml64 
syntax. For the #defines, I commented them in the file (using ml64 
syntax) and I passed them as /D parameters to the assembler command line 
(see the build rule for this file in the project). Well, this is a 
little bit dirty, but it works. Maybe there is room for improvement: try 
to take the original win64.S from libffi and see what you can do with.

-> foreign\foreign.c
+ Small modification to call the new FFI_WIN64 abi when necessary

-> mzscheme\scheme.h
+ Modified the OBJ_TO_LONG macro to support the "long long" syntax under 
_WIN64. Otherwise with the /Wp64 swith, the compiler was getting crazy 
on warnings (conversion from Scheme_Object* to long) since this macro is 
used everywhere..

A few remarks about what's remaining to be done:

!! Important !! I have found that now libffi have been updated to the 
latest version, the win32 build of MzScheme does still compile, but does 
not link anymore! It is because the new libffi have added a few assembly 
functions into Win32.S. Since the assembly code present in this file 
have been inlined manualy in C functions of win32.c for PLT, the new 
functions must be inlined too (we can't use the Microsoft Assembler for 
this one because there is only gas syntax). Anyway, this should not be 
too complicated to do.

+ Now the remaining problems are the conversion warnings:
  - conversion from 'size_t' to long or int(mostly calls to strlen ())
  - conversion from '__int64' to long or int (pointer arithmetic, for 
string manip and regex, stack manipulation, SCHEME_INT_VAL)
  - etc..., etc...

Just to give a try, I have used 'mzlonglong as a replacement for 'long 
when there is a warning. This typedef seems to work as a 
"cross-platform-architecture long" but hell! this kind of modification 
is propagating like a virus all over the code. Since I'm not sure about 
this, I have canceled these changes.

+ a small modification must be done in mzscheme\dynsrc, since the .bat 
files are using the -machine:X86 for the 'lib command.

+ Make the JIT work on LP64 architecture.

+ The tests result (quiet.ss) are quite good... until a crash happens in 
Section(modprot) in read.c. Some kind of unmarshaling problem with .zo 
data. I wasn't able to figure out why for now, but I suspect a 
conversion problem somewhere...

Anyway, I think the win64 port is on its way.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: win64.patch
URL: <http://lists.racket-lang.org/dev/archive/attachments/20100113/9a11bed4/attachment.ksh>

Posted on the dev mailing list.