Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI:
http://source.squeak.org/FFI/FFI-Kernel-mt.95.mcz
==================== Summary ====================
Name: FFI-Kernel-mt.95
Author: mt
Time: 4 June 2020, 8:11:35.218031 pm
UUID: 2f408b53-dfca-3441-8577-e17174eacf91
Ancestors: FFI-Kernel-mt.94
Wow. FFI found its way into many other packages already. This fix is for MCMethodDefinition >> #postLoad. ;-)
=============== Diff against FFI-Kernel-mt.94 ===============
Item was changed:
----- Method: ExternalStructure class>>compileFields (in category 'field definition') -----
compileFields
"Compile the field definition of the receiver.
Return the newly compiled spec."
+ self isSkipped ifTrue: [^ self].
^self compileFields: self fields!
Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI:
http://source.squeak.org/FFI/FFI-Kernel-mt.94.mcz
==================== Summary ====================
Name: FFI-Kernel-mt.94
Author: mt
Time: 4 June 2020, 8:06:52.031031 pm
UUID: 8a7cb739-16a9-2f45-a875-5b5040d7453e
Ancestors: FFI-Kernel-mt.93
Update postscript to consider the #isSkipped mechanism when recompiling all structures.
=============== Diff against FFI-Kernel-mt.93 ===============
Item was changed:
(PackageInfo named: 'FFI-Kernel') postscript: 'Smalltalk removeFromStartUpList: ExternalAddress.
Smalltalk removeFromStartUpList: ExternalObject.
"Since #pointerSize in ExternalType is never nil anymore, make the code generated for fields more specific, i.e., #shortPointerAt:(put:) or #longPointerAt:(put:)."
+ ExternalType platformChangedFrom: nil to: nil.
+ ExternalStructure platformChangedFrom: nil to: nil.'!
- ExternalStructure withAllSubclassesDo: [:cls | cls defineFields].
- '!
Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI:
http://source.squeak.org/FFI/FFI-Kernel-mt.93.mcz
==================== Summary ====================
Name: FFI-Kernel-mt.93
Author: mt
Time: 4 June 2020, 7:50:57.117722 pm
UUID: 7f85e15e-756b-b142-a6e9-54ecdf13e97d
Ancestors: FFI-Kernel-mt.92
Fixes a regression from the previous commit. Not all subclasses of ExternalStructure have fields to be compiled. Mark that with #isSkipped, which is coherent with ExternalPool's #isSkipped.
Mark empty structure types, which are the ones where only the pointer should be used.
Fixes a bug (or regression?) in #doneCompiling. That is, support changing the base class from, e.g., Object to ExternalStructure.
=============== Diff against FFI-Kernel-mt.92 ===============
Item was added:
+ ----- Method: ExternalData class>>isSkipped (in category 'field definition') -----
+ isSkipped
+
+ ^ true!
Item was added:
+ ----- Method: ExternalPackedStructure class>>isSkipped (in category 'field definition') -----
+ isSkipped
+
+ ^ self == ExternalPackedStructure!
Item was changed:
----- Method: ExternalStructure class>>doneCompiling (in category 'class management') -----
doneCompiling
+
+ "Base class changed to something that is an external structure now."
+ self compiledSpec ifNil: [self compileFields].!
- "I have been recompiled. Update any types that reference me."
- ExternalType noticeModificationOf: self.!
Item was changed:
----- Method: ExternalStructure class>>fields (in category 'field definition') -----
fields
+ "Return the fields defining the receiver. By default, return an empty array, which means that only the pointer type of this external structure should be used."
+
- "Return the fields defining the receiver"
^#()!
Item was added:
+ ----- Method: ExternalStructure class>>isSkipped (in category 'field definition') -----
+ isSkipped
+
+ ^ self == ExternalStructure!
Item was changed:
----- Method: ExternalStructure class>>recompileStructures (in category 'system startup') -----
recompileStructures
"Check and update the layout of all subclasses for host machine dependency.
Arrange to check the inner nested structures first."
"ExternalStructure recompileStructures"
| sorted unsorted priorAuthorInitials |
+ unsorted := self withAllSubclasses reject: [:ea | ea isSkipped].
- unsorted := self withAllSubclasses.
sorted := OrderedCollection new: unsorted size.
self sortStructs: unsorted into: sorted.
priorAuthorInitials := Utilities authorInitialsPerSe.
Utilities setAuthorInitials: 'FFI'.
[sorted do: [:struct | struct checkFieldLayoutChange ifFalse: [
"Even if no layout change, communicate that result to the corresponding types."
struct externalType
compiledSpec: struct compiledSpec;
byteAlignment: struct byteAlignment]]]
ensure: [Utilities setAuthorInitials: priorAuthorInitials]!
Item was added:
+ ----- Method: ExternalType>>isEmptyStructureType (in category 'testing') -----
+ isEmptyStructureType
+ "Return true if the receiver represents a structure type"
+ ^ self isStructureType and: [self byteSize = 0]!
Item was changed:
----- Method: ExternalType>>printOn: (in category 'printing') -----
printOn: aStream
self isTypeAlias ifTrue: [
aStream
nextPutAll: referentClass name;
nextPut: $<;
print: self originalType;
nextPut: $>.
^ self].
self isAtomic
ifTrue: [aStream nextPutAll: (AtomicTypeNames at: self atomicType)]
ifFalse: [
referentClass == nil
ifTrue:[aStream nextPutAll: '<unknown struct type>']
+ ifFalse:[
+ aStream nextPutAll: referentClass name.
+ self isEmptyStructureType
+ ifTrue: [aStream nextPutAll: ' { void }']]].
- ifFalse:[aStream nextPutAll: referentClass name]].
self isPointerType ifTrue:[aStream nextPut: $*].!
Item was added:
+ ----- Method: ExternalTypeAlias class>>isSkipped (in category 'field definition') -----
+ isSkipped
+
+ ^ self == ExternalTypeAlias!
Item was added:
+ ----- Method: ExternalUnion class>>isSkipped (in category 'field definition') -----
+ isSkipped
+
+ ^ self == ExternalUnion!
Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI:
http://source.squeak.org/FFI/FFI-Kernel-mt.91.mcz
==================== Summary ====================
Name: FFI-Kernel-mt.91
Author: mt
Time: 4 June 2020, 5:49:29.568669 pm
UUID: 863883be-18f8-4945-a8e5-d138c32b50c4
Ancestors: FFI-Kernel-mt.90
Slightly refactor the process of updating external types and external structs when a platform change is detected.
1. Null (and maybe resize) all external addresses.
2. For all struct types, update pointer sizes and null struct sizes.
3. For all struct classes, look for definition changes and re-configure struct types in any case.
4. Update external pools.
Note that I pushed the field recompilatino code from ExternalObject down to ExternalStruct. Apologies if I overlooked update code for other external objects. There are none at the moment, or are there?
I tried to retain the identity of #compiledSpec in atomic types and struct types. Not sure whether this is necessary. Well, it is nice to have that identity check for #isTypeAlias and #originalType. :-)
=============== Diff against FFI-Kernel-mt.90 ===============
Item was removed:
- ----- Method: ExternalObject class>>install (in category 'system startup') -----
- install
- "Notify all instances of the receiver that we're coming up on a new platform.
- Note: The default implementation does nothing since the general external
- objects are cleaned up by ExternalAddress>>platformChangedFrom:to: but subclasses may
- implement this method so that the appropriate action for existing instances can
- be taken."!
Item was removed:
- ----- Method: ExternalObject class>>installSubclasses (in category 'system startup') -----
- installSubclasses
- "Notify all the subclasses of ExternalObject that we are starting up on a new platform."
- self withAllSubclassesDo:[:cls| cls install].!
Item was removed:
- ----- Method: ExternalObject class>>platformChangedFrom:to: (in category 'system startup') -----
- platformChangedFrom: lastPlatform to: currentPlatform
- "The system is coming up on a new platform. Clear out the existing handles."
- self installSubclasses.!
Item was removed:
- ----- 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."
-
- self recompileStructures.!
Item was added:
+ ----- Method: ExternalStructure class>>platformChangedFrom:to: (in category 'system startup') -----
+ platformChangedFrom: lastPlatform to: currentPlatform
+ "The system is coming up on a new platform. Clear out the existing handles."
+ self recompileStructures.!
Item was changed:
----- Method: ExternalStructure class>>recompileStructures (in category 'system startup') -----
recompileStructures
"Check and update the layout of all subclasses for host machine dependency.
Arrange to check the inner nested structures first."
"ExternalStructure recompileStructures"
| sorted unsorted priorAuthorInitials |
unsorted := self withAllSubclasses.
sorted := OrderedCollection new: unsorted size.
self sortStructs: unsorted into: sorted.
priorAuthorInitials := Utilities authorInitialsPerSe.
Utilities setAuthorInitials: 'FFI'.
+ [sorted do: [:struct | struct checkFieldLayoutChange ifFalse: [
+ "Even if no layout change, communicate that result to the corresponding types."
+ struct externalType
+ compiledSpec: struct compiledSpec;
+ byteAlignment: struct byteAlignment]]]
- [sorted do: [:e | e checkFieldLayoutChange]]
ensure: [Utilities setAuthorInitials: priorAuthorInitials]!
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-Squea…."
#(
"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."
('char' 10 1 1)
('schar' 11 1 1)
('float' 12 4 4)
('double' 13 8 8) "v.i."
"TODO: ('longdouble' 14 10 16? 4?)"
) 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"
+ type := (AtomicTypes at: typeName).
compiled := WordArray with: ((byteSize bitOr: FFIFlagAtomic) bitOr:
(atomicType bitShift: FFIAtomicTypeShift)).
+ compiled ~= type compiledSpec
+ "Preserve the identity of #compiledSpec."
+ ifTrue: [type compiledSpec: compiled].
+ type byteAlignment: byteAlignment.
- type := (AtomicTypes at: typeName).
- type
- compiledSpec: compiled;
- byteAlignment: byteAlignment.
"2) Pointer type"
+ type := type asPointerType.
compiled := WordArray with: ((self pointerSpec bitOr: FFIFlagAtomic) bitOr:
(atomicType bitShift: FFIAtomicTypeShift)).
+ compiled ~= type compiledSpec
+ "Preserve the identity of #compiledSpec."
+ ifTrue: [type compiledSpec: compiled].
+ type byteAlignment: self pointerAlignment.
- type asPointerType
- byteAlignment: self pointerAlignment;
- compiledSpec: compiled.
].!
Item was changed:
----- Method: ExternalType class>>initializeStructureTypes (in category 'class initialization') -----
initializeStructureTypes
+ "Reset all non-pointer struct types to zero and their pointer companions to the appropriate pointer size."
- "ExternalType initialize"
+ StructTypes valuesDo:[:structType |
+ structType "asNonPointerType"
+ compiledSpec: (WordArray with: self structureSpec);
+ byteAlignment: nil.
+ structType asPointerType
+ compiledSpec: (WordArray with: self pointerSpec);
+ byteAlignment: nil].!
- | referentClassOrNil |
- self cleanupUnusedTypes.
-
- StructTypes keysAndValuesDo:[:referentName :type |
- referentClassOrNil := (self environment classNamed: referentName)
- ifNotNil: [:cls | (cls includesBehavior: ExternalStructure) ifTrue: [cls]].
-
- self flag: #remove. "mt: Recompilation happens already via ExternalObject."
- referentClassOrNil ifNotNil: [referentClassOrNil compileFieldsSilently].
-
- type asNonPointerType
- newReferentClass: referentClassOrNil.
- type asPointerType
- newReferentClass: referentClassOrNil.
-
- ].!
Item was changed:
----- 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 cleanupUnusedTypes.
+
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."
+ { ExternalAddress. ExternalType. ExternalStructure. ExternalPool }
- { ExternalType. ExternalAddress. ExternalObject. ExternalPool }
do: [:cls | cls
platformChangedFrom: lastPlatform
to: currentPlatform] ]]] ].!
A new version of Kernel was added to project The Inbox:
http://source.squeak.org/inbox/Kernel-tonyg.1330.mcz
==================== Summary ====================
Name: Kernel-tonyg.1330
Author: tonyg
Time: 4 June 2020, 4:44:15.894747 pm
UUID: 76ade342-1acf-4780-8cda-610dba22bbec
Ancestors: Kernel-eem.1329
Repair a discrepancy between current Promise implementation and the Promises/A+ spec. (Bug reported by Jakob Reschke on squeak-dev, 5 April 2020)
=============== Diff against Kernel-eem.1329 ===============
Item was changed:
----- Method: Promise>>then:ifRejected: (in category 'monad') -----
then: resolvedBlock ifRejected: errBlock
"Return a Promise that, if it resolves, runs the resolvedBlock. If resolution throws an Exception, it runs the errBlock."
| p |
p := Promise new.
self whenResolved: [:v |
[p resolveWith: (resolvedBlock value: v)]
on: Error do: [:e | p rejectWith: e]].
+ self whenRejected: [:e |
+ [p resolveWith: (errBlock value: e)]
+ on: Error do: [:e2 | p rejectWith: e2]].
- self whenRejected: [:e | p rejectWith: (errBlock value: e)].
^ p.!