[squeak-dev] FFI: FFI-Kernel-mt.191.mcz
commits at source.squeak.org
commits at source.squeak.org
Mon Aug 9 16:50:43 UTC 2021
Marcel Taeumel uploaded a new version of FFI-Kernel to project FFI:
http://source.squeak.org/FFI/FFI-Kernel-mt.191.mcz
==================== Summary ====================
Name: FFI-Kernel-mt.191
Author: mt
Time: 9 August 2021, 6:50:42.395391 pm
UUID: 89175a32-7b5e-744d-ae32-06f23674d61d
Ancestors: FFI-Kernel-mt.190
Fixes several code-loading bugs around ExternalStructure.
#doneCompiling needs to recompile/redefine *all* fields. The entire hierarchy of ExternalStructure. Note that #doneCompiling is also currently the hook for loading the methods #fields or #originalTypeName via Monticello. We cannot know the effects of any changed field spec. Local re-compilation/re-definition will not do it.
Therefore, offer a simple way to ensure that re-compilation is only done once for multiple changed field spec. Rely on deferred UI messages. In a CI setting, #tryDefineAllFIelds might need to be called after loading the code. In an interactive setting, this won't be necessary because of the UI process.
=============== Diff against FFI-Kernel-mt.190 ===============
Item was changed:
----- Method: ExternalStructure class>>compileAllFields (in category 'system startup') -----
compileAllFields
"
ExternalStructure compileAllFields
"
| priorAuthorInitials fieldSpec |
priorAuthorInitials := Utilities authorInitialsPerSe.
[Utilities setAuthorInitials: 'FFI'.
self allStructuresInCompilationOrder do: [:structClass |
fieldSpec := structClass fields.
- self flag: #discuss. "mt: Why do we need that extra layout check? Performance gain is minimal..."
(structClass hasFieldLayoutChanged: fieldSpec)
+ ifTrue: [structClass compileFields: fieldSpec].
- ifTrue: [structClass compileFieldsSilently: fieldSpec].
- structClass externalType "asNonPointerType"
- compiledSpec: structClass compiledSpec;
- byteAlignment: structClass byteAlignment.
structClass organization removeEmptyCategories].
"Compilation of fields only needs external types temporarily. Non-weak references to external types are only in methods with FFI calls."
ExternalType cleanupUnusedTypes.
] ensure: [Utilities setAuthorInitials: priorAuthorInitials]!
Item was changed:
----- Method: ExternalStructure class>>compileFields: (in category 'field definition') -----
compileFields: fieldSpec
"Private. Use #compileFields."
+ self compileFields: fieldSpec withAccessors: #generated.
- self compileFieldsSilently: fieldSpec.
ExternalType noticeModificationOf: self.!
Item was removed:
- ----- Method: ExternalStructure class>>compileFieldsSilently: (in category 'field definition') -----
- compileFieldsSilently: fieldSpec
- "Private. Use #compileFields."
-
- self compileFields: fieldSpec withAccessors: #generated.!
Item was changed:
----- Method: ExternalStructure class>>defineAllFields (in category 'system startup') -----
defineAllFields
+ "
- "For convenience.
ExternalStructure defineAllFields
"
+ | priorAuthorInitials fieldSpec |
+ priorAuthorInitials := Utilities authorInitialsPerSe.
+ [Utilities setAuthorInitials: 'FFI'.
+
+ self allStructuresInCompilationOrder do: [:structClass |
+ fieldSpec := structClass fields.
+ (structClass hasFieldLayoutChanged: fieldSpec)
+ ifTrue: [structClass defineFields: fieldSpec].
+ structClass organization removeEmptyCategories].
+ "Compilation of fields only needs external types temporarily. Non-weak references to external types are only in methods with FFI calls."
+ ExternalType cleanupUnusedTypes.
+
+ ] ensure: [Utilities setAuthorInitials: priorAuthorInitials]!
- self allStructuresInCompilationOrder
- do: [:structClass |
- structClass defineFields.
- structClass organization removeEmptyCategories].!
Item was added:
+ ----- Method: ExternalStructure class>>defineFieldsSafely (in category 'field definition') -----
+ defineFieldsSafely
+
+ [self defineFields]
+ ifError: [:msg | Transcript showln: '[FFI] Field definition failed: ', msg].!
Item was changed:
----- Method: ExternalStructure class>>doneCompiling (in category 'class management') -----
doneCompiling
"Base class changed to something that is an external structure now."
self isSkipped ifTrue: [^ self].
+ self triggerDefineAllFields.!
- self compileFieldsSafely.
- self externalType becomeKnownTypeSafely.!
Item was changed:
----- Method: ExternalStructure class>>hasFieldLayoutChanged: (in category 'system startup') -----
hasFieldLayoutChanged: fieldSpec
"Answers whether all fields should be re-compiled (and hence accessors re-generated). This is useful at system startup time if a platform change was detected, which can influence alignment and size of pointers.
!!!!!! Note that this method depends on all referenced types to be checked for field-layout changes first !!!!!!"
+ | oldCompiledSpec oldByteAlignment result |
- | oldCompiledSpec oldByteAlignment |
(oldCompiledSpec := self compiledSpec) ifNil: [^ true].
(oldByteAlignment := self byteAlignment) ifNil: [^ true].
self compileFields: fieldSpec withAccessors: #never.
- self assert: [self isTypeAlias or: [oldCompiledSpec ~~ self compiledSpec]].
-
self flag: #bug. "mt: Changed type aliasing for pointers not noticed unless that alias hides a pointer type."
+ result := self isTypeAlias or: [oldCompiledSpec ~= self compiledSpec].
+
+ self
+ setCompiledSpec: oldCompiledSpec
+ byteAlignment: oldByteAlignment.
+
+ ^ result!
- [^ oldCompiledSpec ~= self compiledSpec]
- ensure: [
- self
- setCompiledSpec: oldCompiledSpec
- byteAlignment: oldByteAlignment]!
Item was changed:
----- Method: ExternalStructure class>>platformChangedFrom:to: (in category 'system startup') -----
platformChangedFrom: lastPlatform to: currentPlatform
+ "The system is coming up on a new platform. Compile all field specs and install them in the respective struct types. Also re-generate all struct-field accessors if necessary."
- "The system is coming up on a new platform. Compile all field specs and install them in the respective struct types."
+ self defineAllFields.!
- self compileAllFields.!
Item was added:
+ ----- Method: ExternalStructure class>>triggerDefineAllFields (in category 'field definition - deferred') -----
+ triggerDefineAllFields
+
+ self environment at: #'FFIDeferredTask_DefineAllFields' put: true.
+ Project current addDeferredUIMessage: [self tryDefineAllFields].!
Item was added:
+ ----- Method: ExternalStructure class>>tryDefineAllFields (in category 'field definition - deferred') -----
+ tryDefineAllFields
+
+ (self environment includesKey: #'FFIDeferredTask_DefineAllFields')
+ ifTrue: [self environment removeKey: #'FFIDeferredTask_DefineAllFields']
+ ifFalse: [^ self].
+
+ self defineAllFields.!
More information about the Squeak-dev
mailing list
|