Marcel Taeumel uploaded a new version of FFI-Callbacks to project FFI:
http://source.squeak.org/FFI/FFI-Callbacks-mt.11.mcz ==================== Summary ==================== Name: FFI-Callbacks-mt.11 Author: mt Time: 7 May 2021, 11:56:59.650725 am UUID: d9a23c73-af82-6246-89db-be73bb87615a Ancestors: FFI-Callbacks-mt.9 Complements FFI-Kernel-mt.140. =============== Diff against FFI-Callbacks-mt.9 =============== Item was changed: ----- Method: ExternalData class>>fromHandle:byteSize: (in category '*FFI-Callbacks') ----- + fromHandle: aHandle byteSize: numBytes + "Answer an instance that manages a number of unsigned bytes." + + ^ self + fromHandle: aHandle + type: ExternalType unsignedByte "content type" + size: numBytes! - fromHandle: aHandle byteSize: byteSize - ^ (self fromHandle: aHandle type: ExternalType unsignedByte asPointerType) - size: byteSize; - yourself! Item was changed: ----- Method: FFICallback>>evaluateDynamic: (in category 'callback - evaluators') ----- evaluateDynamic: callbackContext "Read all arguments and make the call(back). Assume that 'handle' and 'type' are set correctly. Only watch out for the sign. See field definition in FFICallbackContext to explore alternative ways to read the arguments." | byteOffset args intArgs intPos floatArgs floatPos | handle := callbackContext stackPtr getHandle. type := callbackContext stackPtr contentType. byteOffset := 1. intArgs := callbackContext integerArguments. intPos := 0. floatArgs := callbackContext floatArguments. floatPos := 0. args := Array new: argumentTypes size. 1 to: args size do: [:argIndex | | argType data isPointer | argType := argumentTypes at: argIndex. "1) Try to read arguments from registers." data := (intPos < intArgs size and: [(isPointer := argType isPointerType) or: [argType isIntegerType]]) ifTrue: [intPos := intPos + 1. intArgs at: intPos] ifFalse: [(floatPos < floatArgs size and: [argType isFloatType]) ifTrue: [floatPos := floatPos + 1. floatArgs at: floatPos]]. data ifNotNil: [ "1b) Materialize pointers from integers." isPointer ifTrue: [ self flag: #designSmell. "mt: If we had a way to set, for example, double** as container type and double* as content type for intArgs, we would not have to construct the correct external object here but already had it." self flag: #discuss. "mt: Should we resolve atomic types? That is, double* to an actual float object etc? Well, for pointers to external structures (unions, ...) it would make sense to provide an actual instance of that structure to the callback... If so, we just need to send #value below." data := (ExternalData fromHandle: (ExternalAddress fromInteger: data) + type: argType size: 1) "value"]] - type: argType) size: 1; "value; " yourself]] ifNil: [ "2) If nothing was read, read the argument from the stack." data := argType handle: handle at: byteOffset. byteOffset := byteOffset + ((type byteSize max: argType byteSize) roundUpTo: type byteAlignment)]. args at: argIndex put: data]. ^ self setResult: (evaluableObject valueWithArguments: args) inContext: callbackContext! Item was changed: ----- Method: FFICallback>>evaluateDynamic_ARM32: (in category 'callback - evaluators') ----- evaluateDynamic_ARM32: callbackContext "Set handle to access arguments as most appropriate for the ABI. For ''RISCs'' it is the pointer to the integer register." <abi: #ARM32> <evaluator> + callbackContext integerArguments setSize: 4. + callbackContext floatArguments setSize: 8. - callbackContext integerArguments size: 4. - callbackContext floatArguments size: 8. ^ self evaluateDynamic: callbackContext! Item was changed: ----- Method: FFICallback>>evaluateDynamic_ARM64: (in category 'callback - evaluators') ----- evaluateDynamic_ARM64: callbackContext "Set handle to access arguments as most appropriate for the ABI. ARMv8 with AArch64." <abi: #ARM64> <evaluator> + callbackContext integerArguments setSize: 8. + callbackContext floatArguments setSize: 8. - callbackContext integerArguments size: 8. - callbackContext floatArguments size: 8. ^ self evaluateDynamic: callbackContext! Item was changed: ----- Method: FFICallback>>evaluateDynamic_IA32: (in category 'callback - evaluators') ----- evaluateDynamic_IA32: callbackContext "Set handle to access arguments as most appropriate for the ABI. For x86 (i.e. IA32) it is the stack pointer." <abi: #IA32> <evaluator> + callbackContext integerArguments setSize: 0. + callbackContext floatArguments setSize: 0. - callbackContext integerArguments size: 0. - callbackContext floatArguments size: 0. ^ self evaluateDynamic: callbackContext! Item was changed: ----- Method: FFICallback>>evaluateDynamic_X64: (in category 'callback - evaluators') ----- evaluateDynamic_X64: callbackContext "Set handle to access arguments as most appropriate for the ABI. For ''RISCs'' it is the pointer to the integer register." <abi: #X64> <evaluator> + callbackContext integerArguments setSize: 6. + callbackContext floatArguments setSize: 8. - callbackContext integerArguments size: 6. - callbackContext floatArguments size: 8. ^ self evaluateDynamic: callbackContext! Item was changed: ----- Method: FFICallback>>evaluateDynamic_X64Win64: (in category 'callback - evaluators') ----- evaluateDynamic_X64Win64: callbackContext "Set handle to access arguments as most appropriate for the ABI. For ''RISCs'' it is the pointer to the integer register." <abi: #X64Win64> <evaluator> + callbackContext integerArguments setSize: 4. + callbackContext floatArguments setSize: 4. - callbackContext integerArguments size: 4. - callbackContext floatArguments size: 4. ^ self evaluateDynamic: callbackContext! Item was changed: ----- Method: FFICallbackMemory>>addressFieldPut: (in category 'alien compatibility') ----- addressFieldPut: value "<Integer> ^<Integer>" <primitive: 'primAddressFieldPut' module: 'IA32ABI' error: errorCode> self notify: 'Primitive failed. Proceed to use fallback code.'. ^ (ExternalData fromHandle: self type: ExternalType uintptr_t) + at: ExternalAddress wordSize "Alien size prefix bytes" + 1 "Start of pointer address" - at: ExternalData wordSize + 1 put: value! |
Free forum by Nabble | Edit this page |