FFI: FFI-Kernel-mt.136.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.136.mcz

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

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

Name: FFI-Kernel-mt.136
Author: mt
Time: 6 May 2021, 6:12:41.055981 pm
UUID: 21c0b95f-4fab-ca48-ae73-fcc01f01bdb4
Ancestors: FFI-Kernel-mt.135

Clean up #allocate interface on external types:
- Re-direct #new and #externalNew to make those messages available to domain-specific structs.
- Always zero allocated external memory for safe use through tools.
- Remove obsolete #newZero, which is rather new and was not yet used anywhere.

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

Item was added:
+ ----- Method: ExternalStructure class>>allocate (in category 'instance creation') -----
+ allocate
+
+ ^self externalType allocate!

Item was added:
+ ----- Method: ExternalStructure class>>allocateExternal (in category 'instance creation') -----
+ allocateExternal
+
+ ^ self externalType allocateExternal!

Item was changed:
  ----- Method: ExternalStructure class>>externalNew (in category 'instance creation') -----
  externalNew
  "Create an instance of the receiver on the external heap"
 
+ ^ self allocateExternal!
- ^ self fromHandle: (self externalType isTypeAliasForAtomic
- ifTrue: [self error: 'This is an alias-for-atomic type. You must use #fromHandle:']
- ifFalse: [
- self externalType isTypeAliasForPointer
- ifTrue: [ByteArray new: self byteSize]
- ifFalse: [ExternalAddress allocate: self byteSize]])!

Item was changed:
  ----- Method: ExternalStructure class>>new (in category 'instance creation') -----
  new
+
+ ^ self allocate!
- ^self fromHandle: (self externalType isTypeAliasForAtomic
- ifTrue: [self error: 'This is an alias-for-atomic type. You must use #fromHandle:']
- ifFalse: [ByteArray new: self byteSize]).!

Item was removed:
- ----- Method: ExternalStructure class>>newZero (in category 'instance creation') -----
- newZero
-
- ^ self new
- zeroMemory;
- yourself!

Item was changed:
  ----- Method: ExternalType>>allocate (in category 'external data') -----
  allocate
  "Allocate a single representative for this type."
 
- referentClass ifNotNil: [
- "Allocate bytes for the struct."
- ^ referentClass new].
-
  self isPointerType ifTrue: [
+ self flag: #workaround. "mt: Better support for multi-dimensional containers needed."
- "Allocate bytes for a pointer."
  ^ ExternalType void asPointerType allocate: 1].
 
+ ^ (self allocate: 1) first!
- "Answer an object representing the atomic type."
- self notYetImplemented.!

Item was changed:
  ----- Method: ExternalType>>allocate: (in category 'external data') -----
+ allocate: numElements
+ "Allocate space for containing an array of numElements of this dataType"
- allocate: anInteger
- "Allocate space for containing an array of size anInteger of this dataType"
 
  | handle |
  self
  assert: [self isPointerType not or: [self isVoid]]
  description: 'No support for n-dimensional containers. Allocate for void* as workaround.';
  assert: [self byteSize > 0]
  description: 'Invalid byte size.'.
 
+ handle := ByteArray new: self byteSize * numElements.
+ ^(ExternalData fromHandle: handle type: self) size: numElements!
- handle := ByteArray new: self byteSize * anInteger.
- ^(ExternalData fromHandle: handle type: self) size: anInteger!

Item was changed:
  ----- Method: ExternalType>>allocateExternal (in category 'external data') -----
  allocateExternal
+ "Allocate a single representative for this type in external memory."
- "Allocate a single representative for this type."
-
- referentClass ifNotNil: [
- "Allocate bytes for the struct."
- ^ referentClass externalNew].
 
+ | result |
  self isPointerType ifTrue: [
+ self flag: #workaround. "mt: Better support for multi-dimensional containers needed."
- "Allocate bytes for a pointer."
  ^ ExternalType void asPointerType allocateExternal: 1].
 
+ "By design, aliased pointers are stored as byte array."
+ self isTypeAliasForPointer ifTrue: [^ self allocate].
+
+ ^ [(result := self allocateExternal: 1) first]
+ ensure: [
+ "Atomics and alias-to-atomic are immediately available in object memory. We thus must free the external memory to avoid leaks."
+ self isStructureType ifFalse: [result free]]!
- "Answer an object representing the atomic type."
- self notYetImplemented.!

Item was changed:
  ----- Method: ExternalType>>allocateExternal: (in category 'external data') -----
+ allocateExternal: numElements
+ "Allocate space for containing an array of numElements of this type. Note that we zero the memory for safe use. If you do not need that, please use ExternalAddress class >> #allocate: directly. BE AWARE that structs can have pointers tools automatically follow and thus risking a SEGFAULT and hence VM CRASH for uninitalized memory."
- allocateExternal: anInteger
- "Allocate space for containing an array of size anInteger of this dataType"
 
  | handle |
  self
  assert: [self isPointerType not or: [self isVoid]]
  description: 'No support for n-dimensional containers. Allocate for void* as workaround.';
  assert: [self byteSize > 0]
  description: 'Invalid byte size.'.
 
+ handle := ExternalAddress allocate: self byteSize * numElements.
+ ^(ExternalData fromHandle: handle type: self)
+ size: numElements;
+ zeroMemory;
+ yourself!
- handle := ExternalAddress allocate: self byteSize * anInteger.
- ^(ExternalData fromHandle: handle type: self) size: anInteger!