Well, it seems I found the problem.

lexer.h, line 203 reads:

    union
    {
        d_int32 int32value;
        d_uns32 uns32value;
        d_int64 int64value;
        d_uns64 uns64value;
        ...
        ...
        ...
    };

While this optimization is neat, it does not produce correct code on Big Endian or Mixed Endian platforms.

If we write a value to int64value and read it from int32value, then it will be 0 always. This is because the int32value is always read if the upper 32 bits of the int64value is zero. And since a Big Endian platform reads the most significant bits/bytes first, they'll read the upper 32 bits, not the lower 32 bits.

lexer.c:1874; Lexer::number(Token *t) correctly writes n to t->uns64value. -But let's take parse.c:6384 - here token.uns32value is read, thus we'll get a zero, no matter which value was written by number(Token *).

In parse.c:6379 we would get a minus one always.

Looking for union-"tricks", I also found ...
stringtable.c:24 hash will not be the same value on Big Endian, Mixed Endian and Little Endian machines. To hash correctly, read one byte at a time, then use bit-shifting by 8 if another byte is to be read.

Reply via email to