FFI: FFI-Kernel-mt.132.mcz

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

FFI: FFI-Kernel-mt.132.mcz

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

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

Name: FFI-Kernel-mt.132
Author: mt
Time: 5 May 2021, 6:05:28.168784 pm
UUID: 99688c3a-95e7-2a4f-abcc-de6aafa6cca0
Ancestors: FFI-Kernel-mt.131

Adds missing #pointerAt:put: to ExternalData, which might still be useful if you want to access "arrays" of pointers (e.g. char**) manually via void*.

pointers := (ExternalType typeNamed: 'void*') allocate: 20.
pointers at: 1. "answers ExternalAddress; NULL pointer"

Fixes an off-by-one issue in byte-array read-writer.

Make it possible to copy any external structure/data to object memory via #copy. That is, avoid having too many proxies to external memory, which bears the risk of double-free or memory leaks. One could actually allocate new external memory, but ... :-/

nums := ExternalType int32_t allocateExternal: 10.
local := nums copy.
nums free.
local explore.

Depending on the state of your memory, you might get some interesting numbers in this example. :-D See #zeroMemory.

=============== Diff against FFI-Kernel-mt.131 ===============

Item was added:
+ ----- Method: ByteArrayReadWriter>>copy (in category 'copying') -----
+ copy
+
+ ^ byteArray copyFrom: byteOffset + 1 to: byteOffset + byteSize !

Item was changed:
  ----- Method: ByteArrayReadWriter>>doesNotUnderstand: (in category 'system primitives') -----
  doesNotUnderstand: aMessage
 
  | selector args |
  selector := aMessage selector.
  args := aMessage arguments.
  args size caseOf: {
  [ 1 ] -> [ (selector endsWith: 'At:') ifTrue: [ args at: 1 put: args first  + byteOffset ] ].
  [ 2 ] -> [ (selector endsWith: 'length:')
  ifTrue: [
  args at: 1 put: args first + byteOffset.
+ (args first + args second - 1) > byteSize
- args first + args second > byteSize
  ifTrue: [self errorSubscriptBounds: args first + args second] ]
  ifFalse: [(selector endsWith: 'put:') ifTrue: [
  args at: 1 put: args first + byteOffset ]] ].
  [ 3 ] -> [ (selector endsWith: 'length:')
  ifTrue: [
  args at: 1 put: args first + byteOffset.
+ (args first + args third - 1) > byteSize
- args first + args third > byteSize
  ifTrue: [self errorSubscriptBounds: args first + args third]]]
  } otherwise: [].
  ^ aMessage sendTo: byteArray!

Item was changed:
  ----- Method: ExternalData>>copyFrom:to: (in category 'accessing') -----
  copyFrom: firstIndex to: lastIndex
 
+ ^ (self from: firstIndex to: lastIndex) copy!
- ^ (self from: firstIndex to: lastIndex) getExternalData!

Item was added:
+ ----- Method: ExternalData>>pointerAt: (in category 'accessing - pointers') -----
+ pointerAt: index
+
+ | byteOffset |
+ byteOffset := ((index - 1) * ExternalAddress wordSize) + 1.
+
+ self flag: #contentVsContainer. "mt: We should adjust this once we can support n-ary pointer types."
+ ^ handle pointerAt: byteOffset
+
+ "
+ self assert: [self contentType isPointerType].
+ ^ self at: index
+ "!

Item was added:
+ ----- Method: ExternalData>>pointerAt:put: (in category 'accessing - pointers') -----
+ pointerAt: index put: value
+
+ | byteOffset |
+ byteOffset := ((index - 1) * ExternalAddress wordSize) + 1.
+
+ self flag: #contentVsContainer. "mt: We should adjust this once we can support n-ary pointer types."
+ ^ handle pointerAt: byteOffset put: value
+
+ "
+ self assert: [self contentType isPointerType].
+ ^ self at: index put: value
+ "!

Item was added:
+ ----- Method: ExternalStructure>>postCopy (in category 'copying') -----
+ postCopy
+ "Copy external memory into object memory to not loose track of what to #free and what not. It's safer this way."
+
+ handle isExternalAddress
+ ifTrue: [handle := self asExternalData getExternalData getHandle]
+ ifFalse: [handle := handle copy. "Materializes byte-array read-writer section if any"].!