-
Notifications
You must be signed in to change notification settings - Fork 65
/
VMFFICallbacksTest.class.st
142 lines (97 loc) · 4.78 KB
/
VMFFICallbacksTest.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
Class {
#name : #VMFFICallbacksTest,
#superclass : #VMAbstractFFITest,
#category : #VMMakerTests
}
{ #category : #'tests - callbacks' }
VMFFICallbacksTest >> doCallout: tfExternalFunction with: parametersArray [
interpreter push: memory nilObject.
interpreter push: tfExternalFunction.
interpreter push: parametersArray.
interpreter argumentCount: 2.
interpreter primitiveSameThreadCallout.
]
{ #category : #'tests - callbacks' }
VMFFICallbacksTest >> testPrimitiveSameThreadCallbackInCalloutSuspendsActiveProcess [
| parametersArray tfExternalFunction oldActiveProcess callbackContext |
callbackContext := VMCallbackContext new.
tfExternalFunction := self createReturnFloatExternalFunctionFor: [
interpreter ptEnterInterpreterFromCallback: callbackContext ].
oldActiveProcess := interpreter activeProcess.
parametersArray := self newArrayWithSlots: 0.
interpreter push: memory nilObject.
interpreter push: tfExternalFunction.
interpreter push: parametersArray.
interpreter interpreteBlock: [ | oldActiveProcessContext |
"The test will enter the callout primitive, call this callback, assert and then finish.
We do not return from the callback in this test"
"Assert that at callback time:
- the process doing the callout is suspended (has a valid instruction pointer)
- not stored in the ready list
- not stored as active process"
oldActiveProcessContext := memory fetchPointer: SuspendedContextIndex ofObject: oldActiveProcess.
self assert: (interpreter isLiveContext: oldActiveProcessContext).
self deny: (self readyProcesses includes: oldActiveProcess).
^ self deny: interpreter activeProcess equals: oldActiveProcess ].
interpreter argumentCount: 2.
interpreter primitiveSameThreadCallout.
]
{ #category : #'tests - callbacks' }
VMFFICallbacksTest >> testPrimitiveSameThreadCallbackReturnKeepsAllOtherProcessesInReady [
| parametersArray tfExternalFunction callbackContext processBefore |
callbackContext := VMCallbackContext new.
callbackContext trampoline: ExitInterpreter new.
processBefore := self readyProcesses.
tfExternalFunction := self createReturnFloatExternalFunctionFor: [
[interpreter ptEnterInterpreterFromCallback: callbackContext] on: ExitInterpreter do: [ 3.14 ] ].
parametersArray := self newArrayWithSlots: 0.
interpreter push: memory nilObject.
interpreter push: tfExternalFunction.
interpreter push: parametersArray.
interpreter interpreteBlock: [ interpreter ptExitInterpreterToCallback: callbackContext ].
interpreter argumentCount: 2.
interpreter primitiveSameThreadCallout.
self assertCollection: self readyProcesses hasSameElements: processBefore
]
{ #category : #'tests - callbacks' }
VMFFICallbacksTest >> testPrimitiveSameThreadCallbackReturnResumesCalloutProcess [
| parametersArray tfExternalFunction oldActiveProcess callbackContext |
callbackContext := VMCallbackContext new.
callbackContext trampoline: ExitInterpreter new.
tfExternalFunction := self createReturnFloatExternalFunctionFor: [
[interpreter ptEnterInterpreterFromCallback: callbackContext]
on: ExitInterpreter do: [ 3.14 ] ].
oldActiveProcess := interpreter activeProcess.
parametersArray := self newArrayWithSlots: 0.
interpreter push: memory nilObject.
interpreter push: tfExternalFunction.
interpreter push: parametersArray.
interpreter interpreteBlock: [ interpreter ptExitInterpreterToCallback: callbackContext ].
interpreter argumentCount: 2.
interpreter primitiveSameThreadCallout.
self assert: interpreter activeProcess equals: oldActiveProcess.
]
{ #category : #'tests - callbacks' }
VMFFICallbacksTest >> testPrimitiveSameThreadReentrantCallbackRestoresCalloutProcess [
| parametersArray tfExternalFunction oldActiveProcess callbackContext numberOfCallbacks innerCallbackContext tfExternalFunction2 |
callbackContext := VMCallbackContext new.
callbackContext trampoline: ExitInterpreter new.
numberOfCallbacks := 0.
innerCallbackContext := VMCallbackContext new.
innerCallbackContext trampoline: ExitInterpreter new.
tfExternalFunction := self createReturnFloatExternalFunctionFor: [
[interpreter ptEnterInterpreterFromCallback: callbackContext]
on: ExitInterpreter do: [ 3.14 ] ].
tfExternalFunction2 := self createReturnFloatExternalFunctionFor: [
[interpreter ptEnterInterpreterFromCallback: innerCallbackContext]
on: ExitInterpreter do: [ 3.14 ] ].
oldActiveProcess := interpreter activeProcess.
parametersArray := self newArrayWithSlots: 0.
interpreter interpreteBlock: [
numberOfCallbacks := numberOfCallbacks + 1.
numberOfCallbacks = 1 ifTrue: [
self doCallout: tfExternalFunction2 with: parametersArray ].
interpreter ptExitInterpreterToCallback: callbackContext ].
self doCallout: tfExternalFunction with: parametersArray.
self assert: interpreter activeProcess equals: oldActiveProcess.
]