FFI: FFI-Pools-monty.6.mcz

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

FFI: FFI-Pools-monty.6.mcz

commits-2
Marcel Taeumel uploaded a new version of FFI-Pools to project FFI:
http://source.squeak.org/FFI/FFI-Pools-monty.6.mcz

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

Name: FFI-Pools-monty.6
Author: monty
Time: 29 March 2018, 4:08:57.771498 am
UUID: 30ba575f-ea24-0d00-8ca3-7a300bae9894
Ancestors: FFI-Pools-monty.5

use #compilerClass for Squeak compatibility

=============== Diff against FFI-Pools-TorstenBergmann.4 ===============

Item was added:
+ ----- Method: Boolean class>>ffiSharedPoolGenerateOutputCodeFor:with: (in category '*FFI-Pools') -----
+ ffiSharedPoolGenerateOutputCodeFor: aPoolVariableName with: aProgramGenerator
+ aProgramGenerator emitBooleanOutputCodeFor: aPoolVariableName!

Item was added:
+ ----- Method: Character class>>ffiSharedPoolGenerateOutputCodeFor:with: (in category '*FFI-Pools') -----
+ ffiSharedPoolGenerateOutputCodeFor: aPoolVariableName with: aProgramGenerator
+ aProgramGenerator emitCharacterOutputCodeFor: aPoolVariableName!

Item was added:
+ ----- Method: Class>>asFFISharedPoolType (in category '*FFI-Pools') -----
+ asFFISharedPoolType
+ ^ self!

Item was added:
+ SharedPool subclass: #FFISharedPool
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'FFI-Pools'!
+ FFISharedPool class
+ instanceVariableNames: 'lastPlatform'!
+
+ !FFISharedPool commentStamp: 'monty 3/25/2018 03:57' prior: 0!
+ This is a base class for FFI SharedPools that use the output of automatically generated C programs to initialize their pool variables.!
+ FFISharedPool class
+ instanceVariableNames: 'lastPlatform'!

Item was added:
+ ----- Method: FFISharedPool class>>compileGeneratedSourceFile:to:forDefinition: (in category 'private') -----
+ compileGeneratedSourceFile: aSourcePathString to: aProgramPathString forDefinition: aDefinition
+ self
+ executeExternalCommand: '{1} {2} {3} {4}'
+ format:
+ {aDefinition cCompiler.
+ aDefinition cFlags.
+ aProgramPathString.
+ aSourcePathString}
+ description: 'compile generated source code'!

