I encountered a number of issues:
- The mach exception handler code was PowerPC-specific. It needed some changes to work in i386, among them a non-trivial one which took me a while track down: when the exception handler thread receives a mach exception, it changes the program counter of the main Factor thread to the signal handler. However on x86, we also need to align the stack on a 16 byte boundary, since there is no guarantee this will be so when the exception occurs.
- The ABI is different. As I said above, the stack must be aligned before every procedure call, so I had to implement a new set of compiler backend operations to support Intel Macs.
- Getting the Objective C bridge working was the toughest of all. On PowerPC, any message returning a struct must be called with
objc_msgSend_stret. On Intel, structs 8 bytes and smaller are returned in registers. This took a while to pinpoint, since it would manifest as memory corruption and random lossage. Also, when calling a message which returns a struct larger than 8 bytes, Apple's convention is that the callee drops one of the arguments from the C stack. This is completely absurd. It took me ages to figure out what's going on; I finally caught on after studying the disassembly of several Cocoa methods and noticing that the last opcode was
RET 4and not
There are two issues I still have not fixed:
- While calling Objective C methods which return structs now works, methods defined in Factor which return structs do not. There are extra complications to handle here, all because of Apple's funky ABI.
- The mach exception handler does not report the faulting address anymore, so instead of "Data stack underflow" or similar you see a generic "Operating System Signal 11" error. I'm not sure what's going on here, since I barely understand the Mach code (I snarfed it from OpenMCL) and everything works fine on PowerPC.
Neither of these issues are major, so I'll probably release 0.83 with the Mac Intel port as-is, and fix the issues later.
In general, I hate how cruddy and convoluted the whole infrastructure around C is. Mac OS X on Intel seems particularly bad; I have no idea why Apple decided to screw up struct returns and make everything ten times more complicated than it has to be. And of course Mach continues to suck like it always has and always will.
On a final note, it would be nice if somebody volunteered to do Mac Intel binary packages for Factor. The process is trivial (
make clean macosx macosx.app macosx.dmg) and I do not actually own an Intel Mac, I just borrowed it for the purposes of doing the port.