Hi all,
I have practically solved https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/443 for passing/returning struct by value on X64SysV FFI. I still have a few cases of packed struct or union to handle, but I know how to handle them and finish the job. Practically, but not yet... There is an issue that I can't easily solve: slang inlining. The generated code works on fast VM, but not debug nor assert... It does not work because #ffiCalloutTo:SpecOnStack:in: is not inlined. Since it uses sender's alloca as stack pointer (where FFI argVector was marshalled), it obviously will mess the stack if not inlined! The code is not inlined because a sub-function sends a recursive message . Unfortunately I have to check struct alignment for correctly determining the type of 8-byte registers, and algorithm for checking struct alignment is recursive because we must first check alignment of sub-struct.... Having a recursive function should not be a problem, just don't inline it, but invoke it. Unfortunately, our strategy is to inline only sends that can be completely inlined (and recursively for every sub-send). So I'm currently blocked... I'd like to specify to not inquire further sends that explicitely refuse to be inlined, maybe in the unless block in checkForCompletenessIn: parseTree nodesDo: [:node| ...snip...] unless: [:node| node isSend and: [node selector == #cCode:inSmalltalk: or: [node explicitelyRefuseToBeInlined or: [aCodeGen isAssertSelector: node selector]]]]. Thoughts? |
H Nicolas, On Tue, Jan 28, 2020 at 2:55 PM Nicolas Cellier <[hidden email]> wrote:
What's the recursive function? That should be marked as not inalienable (<inline: #false>. And #ffiCalloutTo:SpecOnStack:in: should be marked as <inline: true> or <inline: #always>.
We could pair later on today or early (my time) tomorrow. Right now I'm busy with my day job and so can't spend significant time right now. Feel free to email me the change set to look at too.
_,,,^..^,,,_ best, Eliot |
Hi Eliot, it is in VMMaker inbox, The recursive method is #alignmentOfStructSpec:OfLength:StartingAt: called by #registerTypeForStructSpecs:#OfLength: called by #ffiCalloutTo: procAddr:in: The last one has <inline: true>. I had the idea to put an <inline: false> in #registerTypeForStructSpecs:#OfLength: but thought it didn't work (by stepping thru debugger)... But now that you say it, I rechecked the generated code and it worked, thanks! Le mer. 29 janv. 2020 à 00:14, Eliot Miranda <[hidden email]> a écrit :
|
On Tue, Jan 28, 2020 at 3:47 PM Nicolas Cellier <[hidden email]> wrote:
Cool!! BTW, on the issue of getting 32-bit results too. I think I'm right in thinking that provided one collects the result by virtue of having the relevant field in the struct typed as either float or double, then the data will get written to either xmm0low or xmm1low, depending on whether this is the first or second field of the struct. So then we can access the register and convert from 32 bits to 64-bits if required. i.e. we only need the four combinations of long x double, long x double for the struct, but if either of the fields is actually typed as float, we can fix up the result after the fact by reading the relevant field via the 32-bit accessor. So once we have the return struct loaded, to convert the 32-bit float result to a double for each field we would do something like union { float f; double d; } pun; memcpy(&pun,&retStruct.doubles[0],sizeof(double)); retStruct.doubles[0] = pun.f;
_,,,^..^,,,_ best, Eliot |
Free forum by Nabble | Edit this page |