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

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

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

Name: FFI-Kernel-mt.79
Author: mt
Time: 30 May 2020, 4:56:51.283231 pm
UUID: 2191ddfe-e9ae-844c-bf19-71cc0ab214dd
Ancestors: FFI-Kernel-mt.77

Fixes a bug with wrong byte alignment for double and longlong and ulonglong on 32-bit non-ARM Unix-based platforms.

Start documenting Squeak FFI's relationship to "int" and "long" with the flag #ffiLongVsInt. If you spot an implication somewhere, just put this flag in the code.

Because byte alignment is stored in atomic types, re-initialize those if the platform changed on image start up. This also affects structure types.

(Skip mt.78 because that number rests in our treated inbox for now.)

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

Item was changed:
  ----- Method: ExternalStructure class>>install (in category 'system startup') -----
  install
+ "Resume the system on a new platform. Recompile all structures to account for different word size etc."
- "Resume the system on a new platform. Recompile all structures to accound for different word size etc."
 
  self recompileStructures.!

Item was changed:
  ----- Method: ExternalType class>>initializeAtomicTypes (in category 'class initialization') -----
  initializeAtomicTypes
  "ExternalType initialize"
+
  | atomicType byteSize type typeName byteAlignment |
+ self flag: #ffiLongVsInt. "For a discussion about long vs. int see http://forum.world.st/Re-squeak-dev-64-bit-FFI-was-porting-Croquet-to-Squeak6-0-alpha-tp5113318.html."
+
  #(
  "name atomic id byte size byte alignment"
  ('void' 0 0 0)
  ('bool' 1 1 1)
  ('byte' 2 1 1)
  ('sbyte' 3 1 1)
  ('ushort' 4 2 2)
  ('short' 5 2 2)
+ "!!!!!!" ('ulong' 6 4 "!!!!!!" 4)
+ "!!!!!!" ('long' 7 4 "!!!!!!" 4)
+ ('ulonglong' 8 8 8) "v.i."
+ ('longlong' 9 8 8) "v.i."
- ('ulong' 6 4 4)
- ('long' 7 4 4)
- ('ulonglong' 8 8 8)
- ('longlong' 9 8 8)
  ('char' 10 1 1)
  ('schar' 11 1 1)
  ('float' 12 4 4)
+ ('double' 13 8 8) "v.i."
+ "TODO: ('longdouble' 14 10 16? 4?)"
- ('double' 13 8 8)
  ) do:[:typeSpec| | compiled |
  typeName := typeSpec first.
  atomicType := typeSpec second.
  byteSize := typeSpec third.
  byteAlignment := typeSpec fourth.
+
+ "0) On 32-bits Windows and MacOS, double and long long have an alignment of 8. But on 32-bit Linux, their alignment is 4. But not on a 32-bit Raspberry Pi OS."
+ (FFIPlatformDescription current wordSize = 4
+ and: [FFIPlatformDescription current isUnix
+ and: [FFIPlatformDescription current isARM not]]) ifTrue: [
+ (#('double' 'longlong' 'ulonglong') includes: typeName) ifTrue: [
+ byteAlignment := 4]].
+
+ "1) Regular type"
- "On 32 bits Windows and MacOS, double and long have an alignment of 8. But on Linux, their alignment is 4"
- (FFIPlatformDescription current wordSize = 4 and: [FFIPlatformDescription current isUnix]) ifTrue: [
- (#('double longlong ulonglong') includes: typeName) ifTrue: [
- byteAlignment := 4
- ]
- ].
  compiled := WordArray with: ((byteSize bitOr: FFIFlagAtomic) bitOr:
  (atomicType bitShift: FFIAtomicTypeShift)).
  type := (AtomicTypes at: typeName).
+ type
+ compiledSpec: compiled;
- type compiledSpec: compiled;
  byteAlignment: byteAlignment.
+
+ "2) Pointer type"
  compiled := WordArray with: ((self pointerSpec bitOr: FFIFlagAtomic) bitOr:
  (atomicType bitShift: FFIAtomicTypeShift)).
  type asPointerType
  byteAlignment: self pointerAlignment;
  compiledSpec: compiled.
  ].!

Item was added:
+ ----- Method: ExternalType class>>platformChangedFrom:to: (in category 'system startup') -----
+ platformChangedFrom: lastPlatform to: currentPlatform
+ "Byte size or byte alignment for atomic types might be different on the new platform."
+
+ self initializeAtomicTypes.
+ self initializeStructureTypes.!

Item was changed:
  ----- Method: FFIPlatformDescription class>>startUp: (in category 'system startup') -----
  startUp: resuming
  "Notify all FFI classes about platform changes."
 
  resuming ifTrue: [
  LastPlatform in: [:lastPlatform | self newCurrent in: [:currentPlatform |
  lastPlatform = currentPlatform
  ifTrue: [
  self flag: #discuss. "mt: Maybe add #platformResuming?"
  ExternalAddress allBeNull]
  ifFalse: [
  LastPlatform := currentPlatform. "Update now. See #current."
+ { ExternalType. ExternalAddress. ExternalObject. FFIExternalSharedPool }
- self flag: #discuss. "mt: Maybe directly call ExternalStructure?"
- { ExternalAddress. ExternalObject. FFIExternalSharedPool }
  do: [:cls | cls
  platformChangedFrom: lastPlatform
  to: currentPlatform] ]]] ].!