[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cinvoke-dev] Re: Lua C/Invoke 64 bit return values [SOLVED]

From: Dwight Schauer
Subject: [cinvoke-dev] Re: Lua C/Invoke 64 bit return values [SOLVED]
Date: Tue, 4 Jan 2011 21:58:41 -0600

I found the problem.

typedef struct _ArchRetValue {
        int ivallow;
        int ivalhigh;
        double dval;
} ArchRetValue;

void arch_getval_extralong(ArchRetValue *archval, long long int *outval) {
        *outval = archval->ivalhigh;
        *outval <<= 32;
        *outval |= archval->ivallow;

Since ivallow is signed, if it is negative when shifted, then the
upper bits are all 1's.

I guess what is happening is that "archval->ivallow" is promoted from
int to long long int prior to the |= taking place.

In all my testing the the lower 32 bits happened to have the high bit set.

I changed ivallow from int to unsigned and that fixed this problem.

$ gcc -dumpmachine
$ gcc -dumpversion

Both cl_x86_win and gcc_x86_unix need to be fixed.

sed 's/int.ivallow/unsigned ivallow/' -i lib/arch/cl_x86_win.h
sed 's/int.ivallow/unsigned ivallow/' -i lib/arch/gcc_x86_unix.h

gcc_x86_unix is fine because the return value only uses one register,
rather than two (EAX and EDX).


On Tue, Jan 4, 2011 at 8:14 PM, Dwight Schauer <address@hidden> wrote:
> I'm using C/Invoke Lua and it is working out fairly well.
> I'm running into problems with 64 bit integers though on 32 bit
> platforms. It is not a C problem, as the underlying C code handles the
> 64 bit integers without any problem.
> I'm doing my testing on Linux x86_64 and Linux x86_32.
> I patched Lua to handle 64 integers cleanly, and that works fine on
> both 32 and 64 bit.
> I had to patch C/Invoke Lua as it was mangling 64 integers by using
> "number" routines rather than Lua "integer" routines.
> I have a crude sed patch for that here:
> I need to do a proper patch that uses "#ifdef LNUM_INT64" and
> conditionally compiles the appropriate code.
> On an unrelated note, I also patched _clibrary_get_function to allow
> an address to be passed in with @ as the first character of the
> symbol.
> On 64 bit I can use C/Invoke Lua to pass 64 bit integers into C
> functions, and have the C functions return 64 bit integers properly
> without mangling any of the bits.
> On 32 I can pass 64 bit integers without any problem from to C via
> C/Invoke, and they are not mangled.
> The problem on 32 bit is that I can't return 64 integers from C
> functions to Lua properly, only the lower 32 bits are returned.
> I've tried both Clonglong and Cint64, the results are the same.
> Any advice?
> I'm trying to keep all my code the same as much as possible on 32 and
> 64 bit platforms. With C I can do this, and with the patch for Lua I
> can do this, but now I'm running into problems with C/Invoke as far as
> this is concerned.
> I looked into this a bit in cinvoke_lua.c, but have not found the problem yet.
> At the top of unmarshall_retval I put in a printf and at that point 64
> bit returns are always already truncated (upper is all Fs).
> I also put a printf in _function_call right before the
> cinv_function_invoke call and the return type is correct, 4 indicating
> CINV_T_EXTRALONG. I looked at the all relevant cinvoke code for
> processing the return value and it all seems reasonable to me at a
> cursory glance.
> --DAS

reply via email to

[Prev in Thread] Current Thread [Next in Thread]