Skip to content

Commit

Permalink
Separating old ValueArgument from ConstantArgument.
Browse files Browse the repository at this point in the history
New parse=>resolve works similarly to parse+resolve
  • Loading branch information
guillep committed Sep 27, 2019
1 parent ba1e10d commit 1a8ffbc
Show file tree
Hide file tree
Showing 11 changed files with 345 additions and 39 deletions.
49 changes: 49 additions & 0 deletions src/UnifiedFFI-Tests/FFIAbstractTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Class {
#name : #FFIAbstractTest,
#superclass : #TestCase,
#instVars : [
'intType',
'int32Type',
'voidType',
'charType'
],
#category : #'UnifiedFFI-Tests-Tests'
}

{ #category : #private }
FFIAbstractTest >> externalTypeAlias: aTypeName [

"Prefix the type so we have control over it.
If it is already prefixed, do not prefix it (otherwise this loops)."
(aTypeName beginsWith: '_test_type_')
ifTrue: [ ^ aTypeName ].
^ '_test_type_', aTypeName
]

{ #category : #private }
FFIAbstractTest >> ffiBindingOf: aString [

aString = '_test_type_int'
ifTrue: [ ^ aString -> intType ].
aString = '_test_type_bool'
ifTrue: [ ^ aString -> int32Type ].
aString = '_test_type_uint32'
ifTrue: [ ^ aString -> int32Type ].
aString = '_test_type_int32'
ifTrue: [ ^ aString -> int32Type ].
aString = '_test_type_void'
ifTrue: [ ^ aString -> voidType ].
aString = '_test_type_char'
ifTrue: [ ^ aString -> charType ].
self error: 'Type not recognized: ', aString
]

{ #category : #running }
FFIAbstractTest >> setUp [

super setUp.
intType := FFIInt32.
int32Type := FFIInt32.
voidType := FFIVoid.
charType := FFICharacterType.
]
68 changes: 63 additions & 5 deletions src/UnifiedFFI-Tests/FFIFunctionParserTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ Tests for FFIFunctionParser
"
Class {
#name : #FFIFunctionParserTest,
#superclass : #TestCase,
#superclass : #FFIAbstractTest,
#instVars : [
'ctx',
'resolver'
],
#category : #'UnifiedFFI-Tests-Tests'
}

Expand Down Expand Up @@ -61,11 +65,42 @@ FFIFunctionParserTest >> assertValue: aLiteralArgument is: aValue [
self assert: aLiteralArgument value equals: aValue
]

{ #category : #helpers }
FFIFunctionParserTest >> ffiInstVarArgument: argName generator: aGenerator [

^ FFIInstVarArgument new
argName: argName;
yourself
]

{ #category : #factory }
FFIFunctionParserTest >> newParser [
^ FFIFunctionParser new
]

{ #category : #factory }
FFIFunctionParserTest >> newParserWithRequestor [

^ FFIFunctionParser new
requestor: resolver;
yourself
]

{ #category : #factory }
FFIFunctionParserTest >> setUp [

super setUp.
ctx := Context
sender: nil
receiver: FFITestObject new
method: FFITestObject>>#b:d:
arguments: #( 25 17 ).

resolver := FFICallout new
sender: ctx;
yourself
]

{ #category : #tests }
FFIFunctionParserTest >> testEmptyArgumentReturnsNil [
| parser |
Expand All @@ -88,7 +123,7 @@ FFIFunctionParserTest >> testParseAnonymousFunction [

self assert: parser isAnonymous.
self assert: parser functionName isNil.
self assert: parser returnType equals: #('int' 2).
self assert: parser returnType asOldArraySpec equals: #('int' 2).

args := parser arguments.
self assert: args size equals: 8.
Expand All @@ -114,7 +149,7 @@ FFIFunctionParserTest >> testParseAnonymousFunctionNoArguments [

self assert: parser isAnonymous.
self assert: parser functionName isNil.
self assert: parser returnType equals: #('int' 2).
self assert: parser returnType asOldArraySpec equals: #('int' 2).

args := parser arguments.
self assert: args size equals: 0 ]
Expand All @@ -130,7 +165,7 @@ FFIFunctionParserTest >> testParseFunction [
parser := self newParser parseNamedFunction: spec.

self assert: parser functionName equals: 'function_n$a$m$e'.
self assert: parser returnType equals: #('int' 2).
self assert: parser returnType asOldArraySpec equals: #('int' 2).

args := parser arguments.
self assert: args size equals: 8.
Expand All @@ -147,6 +182,29 @@ FFIFunctionParserTest >> testParseFunction [

]

{ #category : #tests }
FFIFunctionParserTest >> testParseFunction2 [
#((int * * #'function_n$a$m$e' ( 0, nil, -10," FOO_BAR , "int a, int* _b, char** c, void* * * d_))
" ' int * * function_n$a$m$e (0, nil, -10, FOO_BAR , int a, int* _b, char** c, void* * * d_ )'" )
do: [:spec | | functionSpec1 functionSpec2 method1 method2 builder |
functionSpec1 := self newParser parseNamedFunction: spec.
functionSpec1 resolveUsing: resolver.

functionSpec2 := self newParserWithRequestor parseNamedFunction: spec.

builder := (FFICalloutMethodBuilder calloutAPI: (FFICalloutAPI inContext: nil))
sender: ctx;
yourself.
"signature: functionSignature;
sender: sender."
method1 := builder generateMethodFromSpec: functionSpec1.
method2 := builder generateMethodFromSpec: functionSpec2.
self assert: method1 bytecode equals: method2 bytecode.
self assert: method1 literals allButFirst equals: method2 literals allButFirst.
self assert: (method1 literals first analogousCodeTo: method2 literals first) ].

]

{ #category : #tests }
FFIFunctionParserTest >> testParseFunctionNoArguments [
| parser args |
Expand All @@ -157,7 +215,7 @@ FFIFunctionParserTest >> testParseFunctionNoArguments [
parser := self newParser parseNamedFunction: spec.

self assert: parser functionName equals: 'function_name'.
self assert: parser returnType equals: #('int' 2).
self assert: parser returnType asOldArraySpec equals: #('int' 2).

args := parser arguments.
self assert: args size equals: 0 ]
Expand Down
32 changes: 4 additions & 28 deletions src/UnifiedFFI-Tests/FFIFunctionResolutionTest.class.st
Original file line number Diff line number Diff line change
@@ -1,34 +1,12 @@
Class {
#name : #FFIFunctionResolutionTest,
#superclass : #TestCase,
#superclass : #FFIAbstractTest,
#instVars : [
'stack',
'intType',
'int32Type'
'stack'
],
#category : #'UnifiedFFI-Tests-Tests'
}

{ #category : #helpers }
FFIFunctionResolutionTest >> externalTypeAlias: aTypeName [

"Prefix the type so we have control over it.
If it is already prefixed, do not prefix it (otherwise this loops)."
(aTypeName beginsWith: '_test_type_')
ifTrue: [ ^ aTypeName ].
^ '_test_type_', aTypeName
]

{ #category : #helpers }
FFIFunctionResolutionTest >> ffiBindingOf: aString [

aString = '_test_type_int'
ifTrue: [ ^ aString -> intType ].
aString = '_test_type_bool'
ifTrue: [ ^ aString -> int32Type ].
self error: 'Type not recognized: ', aString
]

{ #category : #helpers }
FFIFunctionResolutionTest >> pushInstVar: anInteger [

Expand Down Expand Up @@ -64,8 +42,6 @@ FFIFunctionResolutionTest >> setUp [

super setUp.
stack := Stack new.
intType := FFITestType new.
int32Type := FFITestType new.
]

{ #category : #tests }
Expand Down Expand Up @@ -116,7 +92,7 @@ FFIFunctionResolutionTest >> testResolveArgumentVariableWithExplicitTypeResolves

argument resolveUsing: resolver.

self assert: argument resolvedType equals: intType
self assert: argument resolvedType class equals: intType
]

{ #category : #tests }
Expand Down Expand Up @@ -158,7 +134,7 @@ FFIFunctionResolutionTest >> testResolveConstantFalseShouldSetConstantZeroLoader

argument resolveUsing: resolver.

self assert: argument resolvedType equals: int32Type
self assert: argument resolvedType class equals: int32Type
]

{ #category : #tests }
Expand Down
15 changes: 15 additions & 0 deletions src/UnifiedFFI-Tests/FFITestObject.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Class {
#name : #FFITestObject,
#superclass : #Object,
#instVars : [
'a',
'c'
],
#category : #'UnifiedFFI-Tests-Tests'
}

{ #category : #'as yet unclassified' }
FFITestObject >> b: _b d: d_ [

"some method to bind an ffi callout"
]
22 changes: 21 additions & 1 deletion src/UnifiedFFI-Tests/FFITestType.class.st
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
Class {
#name : #FFITestType,
#superclass : #FFIExternalType,
#instVars : [
'type'
],
#category : #'UnifiedFFI-Tests-Tests'
}

{ #category : #'instance creation' }
FFITestType class >> of: aType [

^ self new type: aType; yourself
]

{ #category : #converting }
FFITestType >> asExternalTypeOn: aTypeResolver [

"FFI sends this to us expecting us to be a class most of the times, but for testing purposes, we use an instance."
^ self
^ self copy
]

{ #category : #accessing }
FFITestType >> externalType [

^ type externalType
]

{ #category : #accessing }
FFITestType >> type: anObject [
type := anObject
]
Loading

0 comments on commit 1a8ffbc

Please sign in to comment.