Skip to content

Commit

Permalink
introduces FFIBit and FFIUBit (this is to be used with structures tha…
Browse files Browse the repository at this point in the history
…t adds bit types)
  • Loading branch information
estebanlm committed Sep 2, 2019
1 parent 7688fb7 commit 48b482a
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 2 deletions.
38 changes: 38 additions & 0 deletions src/UnifiedFFI/ByteArray.extension.st
Expand Up @@ -44,6 +44,25 @@ ByteArray >> packToArity: arity [
self error: 'Use ExternalAddress instead!'
]

{ #category : #'*UnifiedFFI' }
ByteArray >> platformBitAt: byteOffset [

^ self
integerAt: byteOffset
size: FFIArchitecture forCurrentArchitecture bitTypeSize
signed: true
]

{ #category : #'*UnifiedFFI' }
ByteArray >> platformBitAt: byteOffset put: value [

self
integerAt: byteOffset
put: value
size: FFIArchitecture forCurrentArchitecture bitTypeSize
signed: true
]

{ #category : #'*UnifiedFFI' }
ByteArray >> platformLongAt: byteOffset [
^ self
Expand Down Expand Up @@ -78,6 +97,25 @@ ByteArray >> platformSizeTAt: byteOffset put: value [
signed: false
]

{ #category : #'*UnifiedFFI' }
ByteArray >> platformUnsignedBitAt: byteOffset [

^ self
integerAt: byteOffset
size: FFIArchitecture forCurrentArchitecture bitTypeSize
signed: false
]

{ #category : #'*UnifiedFFI' }
ByteArray >> platformUnsignedBitAt: byteOffset put: value [

self
integerAt: byteOffset
put: value
size: FFIArchitecture forCurrentArchitecture bitTypeSize
signed: false
]

{ #category : #'*UnifiedFFI' }
ByteArray >> platformUnsignedLongAt: byteOffset [
^ self
Expand Down
24 changes: 24 additions & 0 deletions src/UnifiedFFI/FFIArchitecture.class.st
Expand Up @@ -39,6 +39,24 @@ FFIArchitecture class >> uniqueInstance [
^ uniqueInstance ifNil: [ uniqueInstance := self basicNew initialize ]
]

{ #category : #types }
FFIArchitecture >> bitTypeAlignment [

^ 1
]

{ #category : #types }
FFIArchitecture >> bitTypeSize [

^ self externalBitType byteSize
]

{ #category : #types }
FFIArchitecture >> externalBitType [

^ ExternalType signedByte
]

{ #category : #types }
FFIArchitecture >> externalLongType [
^ ExternalType long
Expand All @@ -49,6 +67,12 @@ FFIArchitecture >> externalSizeTType [
^ ExternalType ulong
]

{ #category : #types }
FFIArchitecture >> externalUBitType [

^ ExternalType unsignedByte
]

{ #category : #types }
FFIArchitecture >> externalULongType [
^ ExternalType ulong
Expand Down
39 changes: 39 additions & 0 deletions src/UnifiedFFI/FFIBit.class.st
@@ -0,0 +1,39 @@
"
I'm a signed bit type.
See my superclass for an explanation on why this exits.
"
Class {
#name : #FFIBit,
#superclass : #FFIUBit,
#category : #'UnifiedFFI-Types'
}

{ #category : #accessing }
FFIBit class >> externalType [
^ FFIArchitecture forCurrentArchitecture externalLongType
]

{ #category : #private }
FFIBit >> basicHandle: aHandle at: index [
^ aHandle platformBitAt: index
]

{ #category : #private }
FFIBit >> basicHandle: aHandle at: index put: value [
^ aHandle platformBitAt: index put: value
]

{ #category : #'private emitting code' }
FFIBit >> emitSelector [
^ 'platformBitAt'
]

{ #category : #'private emitting code' }
FFIBit >> offsetPointerReadFieldAt: offsetVariableName [
^ '^ExternalData
fromHandle: (handle {1}: {2})
type: FFIArchitecture forCurrentArchitecture externalBitType asPointerType'
format: {
self emitSelector.
offsetVariableName }
]
2 changes: 1 addition & 1 deletion src/UnifiedFFI/FFICallbackArgumentReader.class.st
Expand Up @@ -223,7 +223,7 @@ FFICallbackArgumentReader >> initialize [
currentStackOffset := 1.
extractedArguments := OrderedCollection new.

"If the function returns an struct by copy there is a hidden parameter with a pointer storing it"
"If the function returns an struct by copy there is a hidden parameter with a pointer storing it".
returnType := callback functionSpec returnType.
(returnType isExternalStructure and: [ returnType isPointer not ]) ifTrue: [
returnValueHolder := self stackPointer pointerAt: 1.
Expand Down
2 changes: 1 addition & 1 deletion src/UnifiedFFI/FFIExternalStructure.class.st
Expand Up @@ -106,7 +106,7 @@ FFIExternalStructure class >> defineFieldOffset: fieldName value: offset [
| offsetVarName |
offsetVarName := self offsetVariableNameFor: fieldName.
"Is this field defined in a superclass?"
(self superclass bindingOf: offsetVarName)
(superclass bindingOf: offsetVarName)
ifNil: [
(self hasClassVarNamed: offsetVarName)
ifFalse: [ self addClassVarNamed: offsetVarName ].
Expand Down
113 changes: 113 additions & 0 deletions src/UnifiedFFI/FFIUBit.class.st
@@ -0,0 +1,113 @@
"
I'm an unsigned bit.
Typically, you do not use this type directly but some struct implementations can be declared as one bit:
struct GdkEventKey {
...
guint is_modifier : 1;
};
the real problem is how platforms handle this field:
macOS and linux take it as an uint8, windows takes it as a uint.
Then, you want to use this to model the case.
"
Class {
#name : #FFIUBit,
#superclass : #FFIIntegerType,
#category : #'UnifiedFFI-Types'
}

{ #category : #accessing }
FFIUBit class >> externalType [
^ FFIArchitecture forCurrentArchitecture externalUBitType
]

{ #category : #accessing }
FFIUBit class >> externalTypeAlignment [

^ FFIArchitecture forCurrentArchitecture bitTypeAlignment
]

{ #category : #accessing }
FFIUBit class >> externalTypeSize [
^ FFIArchitecture forCurrentArchitecture bitTypeSize
]

{ #category : #private }
FFIUBit >> basicHandle: aHandle at: index [
^ aHandle platformUnsignedBitAt: index
]

{ #category : #private }
FFIUBit >> basicHandle: aHandle at: index put: value [
^ aHandle platformUnsignedBitAt: index put: value
]

{ #category : #'private emitting code' }
FFIUBit >> emitSelector [
^ 'platformUnsignedBitAt'
]

{ #category : #'private emitting code' }
FFIUBit >> offsetPointerReadFieldAt: offsetVariableName [
^ '^ExternalData
fromHandle: (handle {1}: {2})
type: FFIArchitecture forCurrentArchitecture externalUBitType asPointerType'
format: {
self emitSelector.
offsetVariableName }
]

{ #category : #'emitting code' }
FFIUBit >> offsetReadFieldAt: offsetVariableName [
self isPointer ifTrue: [
^ self offsetPointerReadFieldAt: offsetVariableName ].

^ String streamContents: [ :stream |
stream << '^handle ' << self emitSelector << ': ' << offsetVariableName ]
]

{ #category : #'emitting code' }
FFIUBit >> offsetWriteFieldAt: offsetVariableName with: valueName [
self isPointer ifTrue: [
^ self externalTypeWithArity
offsetWriteFieldAt: offsetVariableName
with: valueName ].

^ String streamContents: [ :stream |
stream
<< '^handle ' << self emitSelector << ': ' << offsetVariableName
<< ' put: ' << valueName ]
]

{ #category : #'private emitting code' }
FFIUBit >> pointerReadFieldAt: byteOffset [
"since offsetPointerReadFieldAt: receives a variable no matter what we use the trick of
just passing the offset as a string... it will work :)"
^ self offsetPointerReadFieldAt: byteOffset asString
]

{ #category : #'emitting code' }
FFIUBit >> readFieldAt: byteOffset [
self isPointer ifTrue: [
^ self pointerReadFieldAt: byteOffset ].

^ String streamContents: [ :stream |
stream << '^handle ' << self emitSelector << ': ' << byteOffset asString ].

]

{ #category : #'emitting code' }
FFIUBit >> writeFieldAt: byteOffset with: valueName [
self isPointer ifTrue: [
^ self externalTypeWithArity
writeFieldAt: byteOffset
with: valueName ].

^ String streamContents: [ :stream |
stream
<< '^handle ' << self emitSelector << ': ' << byteOffset asString
<< ' put: ' << valueName ]

]
18 changes: 18 additions & 0 deletions src/UnifiedFFI/FFI_x86_64_Windows.class.st
Expand Up @@ -19,11 +19,29 @@ FFI_x86_64_Windows class >> isActive [
^ Smalltalk vm wordSize = 8 and: [ OSPlatform current isWindows ]
]

{ #category : #types }
FFI_x86_64_Windows >> bitTypeAlignment [

^ OSPlatform current ffiLongAlignment
]

{ #category : #types }
FFI_x86_64_Windows >> externalBitType [

^ ExternalType long
]

{ #category : #types }
FFI_x86_64_Windows >> externalLongType [
^ ExternalType long
]

{ #category : #types }
FFI_x86_64_Windows >> externalUBitType [

^ ExternalType ulong
]

{ #category : #types }
FFI_x86_64_Windows >> externalULongType [
^ ExternalType ulong
Expand Down

0 comments on commit 48b482a

Please sign in to comment.