ThreadedFFIPlugins: See https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/443
FFI support for returning of a packed struct by value in X64 SysV
On X64/SysV struct up to 16 byte long can be passed by value into a pair of 8-byte registers. The problem is to know whether these are int (RAX RDX) or float (XMM0 XMM1) registers or eventually a mix of...
For each 8-byte, we must know if it contains at least an int (in which case we have to use an int register), or exclusively floating points (a pair of float or a double). Previous algorithm did check first two fields, or last two fields which does not correctly cover all cases... For example int-int-float has last two fields int-float, though it will use RAX XMM0.
So we have to know about struct layout... Unfortunately, this information is not included into the compiledSpec. The idea here is to reconstruct the information. See #registerTypeForStructSpecs:OfLength:
It's also impossible to cover the exotic alignments like packed structure cases... But if we really want to pass that, this will mean passing the alignment information, a more involved change of #compiledSpec (we need up to 16 bits by field to handle that information since our FFI struct are limited to 65535 bytes anyway).
For returning a struct, that's the same problem. We have four possible combinations of int-float registers. Consequently, the idea is to analyze the ffiRetSpec compiledSpec object thru CalloutState (it's the Smalltalk WordArray object, not a pointer to its firstIndexableField) for performing this analysis... Not sure if the best choice.
Since we have 4 different SixteenByte types, I have changed value, since it's what will be used to memcpy to allocated ByteArray handle.
Checking the size of a struct is not the only condition for returning a struct via registers. Some ABI like X64 SysV also mandates that struct fields be properly aligned. Therefore, we cannot just rely on #returnStructInRegisters:.
Perform a more thorough analysis during the setup in #ffiCheckReturn:With:in: The ABI will #encodeStructReturnTypeIn: a new callout state. This structReturnType is telling how the struct should be returned - via registers (and which registers) - or via pointer to memory allocated by caller
This structReturnType will be used at time of: - allocating the memory in caller - see #ffiCall:ArgArrayOrNil:NumArgs: - dispatching to the correct FFI prototype - see ThreadedX64SysVFFIPlugin>>#ffiCalloutTo:SpecOnStack:in: - copying back the struct contents to ExternalStructure handle (a ByteArray) - see #ffiReturnStruct:ofType:in:
Since structReturnType is encoded, it is not necessarily accessed directly, but rather via new implementation of #returnStructInRegisters: whch now takes the calloutState and knows how to decode its structReturnType.
Check for unaligned struct and pass them in MEMORY (alloca'd memory passed thru a pointer).
Use a new (branchless) formulation for aligning the byteSize to next multiple of fieldAlignment.
Encode registryType of invalid unaligned candidate as 2r110, and pass the struct address returned by the foreign function in $RAX register in place of callout limit when stuct is returned by MEMORY.
CoInterpreter: eliminate all but one compiler warning.
Cogit/Slang: fix several C compiler warnings re the Cogits.
Cogit: DUAL_MAPPED_CODE_ZONE (require -DDUAL_MAPPED_CODE_ZONE=1 to enable)
Fix denial of write/execute facility on modern Linuxes by dual mapping the code zone in to a read/execute address range for code execution and a read/write address range for code editing. Maintain codeToDataDelta and provide codeXXXAt:put: to write at address + codeToDataDelta to the offset writable address range.
Hence DUAL_MAPPED_CODE_ZONE requires a new executbale permissions applyer that will also do the dual mapping, sqMakeMemoryExecutableFrom:To:CodeToDataDelta:.
Provide writableMethodFor: as a convenience for obtaining a writable cogMethod.
No longer have the fillInXXXHeaderYYY: methods answer anything since they're given the writable header, not the actual header.
Cogit: Refactor indexForSelector:in:at: to indexForSelector:in: in the back end so it can be inlined (via a macro).
Slang: emit constant for (M << N) and (M - N) - L for constant integers. Fix in slang case statement expansion labels.
During expansion in case statements, trees are duplicated and expanded.
Want to know about upcoming build environment updates?
Would you like to stay up-to-date with the upcoming Travis CI build environment updates? We set up a mailing list for you!