FFI: FFI-Callbacks-mt.6.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

FFI: FFI-Callbacks-mt.6.mcz

commits-2
Marcel Taeumel uploaded a new version of FFI-Callbacks to project FFI:
http://source.squeak.org/FFI/FFI-Callbacks-mt.6.mcz

==================== Summary ====================

Name: FFI-Callbacks-mt.6
Author: mt
Time: 1 May 2021, 8:27:57.27619 am
UUID: d17398f2-ff43-0945-aa04-e00bf7b6e0ae
Ancestors: FFI-Callbacks-mt.5

Adds register lookup for dynamic callback evaluation. Based on the assumption that a callback context is only used once per callback.

=============== Diff against FFI-Callbacks-mt.5 ===============

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 |
- | offset args |
- offset := 1.
- args := Array new: argumentTypes size.
 
+ 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 |
  argType := argumentTypes at: argIndex.
+
+ "1) Try to read arguments from registers."
+ data := (intPos < intArgs size and: [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]].
+
+ "2) If nothing was read, read the argument from the stack."
+ data ifNil: [
+ data := argType handle: handle at: byteOffset.
+ byteOffset := byteOffset
+ + ((type byteSize max: argType byteSize) roundUpTo: type byteAlignment)].
+
+ args at: argIndex put: data].
- data := argType handle: handle at: offset.
- args at: argIndex put: data.
 
- "Move the offset. Consider the byte-alignment?"
- offset := offset + ((type byteSize max: argType byteSize) roundUpTo: type byteSize)].
-
  ^ 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 size: 4.
+ callbackContext floatArguments size: 8.
- | intRegArgs floatRegArgs stackPtr |
- intRegArgs := callbackContext intRegArgs.
- intRegArgs size: 4.
- floatRegArgs := callbackContext floatRegArgs.
- floatRegArgs size: 8.
-
- stackPtr := callbackContext stackPtr.
-
- self assert: [argumentTypes size <= intRegArgs size].
-
- self setArgData: intRegArgs.
  ^ 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 size: 8.
+ callbackContext floatArguments size: 8.
-
- | intRegArgs floatRegArgs stackPtr |
- intRegArgs := callbackContext intRegArgs.
- intRegArgs size: 8.
- floatRegArgs := callbackContext floatRegArgs.
- floatRegArgs size: 8.
-
- stackPtr := callbackContext stackPtr.
-
- self assert: [argumentTypes size <= intRegArgs size].
-
- self setArgData: intRegArgs.
  ^ 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>
- <abi: 'IA32'> <evaluator>
 
+ callbackContext integerArguments size: 0.
+ callbackContext floatArguments size: 0.
- self setArgData: callbackContext stackPtr.
  ^ 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 size: 6.
+ callbackContext floatArguments size: 8.
- | intRegArgs floatRegArgs stackPtr |
- intRegArgs := callbackContext intRegArgs.
- intRegArgs size: 6.
- floatRegArgs := callbackContext floatRegArgs.
- floatRegArgs size: 8.
-
- stackPtr := callbackContext stackPtr.
-
- self assert: [argumentTypes size <= intRegArgs size].
-
- self setArgData: intRegArgs.
  ^ 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 size: 4.
+ callbackContext floatArguments size: 4.
-
- | intRegArgs floatRegArgs stackPtr |
- intRegArgs := callbackContext intRegArgs.
- intRegArgs size: 4.
- floatRegArgs := callbackContext floatRegArgs.
- floatRegArgs size: 4.
-
- stackPtr := callbackContext stackPtr.
-
- self assert: [argumentTypes size <= intRegArgs size].
-
- self setArgData: intRegArgs.
  ^ self evaluateDynamic: callbackContext!

Item was changed:
  ExternalStructure subclass: #FFICallbackContext
+ instanceVariableNames: 'floatArguments integerArguments'
- instanceVariableNames: ''
  classVariableNames: ''
  poolDictionaries: 'FFICallbackConstants'
  category: 'FFI-Callbacks'!
 
  !FFICallbackContext commentStamp: 'mt 4/30/2021 11:32' prior: 0!
  A callback context is a data structure prepared from the VM for accessing the callback's arguments. See FFICallback >> #thunkEntryAddress.
 
  !!!!!! BE AWARE that the actual location of argument values in this structure depend on the current ABI (i.e. 'Application Binary Interface'). See FFIPlatformDescription to access the current ABI.!

Item was added:
+ ----- Method: FFICallbackContext>>floatArguments (in category 'callback arguments') -----
+ floatArguments
+ "Cache proxy to the list of float arguments (i.e. an ExternalData) to attach ABI-specific properties such as #size."
+
+ ^ floatArguments ifNil: [
+ floatArguments := self floatRegArgs]!

Item was added:
+ ----- Method: FFICallbackContext>>integerArguments (in category 'callback arguments') -----
+ integerArguments
+ "Cache proxy to the list of integer arguments (i.e. an ExternalData) to attach ABI-specific properties such as #size."
+
+ ^ integerArguments ifNil: [
+ integerArguments := self intRegArgs]!