This repository has been archived by the owner on Jan 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
sameThread.c
150 lines (116 loc) · 4.19 KB
/
sameThread.c
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
143
144
145
146
147
148
149
150
#include "setjmp.h"
#include "PThreadedPlugin.h"
#include "pharovm/vmCallback.h"
/*
* Define sigsetjmp and siglongjmp to be the most minimal setjmp/longjmp available on the platform.
* Note: on windows 64 via mingw-w64, the 2nd argument NULL to _setjmp prevents stack unwinding
*/
#undef sigsetjmp
#undef siglongjmp
#if _MSC_VER
# define sigsetjmp(jb,ssmf) _setjmp(jb)
# define siglongjmp(jb,v) longjmp(jb,v)
#elif _WIN64 && __GNUC__
# define sigsetjmp(jb,ssmf) _setjmp(jb,NULL)
# define siglongjmp(jb,v) longjmp(jb,v)
#elif _WIN32
# define sigsetjmp(jb,ssmf) setjmp(jb)
# define siglongjmp(jb,v) longjmp(jb,v)
#else
# define sigsetjmp(jb,ssmf) _setjmp(jb)
# define siglongjmp(jb,v) _longjmp(jb,v)
#endif
void sameThreadCallbackEnter(struct _Runner* runner, struct _CallbackInvocation* callback);
void sameThreadCallbackExit(struct _Runner* runner, struct _CallbackInvocation* callback);
void sameThreadPrepareCallback(struct _Runner* runner, struct _CallbackInvocation* callback);
static Runner sameThreadRunner = {
sameThreadCallbackEnter,
sameThreadCallbackExit,
sameThreadPrepareCallback,
NULL
};
/* primitivePerformWorkerCall
*
* receiver: A worker <TFWorker>
*
* arguments:
* 3 - externalFunction <ExternalAddress>
* 2 - arguments <ExternalAddress>
* 1 - returnHolder <ExternalAddress>
* 0 - SemaphoreIndex <Integer>
*/
// This is just because arguments are placed in order in stack, then they are inverse. And is confusing ;)
#define PARAM_EXTERNAL_FUNCTION 3
#define PARAM_ARGUMENTS 2
#define PARAM_RETURN_HOLDER 1
#define PARAM_SEMAPHORE_INDEX 0
PrimitiveWithDepth(primitiveSameThreadCallout, 2) {
void *cif;
void *externalFunction;
void *parameters;
void *returnHolder;
sqInt receiver;
sqInt semaphoreIndex;
returnHolder = readAddress(interpreterProxy->stackValue(PARAM_RETURN_HOLDER));
checkFailed();
parameters = readAddress(interpreterProxy->stackValue(PARAM_ARGUMENTS));
checkFailed();
externalFunction = getHandler(interpreterProxy->stackValue(PARAM_EXTERNAL_FUNCTION));
checkFailed();
//Getting the function CIF of LibFFI
cif = getHandler(interpreterProxy->fetchPointerofObject(1, interpreterProxy->stackValue(PARAM_EXTERNAL_FUNCTION)));
checkFailed();
//Getting the function CIF of LibFFI
cif = getHandler(interpreterProxy->fetchPointerofObject(1, interpreterProxy->stackValue(PARAM_EXTERNAL_FUNCTION)));
checkFailed();
semaphoreIndex = interpreterProxy->stackIntegerValue(PARAM_SEMAPHORE_INDEX);
checkFailed();
receiver = getReceiver();
checkFailed();
ffi_call(cif,
externalFunction,
returnHolder,
parameters);
interpreterProxy->signalSemaphoreWithIndex(semaphoreIndex);
checkFailed();
primitiveEnd();
}
Primitive(primitiveGetSameThreadRunnerAddress) {
sqInt externalAddress;
externalAddress = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalAddress(), sizeof(void*));
checkFailed();
writeAddress(externalAddress, &sameThreadRunner);
checkFailed();
primitiveEndReturn(externalAddress);
}
void sameThreadCallbackEnter(struct _Runner* runner, struct _CallbackInvocation* callback){
VMCallbackContext *vmcc;
sqInt flags;
// if ((flags = interpreterProxy->ownVM(0)) < 0) {
// fprintf(stderr,"Warning; callback failed to own the VM\n");
// return;
// }
vmcc = malloc(sizeof(VMCallbackContext));
callback->payload = vmcc;
if ((!sigsetjmp(vmcc->trampoline, 0))) {
//Used to mark that is a fake callback!
vmcc->thunkp = NULL;
vmcc->stackp = NULL;
vmcc->intregargsp = NULL;
vmcc->floatregargsp = NULL;
interpreterProxy->ptEnterInterpreterFromCallback(vmcc);
fprintf(stderr,"Warning; callback failed to invoke\n");
// interpreterProxy->disownVM(flags);
return;
}
free(vmcc);
// interpreterProxy->disownVM(flags);
}
void sameThreadCallbackExit(struct _Runner* runner, struct _CallbackInvocation* callback){
VMCallbackContext *vmcc;
vmcc = (VMCallbackContext*)callback->payload;
interpreterProxy->ptExitInterpreterToCallback(vmcc);
}
void sameThreadPrepareCallback(struct _Runner* runner, struct _CallbackInvocation* callback){
// I do not do nothing
}