Here is an initial attempt at a patch to make Chuck run on 64-bit architectures.
Mostly it only modifies chuck_instr.cpp and chuck_emit.cpp.
First I'll summarize the results so far and then describe the patches a little.
Result:
-------
This code seems to allow the Chuck VM to run on 64-bit platforms. I
haven't had 100% success with every computer I've tried it on, but I'm
able to run several test programs, with while loops. Function calls
seem to work, as do classes with member functions. I ran into
problems with the real-time audio, which I'll discuss below, however
time does seem to advance and using WvOut I'm able to generate a
seemingly good .wav file. I've only tested with SinOsc so far. Also,
I should note that the only code in chuck_instr.cpp that I have *not
touched* yet is the array stuff, which probably still has issues.
(Although, it seems I'm able to make int and float arrays okay, but I
would expect problems, seeing as the array types are based on byte
size.)
This has only been tested on Fedora and Ubuntu, it may work
differently on other platforms. (Particularly with other compilers if
I got the #ifdefs wrong for some particular case.)
Oh yes and the patches are generated against today's CVS.
Technical:
----------
The technique here is to change all the places that depend on byte
count or type assumptions and replace them with word sizes instead.
So, for example when the Reg_Push_Imm2 instruction is called, this no
longer for "floats", but for "types using 2 words". Correspondingly,
the emitter emits the 1-word instruction for floating-point values, so
Imm2 is only used for complex types.
So you'll see lots of replacements of things like "if ( ..
type->size==4)" with "if ( .. type->words()==1 )".
In general, word size is calculated by sizeof(type) / sizeof(long).
This is done in chuck_def.h, and a series of "wd_" macros are defined
similar to the "sz_" macros.
There is one special case where I couldn't see any alternative except
to use #ifdef, so I defined a macro called CK64BIT based on a few
common compiler macros used to define a 64-bit environment. This case
was for places that needed to agnostically refer to "some type" of a
particular word size. For example, lots of code referred to t_CKUINT
for a 1-word type and t_CKFLOAT for a 2-word type. This code didn't
actually need to know that it was a floating-point number, since it's
just copying memory from one place to another, but it needed a type of
the correct size. So I defined t_CK1WORD, t_CK2WORD, and t_CK4WORD
which are different depending on the architecture, and replaced
references of CKUINT to CK1WORD, and CKFLOAT to CK2WORD, etc.
Also, though arguably not necessary, there were also a lot of places
where CKUINT is used interchangeably with object pointers. I replaced
these with CKVOIDPTR. On both 32- and 64-bit architectures CKUINT and
CKVOIDPTR are the same size, but I thought it would be better to make
this more semantically accurate regardless.
Lastly there are a few places where a "zero" value is placed on the
stack. This was the only other place where I needed the CK64BIT
macro, which was to define some constants for the zero values, which
are of different sizes depending on the architecture. There was no
chuck_def.cpp to place these in so I stuck them in chuck_type.cpp
instead. Possibly memset() could be used here instead of using the
const values.
So, this was enough to get things running, but it seemed that if I
included a ugen in the test program Chuck would just hang. It turns
out this was some problem with RtAudio for ALSA, where snd_pcm_readn()
returns EPIPE indicating XRUN, but the XRUN flag is not set. I don't
know what the issue is, but I found that if snd_pcm_link() is not
called the problem doesn't occur, so I've included here a work-around
patch for now. I'm discussing this with Gary Scavone at the moment,
so hopefully we'll be able to fix it. (It occurs even with
RtAudio/STK 4.3.1, so he's interested in getting it working.) That
said, even with this patch it doesn't quite *sound* right. A sine
wave sounds all choppy and distorted, so it *might* have something to
do with RtAudio's byte swapping code, but I'm still investigating
this. The same script sent to a file with WvOut produces a good sine
wave, so it's certainly an RtAudio issue and not a deeper problem.
Finally, I was getting a segfault whenever an error message was
printed, and I think it's due to the handling of variable arguments in
the error handler, specifically the ap_list being used more than once
after va_start(), so I include here a separate patch for this issue.
....
So I've got to take a break from this now and do other things, because
this has been somewhat consuming me for a week. I found it an
interesting problem to solve, but the RtAudio issues are driving me
_crazy_. If anyone wants to try this patch and tell me how it goes,
I'd love to hear from you. I'll keep working on it eventually, but I
have to catch up now on other stuff.. :)
Steve