FFI: FFI-Callbacks-mt.22.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.22.mcz

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

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

Name: FFI-Callbacks-mt.22
Author: mt
Time: 28 May 2021, 11:15:38.8907 am
UUID: ed814637-f5b8-294e-8838-559202cd3716
Ancestors: FFI-Callbacks-mt.21

Clean up and document GC interface for FFI callbacks. Use the managed version for bsearch and qsort because both are short-living.

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

Item was added:
+ ----- Method: BlockClosure>>gcSignature: (in category '*FFI-Callbacks') -----
+ gcSignature: signature
+
+ ^ FFICallback
+ gcSignature: signature
+ block: self!

Item was changed:
  ----- Method: CStandardLibrary>>bsearch:in:compare: (in category '*FFI-Callbacks') -----
  bsearch: key in: array compare: block
 
+ | result |
+ result := self
- | result callback |
- [result := self
  bsearch: key
  with: array
  with: array size
  with: array contentType byteSize
+ with: (self compare: array contentType through: block).
- with: (callback := self compare: array contentType through: block).
- ] ensure: [callback free].
  result
  setContentType: array contentType;
  setSize: 1.
  ^ result!

Item was changed:
  ----- Method: CStandardLibrary>>compare:through: (in category '*FFI-Callbacks') -----
  compare: contentType through: evaluable
  "Answers a callback for comparing the given contentType through the given evaluable, i.e., messages sends or blocks. Supports pointer types as contentType."
 
  <callback: int32_t (*)(const void*, const void*)>
 
  | argType signature |
  self assert: [evaluable numArgs = 2].
 
  argType := contentType isPointerType
  ifTrue: [(contentType asArrayType: nil)]
  ifFalse: [contentType].
 
  signature := ((thisContext method pragmaAt: #callback:) argumentAt: 1) copy.
  signature at: 2 put: argType asPointerType.
  signature at: 3 put: argType asPointerType.
 
+ ^ evaluable gcSignature: signature!
- ^ evaluable signature: signature!

Item was changed:
  ----- Method: CStandardLibrary>>qsort:compare: (in category '*FFI-Callbacks') -----
  qsort: array compare: block
+
+ ^ self
-
- | callback result |
- [result := self
  qsort: array
  with: array size
  with: array contentType byteSize
+ with: (self compare: array contentType through: block)!
- with: (callback := self compare: array contentType through: block).
- ] ensure: [callback free].
- ^ result!

Item was added:
+ ----- Method: FFICallback class>>gcMessage: (in category 'instance creation - managed') -----
+ gcMessage: message
+ "Like #message: but automatically free'd when message gets garbage collected. Thus, the callback holds only weakly to the message and the sender MUST take care of not loosing the reference as long as needed. BEWARE that any external library using a free'd NULL callback will most likely SEGFAULT."
+
+ ^ self newGC
+ setMessage: message;
+ yourself
+ !

Item was added:
+ ----- Method: FFICallback class>>gcSignature:block: (in category 'instance creation - managed') -----
+ gcSignature: signature "<String>" block: aBlock "<BlockClosure> ^<FFICallback>"
+ "Like #signature:block: but automatically free'd when aBlock gets garbage collected. Thus, the callback holds only weakly to aBlock and the sender MUST take care of not loosing the reference as long as needed. BEWARE that any external library using a free'd NULL callback will most likely SEGFAULT."
+
+ ^ self newGC
+ setBlock: aBlock
+ signature: signature;
+ yourself!

Item was added:
+ ----- Method: FFICallback class>>gcSignature:message: (in category 'instance creation - managed') -----
+ gcSignature: signature "<String>" message: message "<MessageSend> ^<FFICallback>"
+ "Like #signature:message: but automatically free'd when message gets garbage collected. Thus, the callback holds only weakly to the message and the sender MUST take care of not loosing the reference as long as needed. BEWARE that any external library using a free'd NULL callback will most likely SEGFAULT."
+
+ ^ self newGC
+ setMessage: message
+ signature: signature;
+ yourself!

Item was added:
+ ----- Method: FFICallback class>>lookupCallbackForEvaluable: (in category 'instance lookup') -----
+ lookupCallbackForEvaluable: evaluable
+ "For managed callbacks, you can lookup the callback instance through the evaluable object you take care of."
+
+ ^ EvaluableToCallbackMap at: evaluable ifAbsent: [nil]!

Item was changed:
  ----- Method: FFICallback class>>message: (in category 'instance creation') -----
  message: message "<MessageSend> ^<FFICallback>"
+ "Answers a new FFI callback for the given message (send). The callback signature will be looked up in the actual method's callback pragma."
+
  ^ self new
+ setMessage: message;
+ yourself
- setMessage: message
  !

Item was changed:
+ ----- Method: FFICallback class>>newGC (in category 'instance creation - managed') -----
- ----- Method: FFICallback class>>newGC (in category 'instance creation') -----
  newGC
 
  ^ self new beManaged; yourself!

Item was changed:
  ----- Method: FFICallback class>>signature:block: (in category 'instance creation') -----
+ signature: signature "<String | Array>" block: aBlock "<BlockClosure> ^<FFICallback>"
+ "Answers a new FFI callback for the given signature and block. The signature can have the form of a callback pragma, a list of type names, or a list of actual types. The first type is always the return type."
+
- signature: signature "<String>" block: aBlock "<BlockClosure> ^<FFICallback>"
  ^ self new
  setBlock: aBlock
+ signature: signature;
+ yourself!
- signature: signature!

Item was changed:
  ----- Method: FFICallback class>>signature:message: (in category 'instance creation') -----
+ signature: signature "<String | Array>" message: message "<MessageSend> ^<FFICallback>"
+ "Answers a new FFI callback for the given signature and message (send). The signature can have the form of a callback pragma, a list of type names, or a list of actual types. The first type is always the return type."
+
- signature: signature "<String>" message: message "<MessageSend> ^<FFICallback>"
  ^ self new
  setMessage: message
+ signature: signature;
+ yourself!
- signature: signature!