Re: Callbacks with floats

new topic     » goto parent     » topic index » view thread      » older message » newer message
petelomax said...

Note that Ihandle is effectively an atom, and Icallback() is just a call_back() wrapper. The thing is that on 32bit ih is just an address whereas posx and posy are passed as 32-bit floats and could in theory be converted via float32_to_atom(int_to_bytes(posx/y)), whereas on 64 bit, again ih is just an address (in rcx) but posx/y would be passed in xmm1/2 and they would end up with whatever garbage happened to be in rdx/r9. Unfortunately no extra type info is/can be specified in a call_back() call, and it is that specific fact which makes this a fundamentally unsolveable problem. Ultimately we cannot treat atom ih one way but atom posx another, cmiiw.

You're correct in that floats and ints are passed via different registers so either you'd receive garbage or, if there were ints after the floats, you'd read the later ints too early. And yes, from inside call_back() we just assume we're being passed ints (really uintptr_t) for each parameter. Internally there's no way to know the type coming in; this is something a compiler usually takes care of setting up based on a function signature.

petelomax said...

For sure, if I really really wanted to I could write a block of inline assembly and use the address of that as the callback instead of a call_back() result, but, yuk.

Agreed. Very yucky and not portable. It probably would work though. But you still have to specify type information somewhere.

petelomax said...

Update: Again, just double!-checking, there isn't any way to sort this out via something like define_c_func({},call_back(),{C_FLOAT/C_DOUBLE,...), is there?

I think you're barking up the right tree here. Speaking strictly for Euphoria's backend, it's possible to accommodate this but there are some caveats.

Add support for an optional sequence types={} parameter to call_back() that takes a matching number of C_ constants to specify the required type of each argument. This would currently only be possible on 64-bit and 32-bit CDECL callbacks since the 32-bit STDCALL callbacks uses a series of hard-coded 0-9 parameter functions. Although the CDECL function could probably be adapted to be a CDECL-or-STDCALL handler. We'd just have to store the routine pointer, type information, and calling convention alongside the function itself.

function myfunc( atom handle, atom posx, atom posy ) 
    return 0 
end function 
atom cb = call_back( routine_id("myfunc"), {C_POINTER,C_FLOAT,C_FLOAT} ) 

Or, we drop the custom-built internal callback handler altogether and move to something like libffi, which I've already considered to better support more platforms like 64-bit ARM and OS X on M1 (ARM). I'd still need to take the time to understand how libffi even works before I could begin integrating.


new topic     » goto parent     » topic index » view thread      » older message » newer message


Quick Links

User menu

Not signed in.

Misc Menu