Item was added:
+ ----- Method: FFISharedPool class>>definitions (in category 'accessing') -----
+ definitions
+ | definitions |
+
+ definitions :=
+ OrderedCollection with:
+ (FFISharedPoolDefinition fromClass: self).
+
+ self class methodsDo: [:each |
+ (each pragmaAt: #ffiSharedPool)
+ ifNotNil: [
+ definitions addLast:
+ (FFISharedPoolDefinition fromMethod: each)]].
+
+ ^ definitions asArray.!

Item was added:
+ ----- Method: FFISharedPool class>>ensureDirectoryExists: (in category 'private') -----
+ ensureDirectoryExists: aDirectoryPath
+ ^ self environment
+ at: #FileDirectory
+ ifPresent: [:fileDirectory |
+ "use Squeak's FileDirectory"
+ fileDirectory default assureExistenceOfPath: aDirectoryPath]
+ ifAbsent: [
+ "use Pharo's FileSystem"
+ aDirectoryPath asFileReference ensureCreateDirectory]!

Item was added:
+ ----- Method: FFISharedPool class>>errorFailedCommandTo: (in category 'private') -----
+ errorFailedCommandTo: aDescription
+ self error: 'Command executed to ', aDescription, ' failed'!

Item was added:
+ ----- Method: FFISharedPool class>>errorOSProcessRequiredTo: (in category 'private') -----
+ errorOSProcessRequiredTo: aDescription
+ self error:
+ 'The OSProcess library is needed to execute command to ', aDescription!

Item was added:
+ ----- Method: FFISharedPool class>>errorSavedPlatform:isNotCompatibleWith: (in category 'private') -----
+ errorSavedPlatform: aSavedPlatform isNotCompatibleWith: aCurrentPlatform
+ self error:
+ ('The saved platform is incompatible with the current platform: {1} ~= {2}'
+ format: {aSavedPlatform. aCurrentPlatform})!

Item was added:
+ ----- Method: FFISharedPool class>>executeExternalCommand:description: (in category 'private') -----
+ executeExternalCommand: aCommandString description: aDescription
+ | commandProcess |
+
+ commandProcess :=
+ (self environment
+ at: #OSProcess
+ ifAbsent: [self errorOSProcessRequiredTo: aDescription])
+ waitForCommand: aCommandString.
+ commandProcess succeeded
+ ifFalse: [self errorFailedCommandTo: aDescription].!

Item was added:
+ ----- Method: FFISharedPool class>>executeExternalCommand:format:description: (in category 'private') -----
+ executeExternalCommand: aString format: aCollection description: aDescription
+ ^ self
+ executeExternalCommand: (aString format: aCollection)
+ description: aDescription!

Item was added:
+ ----- Method: FFISharedPool class>>generateAllPrograms (in category 'generating') -----
+ generateAllPrograms
+ "self generateAllPrograms"
+
+ self allSubclassesDo: [:each |
+ each generateProgram]!

Item was added:
+ ----- Method: FFISharedPool class>>generateProgram (in category 'generating') -----
+ generateProgram
+ "self generateProgram"
+
+ | currentPlatform preferredDefinition sourceFilePath |
+
+ currentPlatform := FFISharedPoolPlatform current.
+ preferredDefinition :=
+ self preferredResolvedDefinitionForPlatform: currentPlatform.
+ sourceFilePath := self generatedSourceFilePath.
+
+ self ensureDirectoryExists: self generatedProgramDirectory.
+ self
+ generateSourceFile: sourceFilePath
+ forDefinition: preferredDefinition.
+ self
+ compileGeneratedSourceFile: sourceFilePath
+ to: self generatedProgramPath
+ forDefinition: preferredDefinition.!

Item was added:
+ ----- Method: FFISharedPool class>>generateSourceFile:forDefinition: (in category 'private') -----
+ generateSourceFile: aSourceFilePath forDefinition: aDefinition
+ self
+ writeStreamOnNewFileAt: aSourceFilePath
+ do: [:writeStream |
+ aDefinition generateProgramOn: writeStream]!

Item was added:
+ ----- Method: FFISharedPool class>>generatedProgramDirectory (in category 'defaults') -----
+ generatedProgramDirectory
+ ^ self vmPath, 'FFISharedPools/'!

Item was added:
+ ----- Method: FFISharedPool class>>generatedProgramExtension (in category 'defaults') -----
+ generatedProgramExtension
+ ^ FFISharedPoolPlatform isCurrentlyWindows
+ ifTrue: ['.exe']
+ ifFalse: ['']!

Item was added:
+ ----- Method: FFISharedPool class>>generatedProgramName (in category 'defaults') -----
+ generatedProgramName
+ ^ self name asString, self generatedProgramExtension!

Item was added:
+ ----- Method: FFISharedPool class>>generatedProgramPath (in category 'defaults') -----
+ generatedProgramPath
+ ^ self generatedProgramDirectory, self generatedProgramName!

Item was added:
+ ----- Method: FFISharedPool class>>generatedSourceFileExtension (in category 'defaults') -----
+ generatedSourceFileExtension
+ ^ '.c'!

Item was added:
+ ----- Method: FFISharedPool class>>generatedSourceFileName (in category 'defaults') -----
+ generatedSourceFileName
+ ^ self name asString, self generatedSourceFileExtension!

Item was added:
+ ----- Method: FFISharedPool class>>generatedSourceFilePath (in category 'defaults') -----
+ generatedSourceFilePath
+ ^ self generatedProgramDirectory, self generatedSourceFileName!

Item was added:
+ ----- Method: FFISharedPool class>>initialize (in category 'class initialization') -----
+ initialize
+ "self initialize"
+
+ self reinitializeAllSubclassesFromGeneratedProgramOutput!

Item was added:
+ ----- Method: FFISharedPool class>>lastPlatform (in category 'accessing') -----
+ lastPlatform
+ ^ lastPlatform!

Item was added:
+ ----- Method: FFISharedPool class>>lastPlatform: (in category 'accessing') -----
+ lastPlatform: aPlatform
+ lastPlatform := aPlatform!

Item was added:
+ ----- Method: FFISharedPool class>>outputFileExtension (in category 'defaults') -----
+ outputFileExtension
+ ^ '.st'!

Item was added:
+ ----- Method: FFISharedPool class>>outputFileName (in category 'defaults') -----
+ outputFileName
+ ^ self name asString, self outputFileExtension!

Item was added:
+ ----- Method: FFISharedPool class>>outputFilePath (in category 'defaults') -----
+ outputFilePath
+ ^ self generatedProgramDirectory, self outputFileName!

Item was added:
+ ----- Method: FFISharedPool class>>preferredResolvedDefinitionForPlatform: (in category 'accessing') -----
+ preferredResolvedDefinitionForPlatform: aPlatform
+ | compatibleResolvedDefinitions |
+
+ compatibleResolvedDefinitions :=
+ self resolvedDefinitions select: [:each |
+ each platform isCompatibleWith: aPlatform].
+
+ compatibleResolvedDefinitions sort: [:a :b |
+ a isMorePlatformSpecificThan: b].
+
+ ^ compatibleResolvedDefinitions first.!

Item was added:
+ ----- Method: FFISharedPool class>>readAndEvaluatedGeneratedProgramOutput (in category 'reading') -----
+ readAndEvaluatedGeneratedProgramOutput
+ | generatedProgramOutput |
+
+ generatedProgramOutput :=
+ [self readGeneratedProgramOutput]
+ on: FileDoesNotExistException
+ do: [:error | nil].
+ "try again, this time running the program first to create the output file"
+ generatedProgramOutput
+ ifNil: [
+ generatedProgramOutput :=
+ self
+ runGeneratedProgram;
+ readGeneratedProgramOutput].
+
+ ^ self compilerClass evaluate: generatedProgramOutput.!

Item was added:
+ ----- Method: FFISharedPool class>>readGeneratedProgramOutput (in category 'private') -----
+ readGeneratedProgramOutput
+ ^ self
+ readStreamOnExistingFileAt: self outputFilePath
+ do: [:readStream |
+ readStream upToEnd]!

Item was added:
+ ----- Method: FFISharedPool class>>readStreamOnExistingFileAt:do: (in category 'private') -----
+ readStreamOnExistingFileAt: aPathString do: aBlock
+ | readStream |
+
+ readStream := StandardFileStream readOnlyFileNamed: aPathString.
+ ^ [
+ readStream ascii.
+ aBlock value: readStream]
+ ensure: [readStream close].!

Item was added:
+ ----- Method: FFISharedPool class>>reinitializeAllSubclassesFromGeneratedProgramOutput (in category 'class initialization') -----
+ reinitializeAllSubclassesFromGeneratedProgramOutput
+ | currentPlatform |
+
+ currentPlatform := FFISharedPoolPlatform current.
+ self allSubclassesDo: [:each |
+ each reinitializeFromGeneratedProgramOutputForPlatform:
+ currentPlatform].!

Item was added:
+ ----- Method: FFISharedPool class>>reinitializeFromGeneratedProgramOutput (in category 'class initialization') -----
+ reinitializeFromGeneratedProgramOutput
+ "self reinitializeFromGeneratedProgramOutput"
+
+ self reinitializeFromGeneratedProgramOutputForPlatform:
+ FFISharedPoolPlatform current!

Item was added:
+ ----- Method: FFISharedPool class>>reinitializeFromGeneratedProgramOutputForPlatform: (in category 'class initialization') -----
+ reinitializeFromGeneratedProgramOutputForPlatform: aPlatform
+ | outputArray outputPlatform outputVariableDictionary |
+
+ outputArray :=
+ self readAndEvaluatedGeneratedProgramOutput.
+ outputPlatform := outputArray first.
+ outputVariableDictionary := outputArray second.
+
+ (outputPlatform isCompatibleWith: aPlatform)
+ ifFalse: [
+ self
+ errorSavedPlatform: outputPlatform
+ isNotCompatibleWith: aPlatform].
+
+ outputVariableDictionary keysAndValuesDo: [:key :value |
+ self classPool
+ at: key
+ put: value].
+
+ self lastPlatform: aPlatform.!

Item was added:
+ ----- Method: FFISharedPool class>>resolvedDefinitions (in category 'accessing') -----
+ resolvedDefinitions
+ ^ (FFISharedPoolDefinitionResolver
+ class: self
+ definitions: self definitions) resolvedDefinitions!

Item was added:
+ ----- Method: FFISharedPool class>>runGeneratedProgram (in category 'running') -----
+ runGeneratedProgram
+ "self runGeneratedProgram"
+
+ self
+ executeExternalCommand: 'cd {1}; ./{2} {3}'
+ format:
+ {self generatedProgramDirectory.
+ self generatedProgramName.
+ self outputFilePath}
+ description: 'run generated program'!

Item was added:
+ ----- Method: FFISharedPool class>>startUp: (in category 'system startup') -----
+ startUp: isResuming
+ isResuming
+ ifTrue: [| currentPlatform |
+ currentPlatform := FFISharedPoolPlatform current.
+ self allSubclassesDo: [:each |
+ each lastPlatform = currentPlatform
+ ifFalse: [
+ each reinitializeFromGeneratedProgramOutputForPlatform:
+ currentPlatform]]]
+ ifFalse: [self reinitializeAllSubclassesFromGeneratedProgramOutput]!

Item was added:
+ ----- Method: FFISharedPool class>>vmPath (in category 'defaults') -----
+ vmPath
+ ^ (Smalltalk respondsTo: #vmPath)
+ ifTrue: [
+ "for Squeak"
+ Smalltalk vmPath]
+ ifFalse: [
+ "for Pharo"
+ Smalltalk vm path]!

Item was added:
+ ----- Method: FFISharedPool class>>writeStreamOnNewFileAt:do: (in category 'private') -----
+ writeStreamOnNewFileAt: aPathString do: aBlock
+ | writeStream |
+
+ "use #forceNewFileNamed: to ensure truncation of existing files before writing"
+ writeStream := StandardFileStream forceNewFileNamed: aPathString.
+ ^ [
+ writeStream ascii.
+ aBlock value: writeStream]
+ ensure: [writeStream close].!

Item was added:
+ Object subclass: #FFISharedPoolDefinition
+ instanceVariableNames: 'name inheritsFrom variablesAndTypes platform cFlags cCompiler cHeaders programGeneratorClass'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'FFI-Pools'!
+
+ !FFISharedPoolDefinition commentStamp: 'monty 3/29/2018 03:36' prior: 0!
+ This class stores parsed FFISharedPool definitions. It can inherit from another definition with #inheritFrom:, and generate a program with #generateProgramOn:.
+
+ The supported pragmas for methods defining FFISharedPools are in the "pragmas" category.!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>defaultCCompiler (in category 'defaults') -----
+ defaultCCompiler
+ ^ 'cc'!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>defaultCFlags (in category 'defaults') -----
+ defaultCFlags
+ ^ '-o'!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>defaultCHeaders (in category 'defaults') -----
+ defaultCHeaders
+ ^ #()!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>defaultPlatform (in category 'defaults') -----
+ defaultPlatform
+ ^ FFISharedPoolPlatform empty!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>defaultProgramGeneratorClass (in category 'defaults') -----
+ defaultProgramGeneratorClass
+ ^ FFISharedPoolProgramGenerator!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>defaultVariableType (in category 'defaults') -----
+ defaultVariableType
+ ^ Integer!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>fromClass: (in category 'instance creation') -----
+ fromClass: aClass
+ | definition |
+
+ (definition := self new)
+ cCompiler: self defaultCCompiler;
+ cFlags: self defaultCFlags;
+ cHeaders: self defaultCHeaders;
+ platform: self defaultPlatform;
+ programGeneratorClass: self defaultProgramGeneratorClass.
+
+ aClass classPool keysDo: [:each |
+ definition
+ variablesAndTypesAt: each
+ put: self defaultVariableType].
+
+ ^ definition.!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>fromMethod: (in category 'instance creation') -----
+ fromMethod: aCompiledMethod
+ | definition |
+
+ definition := self name: aCompiledMethod selector.
+
+ "Squeak does not have #pragmasDo:"
+ aCompiledMethod pragmas do: [:each |
+ (self whichCategoryIncludesSelector: each keyword) == #'pragmas'
+ ifTrue: [
+ definition
+ perform: each keyword
+ withArguments: each arguments]].
+
+ ^ definition.!

Item was added:
+ ----- Method: FFISharedPoolDefinition class>>name: (in category 'instance creation') -----
+ name: aSelector
+ ^ self new name: aSelector!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>cCompiler (in category 'accessing') -----
+ cCompiler
+ ^ cCompiler ifNil: [cCompiler := '']!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>cCompiler: (in category 'accessing') -----
+ cCompiler: aString
+ cCompiler := aString!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>cFlags (in category 'accessing') -----
+ cFlags
+ ^ cFlags ifNil: [cFlags := '']!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>cFlags: (in category 'accessing') -----
+ cFlags: aString
+ cFlags := aString!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>cHeaders (in category 'accessing') -----
+ cHeaders
+ ^ cHeaders ifNil: [cHeaders := #()]!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>cHeaders: (in category 'accessing') -----
+ cHeaders: aHeaderPathCollection
+ cHeaders :=
+ aHeaderPathCollection asArray
+ select: [:each | each notEmpty]
+ thenCollect: [:each |
+ (each first == $"
+ or: [each first == $<])
+ ifTrue: [each]
+ ifFalse: ['<', each, '>']]!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>cHeadersDo: (in category 'enumerating') -----
+ cHeadersDo: aBlock
+ self cHeaders do: aBlock!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiCCompiler: (in category 'pragmas') -----
+ ffiCCompiler: aString
+ self cCompiler: aString!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiCFlags: (in category 'pragmas') -----
+ ffiCFlags: aString
+ self cFlags: aString!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiCHeaders: (in category 'pragmas') -----
+ ffiCHeaders: aHeaderPathCollection
+ self cHeaders: aHeaderPathCollection!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiInheritsFrom: (in category 'pragmas') -----
+ ffiInheritsFrom: aSelector
+ self inheritsFrom: aSelector!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiPlatformName: (in category 'pragmas') -----
+ ffiPlatformName: aName
+ self platform:
+ (FFISharedPoolPlatform name: aName)!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiPlatformName:osVersion: (in category 'pragmas') -----
+ ffiPlatformName: aName osVersion: anOSVersionString
+ self platform:
+ (FFISharedPoolPlatform
+ name: aName
+ osVersion: anOSVersionString)!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiPlatformName:osVersion:subtype: (in category 'pragmas') -----
+ ffiPlatformName: aName osVersion: anOSVersionString subtype: aSubtypeString
+ self platform:
+ (FFISharedPoolPlatform
+ name: aName
+ osVersion: anOSVersionString
+ subtype: aSubtypeString)!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiPlatformName:osVersion:subtype:wordSize: (in category 'pragmas') -----
+ ffiPlatformName: aName osVersion: anOSVersionString subtype: aSubtypeString wordSize: aWordSize
+ self platform:
+ (FFISharedPoolPlatform
+ name: aName
+ osVersion: anOSVersionString
+ subtype: aSubtypeString
+ wordSize: aWordSize)!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiPlatformName:wordSize: (in category 'pragmas') -----
+ ffiPlatformName: aName wordSize: aWordSize
+ self platform:
+ (FFISharedPoolPlatform
+ name: aName
+ wordSize: aWordSize)!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiProgramGeneratorClass: (in category 'pragmas') -----
+ ffiProgramGeneratorClass: aClass
+ self programGeneratorClass: aClass!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiSharedPool (in category 'pragmas') -----
+ ffiSharedPool!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>ffiVariable:type: (in category 'pragmas') -----
+ ffiVariable: aVariableName type: aType
+ self
+ variablesAndTypesAt: aVariableName
+ put: aType!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>generateProgramOn: (in category 'generating') -----
+ generateProgramOn: aStream
+ (self programGeneratorClass
+ on: aStream
+ definition: self) generate!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>inheritFrom: (in category 'inheriting') -----
+ inheritFrom: aDefinition
+ self cCompiler
+ ifEmpty: [self cCompiler: aDefinition cCompiler].
+ self cFlags
+ ifEmpty: [self cFlags: aDefinition cFlags].
+ self cHeaders
+ ifEmpty: [self cHeaders: aDefinition cHeaders].
+ self platform
+ ifNil: [self platform: aDefinition platform].
+ self programGeneratorClass
+ ifNil: [self programGeneratorClass: aDefinition programGeneratorClass].
+
+ aDefinition variablesAndTypesDo: [:key :value |
+ self
+ variablesAndTypesAt: key
+ ifAbsentPut: value].!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>inheritsFrom (in category 'accessing') -----
+ inheritsFrom
+ ^ inheritsFrom!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>inheritsFrom: (in category 'accessing') -----
+ inheritsFrom: aSelector
+ inheritsFrom := aSelector!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>isDefault (in category 'testing') -----
+ isDefault
+ ^ self name isNil!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>isMorePlatformSpecificThan: (in category 'testing') -----
+ isMorePlatformSpecificThan: aDefinition
+ ^ aDefinition isDefault
+ or: [self platform isMoreSpecificThan: aDefinition platform]!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>name (in category 'accessing') -----
+ name
+ ^ name!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>name: (in category 'accessing') -----
+ name: aSelector
+ name := aSelector!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>platform (in category 'accessing') -----
+ platform
+ ^ platform!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>platform: (in category 'accessing') -----
+ platform: aPlatform
+ platform := aPlatform!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>printOn: (in category 'printing') -----
+ printOn: aStream
+ super printOn: aStream.
+
+ aStream nextPut: $(.
+ self isDefault
+ ifTrue: [aStream nextPutAll: 'default']
+ ifFalse: [aStream print: self name].
+ aStream nextPut: $).!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>programGeneratorClass (in category 'accessing') -----
+ programGeneratorClass
+ ^ programGeneratorClass!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>programGeneratorClass: (in category 'accessing') -----
+ programGeneratorClass: aClass
+ programGeneratorClass := aClass!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>variablesAndTypes (in category 'accessing') -----
+ variablesAndTypes
+ ^ variablesAndTypes ifNil: [variablesAndTypes := Dictionary new]!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>variablesAndTypes: (in category 'accessing') -----
+ variablesAndTypes: anAssociationCollection
+ variablesAndTypes := Dictionary new.
+ anAssociationCollection associationsDo: [:each |
+ self
+ variablesAndTypesAt: each key
+ put: each value].!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>variablesAndTypesAt: (in category 'accessing') -----
+ variablesAndTypesAt: aVaraibleName
+ ^ self
+ variablesAndTypesAt: aVaraibleName
+ ifAbsent: [nil]!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>variablesAndTypesAt:ifAbsent: (in category 'accessing') -----
+ variablesAndTypesAt: aVaraibleName ifAbsent: aBlock
+ ^ self variablesAndTypes
+ at: aVaraibleName asSymbol
+ ifAbsent: aBlock!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>variablesAndTypesAt:ifAbsentPut: (in category 'accessing') -----
+ variablesAndTypesAt: aVaraibleName ifAbsentPut: aBlock
+ ^ self
+ variablesAndTypesAt: aVaraibleName
+ ifAbsent: [
+ self
+ variablesAndTypesAt: aVaraibleName
+ put: aBlock value]!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>variablesAndTypesAt:put: (in category 'accessing') -----
+ variablesAndTypesAt: aVaraibleName put: aClassOrNil
+ ^ self variablesAndTypes
+ at: aVaraibleName asSymbol
+ put: aClassOrNil asFFISharedPoolType!

Item was added:
+ ----- Method: FFISharedPoolDefinition>>variablesAndTypesDo: (in category 'enumerating') -----
+ variablesAndTypesDo: aTwoArgumentBlock
+ self variablesAndTypes keysAndValuesDo: aTwoArgumentBlock!

Item was added:
+ Object subclass: #FFISharedPoolDefinitionResolver
+ instanceVariableNames: 'class definitions definitionsByName defaultDefinition unresolvedDefinitions visitedDefintions'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'FFI-Pools'!
+
+ !FFISharedPoolDefinitionResolver commentStamp: 'monty 3/29/2018 03:37' prior: 0!
+ This class resolves FFISharedPoolDefinition inheritance dependencies.!

Item was added:
+ ----- Method: FFISharedPoolDefinitionResolver class>>class:definitions: (in category 'instance creation') -----
+ class: aClass definitions: aDefinitionCollection
+ ^ self new
+ setClass: aClass
+ definitions: aDefinitionCollection!

Item was added:
+ ----- Method: FFISharedPoolDefinitionResolver>>errorLoopInDefinitions (in category 'private') -----
+ errorLoopInDefinitions
+ self error: 'Class ', class name asString, ' has a loop in its definitions'!

Item was added:
+ ----- Method: FFISharedPoolDefinitionResolver>>errorUnknownReferenceInDefinition: (in category 'private') -----
+ errorUnknownReferenceInDefinition: aDefinition
+ self error:
+ ('Unknown reference to definition #{1} in definition #{2} from class {3}'
+ format: {aDefinition inheritsFrom. aDefinition name. class name})!

Item was added:
+ ----- Method: FFISharedPoolDefinitionResolver>>resolveDefinition: (in category 'private') -----
+ resolveDefinition: aDefinition
+ aDefinition inheritsFrom
+ ifNil: [aDefinition inheritFrom: defaultDefinition]
+ ifNotNil: [:inheritsFrom | | inheritedDefinition |
+ inheritedDefinition :=
+ definitionsByName
+ at: inheritsFrom
+ ifAbsent: [self errorUnknownReferenceInDefinition: aDefinition].
+
+ (visitedDefintions includes: inheritedDefinition)
+ ifTrue: [self errorLoopInDefinitions].
+ visitedDefintions add: inheritedDefinition.
+
+ (unresolvedDefinitions includes: inheritedDefinition)
+ ifTrue: [self resolveDefinition: inheritedDefinition].
+
+ aDefinition inheritFrom: inheritedDefinition].
+
+ unresolvedDefinitions remove: aDefinition.!

Item was added:
+ ----- Method: FFISharedPoolDefinitionResolver>>resolvedDefinitions (in category 'accessing') -----
+ resolvedDefinitions
+ [unresolvedDefinitions isEmpty]
+ whileFalse: [| definition |
+ definition := unresolvedDefinitions anyOne.
+ visitedDefintions := Set with: definition.
+ self resolveDefinition: definition].
+
+ ^ definitions.!

Item was added:
+ ----- Method: FFISharedPoolDefinitionResolver>>setClass:definitions: (in category 'initialization') -----
+ setClass: aClass definitions: aDefinitionCollection
+ class := aClass.
+ definitions := aDefinitionCollection.
+ definitionsByName := Dictionary new.
+ unresolvedDefinitions := Set new.
+ definitions do: [:each |
+ each isDefault
+ ifTrue: [defaultDefinition := each]
+ ifFalse: [
+ definitionsByName
+ at: each name
+ put: each.
+ unresolvedDefinitions add: each]].!

Item was added:
+ Object subclass: #FFISharedPoolPlatform
+ instanceVariableNames: 'name osVersion subtype wordSize'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'FFI-Pools'!
+
+ !FFISharedPoolPlatform commentStamp: 'monty 3/25/2018 04:31' prior: 0!
+ A class for storing the platform information for an FFISharedPool!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>current (in category 'instance creation') -----
+ current
+ ^ self
+ name: self currentName
+ osVersion: self currentOSVersion
+ subtype: self currentSubtype
+ wordSize: self currentWordSize!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>currentName (in category 'accessing') -----
+ currentName
+ "self currentName"
+
+ ^ Smalltalk os platformName!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>currentOSVersion (in category 'accessing') -----
+ currentOSVersion
+ "self currentOSVersion"
+
+ "'Smalltalk os version' and 'Smalltalk osVersion' are not portable to Pharo.
+ On Squeak:
+ Smalltalk osVersion = (Smalltalk getSystemAttribute: 1002) asString"
+ ^ (Smalltalk getSystemAttribute: 1002) asString!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>currentSubtype (in category 'accessing') -----
+ currentSubtype
+ "self currentSubtype"
+
+ "'Smalltalk platformSubtype' is not portable to Pharo.
+ On Squeak:
+ Smalltalk platformSubtype = (Smalltalk getSystemAttribute: 1003) asString"
+ ^ (Smalltalk getSystemAttribute: 1003) asString!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>currentWordSize (in category 'accessing') -----
+ currentWordSize
+ "self currentWordSize"
+
+ ^ Smalltalk wordSize!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>empty (in category 'instance creation') -----
+ empty
+ ^ self new!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>isCurrentlyWindows (in category 'testing') -----
+ isCurrentlyWindows
+ ^ self currentName asLowercase beginsWith: 'win'!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>name: (in category 'instance creation') -----
+ name: aName
+ ^ self new name: aName!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>name:osVersion: (in category 'instance creation') -----
+ name: aName osVersion: anOSVersionString
+ ^ self new
+ name: aName;
+ osVersion: anOSVersionString!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>name:osVersion:subtype: (in category 'instance creation') -----
+ name: aName osVersion: anOSVersionString subtype: aSubtypeString
+ ^ self new
+ name: aName;
+ osVersion: anOSVersionString;
+ subtype: aSubtypeString!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>name:osVersion:subtype:wordSize: (in category 'instance creation') -----
+ name: aName osVersion: anOSVersionString subtype: aSubtypeString wordSize: aWordSize
+ ^ self new
+ name: aName;
+ osVersion: anOSVersionString;
+ subtype: aSubtypeString;
+ wordSize: aWordSize!

Item was added:
+ ----- Method: FFISharedPoolPlatform class>>name:wordSize: (in category 'instance creation') -----
+ name: aName wordSize: aWordSize
+ ^ self new
+ name: aName;
+ wordSize: aWordSize!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>= (in category 'comparing') -----
+ = anObject
+ self == anObject
+ ifTrue: [^ true].
+
+ self species == anObject species
+ ifFalse: [^ false].
+
+ ^ self name = anObject name
+ and: [self osVersion = anObject osVersion
+ and: [self subtype = anObject subtype
+ and: [self wordSize = anObject wordSize]]].!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>hasName (in category 'testing') -----
+ hasName
+ ^ self name notEmpty!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>hasOSVersion (in category 'testing') -----
+ hasOSVersion
+ ^ self osVersion notEmpty!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>hasSubtype (in category 'testing') -----
+ hasSubtype
+ ^ self subtype notEmpty!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>hasWordSize (in category 'testing') -----
+ hasWordSize
+ ^ self wordSize notNil!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>hash (in category 'comparing') -----
+ hash
+ ^ (((self species hash bitXor:
+ self name hash) bitXor:
+ self osVersion hash) bitXor:
+ self subtype hash) bitXor:
+ self wordSize hash!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>isCompatibleWith: (in category 'testing') -----
+ isCompatibleWith: aPlatform
+ self == aPlatform
+ ifTrue: [^ true].
+
+ (self name = aPlatform name
+ or: [self hasName not
+ or: [aPlatform hasName not]])
+ ifFalse: [^ false].
+
+ (self osVersion = aPlatform osVersion
+ or: [self hasOSVersion not
+ or: [aPlatform hasOSVersion not]])
+ ifFalse: [^ false].
+
+ (self subtype = aPlatform subtype
+ or: [self hasSubtype not
+ or: [aPlatform hasSubtype not]])
+ ifFalse: [^ false].
+
+ (self wordSize = aPlatform wordSize
+ or: [self hasWordSize not
+ or: [aPlatform hasWordSize not]])
+ ifFalse: [^ false].
+
+ ^ true.!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>isMoreSpecificThan: (in category 'testing') -----
+ isMoreSpecificThan: aPlatform
+ self == aPlatform
+ ifTrue: [^ false].
+
+ (self hasName
+ and: [aPlatform hasName not])
+ ifTrue: [^ true].
+
+ (self hasOSVersion
+ and: [aPlatform hasOSVersion not])
+ ifTrue: [^ true].
+
+ (self hasSubtype
+ and: [aPlatform hasSubtype not])
+ ifTrue: [^ true].
+
+ (self hasWordSize
+ and: [aPlatform hasWordSize not])
+ ifTrue: [^ true].
+
+ ^ false.!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>name (in category 'accessing') -----
+ name
+ ^ name ifNil: [name := '']!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>name: (in category 'accessing') -----
+ name: aName
+ name := aName!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>osVersion (in category 'accessing') -----
+ osVersion
+ ^ osVersion ifNil: [osVersion := '']!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>osVersion: (in category 'accessing') -----
+ osVersion: anOSVersionString
+ osVersion := anOSVersionString!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>printOn: (in category 'printing') -----
+ printOn: aStream
+ self storeOn: aStream!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>storeOn: (in category 'printing') -----
+ storeOn: aStream
+ aStream
+ nextPut: $(;
+ nextPutAll: self class name asString;
+ nextPutAll: ' name: ';
+ print: self name;
+ nextPutAll: ' osVersion: ';
+ print: self osVersion;
+ nextPutAll: ' subtype: ';
+ print: self subtype;
+ nextPutAll: ' wordSize: ';
+ print: self wordSize;
+ nextPut: $).!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>subtype (in category 'accessing') -----
+ subtype
+ ^ subtype ifNil: [subtype := '']!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>subtype: (in category 'accessing') -----
+ subtype: aSubtypeString
+ subtype := aSubtypeString!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>wordSize (in category 'accessing') -----
+ wordSize
+ ^ wordSize!

Item was added:
+ ----- Method: FFISharedPoolPlatform>>wordSize: (in category 'accessing') -----
+ wordSize: aWordSize
+ wordSize := aWordSize!

Item was added:
+ Object subclass: #FFISharedPoolProgramGenerator
+ instanceVariableNames: 'stream definition'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'FFI-Pools'!
+
+ !FFISharedPoolProgramGenerator commentStamp: 'monty 3/28/2018 03:11' prior: 0!
+ This class generates a program to output an evaluable Smalltalk representation of an FFISharedPoolDefinition.!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator class>>new (in category 'instance creation') -----
+ new
+ self shouldNotImplement!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator class>>on:definition: (in category 'instance creation') -----
+ on: aStream definition: aDefinition
+ ^ self basicNew initialize
+ setStream: aStream
+ definition: aDefinition  !

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>contents (in category 'accessing') -----
+ contents
+ ^ self stream contents!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>defaultHeaders (in category 'defaults') -----
+ defaultHeaders
+ ^ #('<errno.h>' '<stdarg.h>' '<stddef.h>' '<stdio.h>' '<stdlib.h>' '<string.h>')!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>definition (in category 'accessing') -----
+ definition
+ ^ definition!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emit: (in category 'emitting') -----
+ emit: aCharacter
+ self stream nextPut: aCharacter!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitAll: (in category 'emitting') -----
+ emitAll: aString
+ self stream nextPutAll: aString asString!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitAll:format: (in category 'emitting') -----
+ emitAll: aTemplateString format: aSequenceableCollectionOrDictionary
+ "works similar to String>>#format:, except it uses '${xxx}' syntax
+ for macro expansion, which is more convenient for C"
+
+ | templateReadStream |
+
+ templateReadStream := aTemplateString asString readStream.
+ [templateReadStream atEnd]
+ whileFalse: [| nextChar |
+ ((nextChar := templateReadStream next) == $$
+ and: [templateReadStream peekFor: ${])
+ ifTrue: [| key |
+ key := templateReadStream upTo: $}.
+ self emitAll:
+ (aSequenceableCollectionOrDictionary at:
+ (aSequenceableCollectionOrDictionary isDictionary
+ ifTrue: [key]
+ ifFalse: [key asUnsignedInteger])) asString]
+ ifFalse: [self emit: nextChar]].!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitBooleanOutputCodeFor: (in category 'emitting - output code') -----
+ emitBooleanOutputCodeFor: anIdentifier
+ self
+ emitAll: '${1}(file, "(%s)", (${2} ? "true" : "false"))'
+ format: {self printfFunctionName. anIdentifier}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitCharacterOutputCodeFor: (in category 'emitting - output code') -----
+ emitCharacterOutputCodeFor: anIdentifier
+ self
+ emitAll: '${1}(file, "(%ul asCharacter)", (unsigned long) ((${2} < 0) ? 0 : ${2}))'
+ format: {self printfFunctionName. anIdentifier}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitEndMainFunctionDefinition (in category 'emitting - function definitions') -----
+ emitEndMainFunctionDefinition
+ self
+ emitAll:
+ '
+ if (file !!= stdout) {
+ if (fclose(file) !!= 0) {
+ ${1}("Can''t close file", errno);
+ return EXIT_FAILURE;
+ }
+ }
+
+ return EXIT_SUCCESS;
+ }
+ ' format: {self errorFunctionName}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitEndOutputCode (in category 'emitting - output code') -----
+ emitEndOutputCode
+ self
+ emitAll:
+ ' ${1}(file, "}\n");
+ '
+ format: {self printfFunctionName}
+ !

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitEpilog (in category 'emitting') -----
+ emitEpilog
+ self emitEndMainFunctionDefinition!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitErrorFunctionDefinition (in category 'emitting - function definitions') -----
+ emitErrorFunctionDefinition
+ self
+ emitAll: '
+ static void ${1}(const char *message, int error)
+ {
+ fprintf(stderr, "%s: %s\n", message, strerror(error));
+ ${2}
+ }
+ '
+ format: {
+ self errorFunctionName.
+ self generatedProgramExitsOnError
+ ifTrue: ['exit(EXIT_FAILURE);']
+ ifFalse: ['/* no exit on error */']}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitFileComment (in category 'emitting') -----
+ emitFileComment
+ self
+ emitAll: '/*
+  * This file was automatically generated by ${1}.
+  * ''${2}''
+  * ''${3}''
+  */
+
+ '
+ format: {self class name. DateAndTime now. Smalltalk version}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitFloatOutputCodeFor: (in category 'emitting - output code') -----
+ emitFloatOutputCodeFor: anIdentifier
+ self
+ emitAll: '${1}(file, "(Float ffiSharedPoolReadFrom: ''%Lg'')", (long double) ${2})'
+ format: {self printfFunctionName. anIdentifier}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitFunctionDefinitions (in category 'emitting - function definitions') -----
+ emitFunctionDefinitions
+ self
+ emitErrorFunctionDefinition;
+ emitPrintfFunctionDefinition;
+ emitPutcFunctionDefinition;
+ emitStringOutputFunctionDefinition!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitHeader: (in category 'emitting - headers') -----
+ emitHeader: aHeaderPath
+ self
+ emitAll: '#include ${1}
+ '
+ format: {aHeaderPath}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitHeaders (in category 'emitting - headers') -----
+ emitHeaders
+ self defaultHeaders do: [:each |
+ self emitHeader: each].
+ self definition cHeadersDo: [:each |
+ self emitHeader: each].!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitIntegerOutputCodeFor: (in category 'emitting - output code') -----
+ emitIntegerOutputCodeFor: anIdentifier
+ self
+ emitAll: '${1}(file, "(%ld)", (long) ${2})'
+ format: {self printfFunctionName. anIdentifier}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitOutputCode (in category 'emitting - output code') -----
+ emitOutputCode
+ self
+ emitStartOutputCode;
+ emitPlatformOutputCode;
+ emitVariableOutputCode;
+ emitEndOutputCode!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitPlatformOutputCode (in category 'emitting - output code') -----
+ emitPlatformOutputCode
+ self
+ emitAll:
+ ' ${1}(file, "\t%s.\n",
+ '
+ format: {self printfFunctionName}.
+ "serialize the store string as a C string literal with proper escaping"
+ self
+ emitStringLiteral: self definition platform storeString;
+ emitAll: ');
+ '.
+ !

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitPrintfFunctionDefinition (in category 'emitting - function definitions') -----
+ emitPrintfFunctionDefinition
+ self
+ emitAll: '
+ static int ${1}(FILE *file, const char *format, ...)
+ {
+ va_list ap;
+ int rv;
+
+ va_start(ap, format);
+ if ((rv = vfprintf(file, format, ap)) >= 0) {
+ va_end(ap);
+ } else {
+ int err = errno; /* save errno */
+ va_end(ap);
+ ${2}("Can''t print to file", err);
+ }
+
+ return rv;
+ }
+ '
+ format: {self printfFunctionName. self errorFunctionName}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitProlog (in category 'emitting') -----
+ emitProlog
+ self
+ emitFileComment;
+ emitHeaders;
+ emitFunctionDefinitions;
+ emitStartMainFunctionDefinition!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitPutcFunctionDefinition (in category 'emitting - function definitions') -----
+ emitPutcFunctionDefinition
+ self
+ emitAll: '
+ static int ${1}(int c, FILE *file)
+ {
+ int rv;
+
+ if ((rv = fputc(c, file)) == EOF)
+ ${2}("Can''t print to file", errno);
+
+ return rv;
+ }
+ '
+ format: {self putcFunctionName. self errorFunctionName}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitStartMainFunctionDefinition (in category 'emitting - function definitions') -----
+ emitStartMainFunctionDefinition
+ self
+ emitAll: '
+ int main(int argc, char *argv[])
+ {
+ FILE *file;
+
+ if (argc > 1) {
+ if ((file = fopen(argv[1], "wb")) == NULL) {
+ ${1}("Can''t open file", errno);
+ return EXIT_FAILURE;
+ }
+ } else {
+ file = stdout;
+ }
+
+ '
+ format: {self errorFunctionName}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitStartOutputCode (in category 'emitting - output code') -----
+ emitStartOutputCode
+ self
+ emitAll:
+ ' ${1}(file, "{\n");
+ '
+ format: {self printfFunctionName}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitStringLiteral: (in category 'emitting') -----
+ emitStringLiteral: aString
+ self emit: $".
+ aString do: [:each |
+ (each == $"
+ or: [each == $\])
+ ifTrue: [self emit: $\].
+ self emit: each].
+ self emit: $".!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitStringOutputCodeFor: (in category 'emitting - output code') -----
+ emitStringOutputCodeFor: anIdentifier
+ self
+ emitAll: '${1}(file, ${2})'
+ format: {self stringOutputFunctionName. anIdentifier}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitStringOutputFunctionDefinition (in category 'emitting - function definitions') -----
+ emitStringOutputFunctionDefinition
+ self
+ emitAll: '
+ static void ${1}(FILE *file, const char *s)
+ {
+ ${2}(file, "(''");
+ while (*s !!= ''\0'') {
+ if (*s == ''\'''')
+ ${3}(''\'''', file); /* escape the subquote */
+ ${3}(*s++, file);
+ }
+ ${2}(file, "'')");
+ }
+ '
+ format:
+ {self stringOutputFunctionName.
+ self printfFunctionName.
+ self putcFunctionName}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitUnsignedIntegerOutputCodeFor: (in category 'emitting - output code') -----
+ emitUnsignedIntegerOutputCodeFor: anIdentifier
+ self
+ emitAll: '${1}(file, "(%lu)", (unsigned long) ${2})'
+ format: {self printfFunctionName. anIdentifier}!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitVariableOutputCode (in category 'emitting - output code') -----
+ emitVariableOutputCode
+ | emittedVariableOutputCode |
+
+ self
+ emitAll:
+ ' ${1}(file, "\tDictionary new\n");
+ '
+ format: {self printfFunctionName}.
+
+ emittedVariableOutputCode := false.
+ self definition variablesAndTypesDo: [:key :value |
+ value
+ ifNotNil: [
+ self
+ emitVariableOutputCodeFor: key
+ type: value.
+ emittedVariableOutputCode := true]].
+
+ emittedVariableOutputCode
+ ifTrue: [
+ self
+ emitAll:
+ ' ${1}(file, "\t\tyourself\n");
+ '
+ format: {self printfFunctionName}].!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>emitVariableOutputCodeFor:type: (in category 'emitting - output code') -----
+ emitVariableOutputCodeFor: aVariableName type: aType
+ self
+ emitAll:
+ ' ${1}(file, "\t\tat: #%s put: ", "${2}");
+ '
+ format: {self printfFunctionName. aVariableName}.
+
+ aType
+ ffiSharedPoolGenerateOutputCodeFor: aVariableName
+ with: self.
+
+ self
+ emitAll:
+ ';
+ ${1}(file, ";\n");
+ '
+ format: {self printfFunctionName}.!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>errorFunctionName (in category 'defaults') -----
+ errorFunctionName
+ ^ self functionNamed: 'Error'!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>functionNamed: (in category 'defaults') -----
+ functionNamed: aPartialFunctionName
+ ^ self functionNamespace, aPartialFunctionName!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>functionNamespace (in category 'defaults') -----
+ functionNamespace
+ ^ 'ffiSharedPool'!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>generate (in category 'generating') -----
+ generate
+ self
+ emitProlog;
+ emitOutputCode;
+ emitEpilog!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>generatedProgramExitsOnError (in category 'testing') -----
+ generatedProgramExitsOnError
+ ^ true!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>printfFunctionName (in category 'defaults') -----
+ printfFunctionName
+ ^ self functionNamed: 'Printf'!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>putcFunctionName (in category 'defaults') -----
+ putcFunctionName
+ ^ self functionNamed: 'Putc'!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>setStream:definition: (in category 'initialization') -----
+ setStream: aStream definition: aDefinition
+ stream := aStream.
+ definition := aDefinition.!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>stream (in category 'accessing') -----
+ stream
+ ^ stream!

Item was added:
+ ----- Method: FFISharedPoolProgramGenerator>>stringOutputFunctionName (in category 'defaults') -----
+ stringOutputFunctionName
+ ^ self functionNamed: 'OutputString'!

Item was added:
+ ----- Method: Float class>>ffiSharedPoolGenerateOutputCodeFor:with: (in category '*FFI-Pools') -----
+ ffiSharedPoolGenerateOutputCodeFor: aPoolVariableName with: aProgramGenerator
+ aProgramGenerator emitFloatOutputCodeFor: aPoolVariableName!

Item was added:
+ ----- Method: Float class>>ffiSharedPoolReadFrom: (in category '*FFI-Pools') -----
+ ffiSharedPoolReadFrom: aStreamOrString
+ ^ self
+ ffiSharedPoolReadFrom: aStreamOrString
+ ifFail: [nil]!

Item was added:
+ ----- Method: Float class>>ffiSharedPoolReadFrom:ifFail: (in category '*FFI-Pools') -----
+ ffiSharedPoolReadFrom: aStreamOrString ifFail: aBlock
+ | readStream startPosition isNegative |
+
+ readStream :=
+ aStreamOrString isStream
+ ifTrue: [aStreamOrString]
+ ifFalse: [aStreamOrString readStream].
+ startPosition := readStream position.
+
+ (isNegative := readStream peekFor: $-)
+ ifFalse: [readStream peekFor: $+].
+
+ ((readStream nextMatchAll: 'infinity')
+ or: [(readStream nextMatchAll: 'INFINITY')
+ or: [(readStream nextMatchAll: 'inf')
+ or: [(readStream nextMatchAll: 'INF')]]])
+ ifTrue: [
+ ^ isNegative
+ ifTrue: [self negativeInfinity]
+ ifFalse: [self infinity]].
+
+ ((readStream nextMatchAll: 'nan')
+ or: [readStream nextMatchAll: 'NAN'])
+ ifTrue: [^ self nan].
+
+ readStream position: startPosition.
+ ^ self
+ readFrom: readStream
+ ifFail: aBlock.!

Item was added:
+ ----- Method: Integer class>>ffiSharedPoolGenerateOutputCodeFor:with: (in category '*FFI-Pools') -----
+ ffiSharedPoolGenerateOutputCodeFor: aPoolVariableName with: aProgramGenerator
+ aProgramGenerator emitIntegerOutputCodeFor: aPoolVariableName!

Item was added:
+ ----- Method: LargePositiveInteger class>>ffiSharedPoolGenerateOutputCodeFor:with: (in category '*FFI-Pools') -----
+ ffiSharedPoolGenerateOutputCodeFor: aPoolVariableName with: aProgramGenerator
+ aProgramGenerator emitUnsignedIntegerOutputCodeFor: aPoolVariableName!

Item was added:
+ ----- Method: Object>>asFFISharedPoolType (in category '*FFI-Pools') -----
+ asFFISharedPoolType
+ self error: 'Cannot convert object to type'!

Item was added:
+ ----- Method: Object>>ffiSharedPoolGenerateOutputCodeFor:with: (in category '*FFI-Pools') -----
+ ffiSharedPoolGenerateOutputCodeFor: aPoolVariableName with: aProgramGenerator
+ self error: 'Cannot generate output code for ', self class name asString!

Item was added:
+ ----- Method: String class>>ffiSharedPoolGenerateOutputCodeFor:with: (in category '*FFI-Pools') -----
+ ffiSharedPoolGenerateOutputCodeFor: aPoolVariableName with: aProgramGenerator
+ aProgramGenerator emitStringOutputCodeFor: aPoolVariableName!

Item was added:
+ ----- Method: String>>asFFISharedPoolType (in category '*FFI-Pools') -----
+ asFFISharedPoolType
+ ^ self class environment
+ at: self asSymbol
+ ifAbsent: [self error: 'Cannot convert object to type']!

Item was added:
+ ----- Method: UndefinedObject>>asFFISharedPoolType (in category '*FFI-Pools') -----
+ asFFISharedPoolType
+ ^ self!