Mercurial > projects > dwt-mac
comparison dwt/internal/c/callback.d @ 1:8b48be5454ce
The internal cocoa classes compile now
author | Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com> |
---|---|
date | Tue, 19 Aug 2008 17:35:17 +0200 |
parents | 380af2bdd8e5 |
children | e831403a80a9 a329f9c3d66d |
comparison
equal
deleted
inserted
replaced
0:380af2bdd8e5 | 1:8b48be5454ce |
---|---|
11 * Port to the D Programming language: | 11 * Port to the D Programming language: |
12 * Jacob Carlborg <jacob.carlborg@gmail.com> | 12 * Jacob Carlborg <jacob.carlborg@gmail.com> |
13 *******************************************************************************/ | 13 *******************************************************************************/ |
14 module dwt.internal.c.callback; | 14 module dwt.internal.c.callback; |
15 | 15 |
16 /** | |
17 * Callback implementation. | |
18 */ | |
19 import dwt.dwthelper.utils; | |
16 import dwt.internal.Callback; | 20 import dwt.internal.Callback; |
21 | |
22 /* Header */ | |
23 | |
24 version (Win32) | |
25 { | |
26 import tango.sys.win32.UserGdi; | |
27 import tango.sys.win32.Types; | |
28 } | |
29 | |
30 else version (Win32_WCE) | |
31 { | |
32 import tango.sys.win32.UserGdi; | |
33 import tango.sys.win32.Types; | |
34 } | |
35 | |
36 else | |
37 alias RETURN_TYPE SWT_PTR; | |
38 | |
39 /* Implementation */ | |
17 | 40 |
18 alias size_t SWT_PTR; | 41 alias size_t SWT_PTR; |
19 | 42 |
20 struct CALLBACK_DATA | 43 struct CALLBACK_DATA |
21 { | 44 { |
39 int callbackEnabled = 1; | 62 int callbackEnabled = 1; |
40 int callbackEntryCount = 0; | 63 int callbackEntryCount = 0; |
41 int initialized = 0; | 64 int initialized = 0; |
42 } | 65 } |
43 | 66 |
44 | |
45 SWT_PTR callback(int index, ...); | 67 SWT_PTR callback(int index, ...); |
46 | 68 |
47 static if (USE_ASSEMBLER) | 69 static if (USE_ASSEMBLER) |
48 { | 70 { |
49 version (Win32){} | 71 version (Win32){} |
53 | 75 |
54 ubyte* callbackCode = null; | 76 ubyte* callbackCode = null; |
55 int CALLBACK_THUNK_SIZE = 64; | 77 int CALLBACK_THUNK_SIZE = 64; |
56 } | 78 } |
57 | 79 |
58 SWT_PTR Java_org_eclipse_swt_internal_Callback_bind (JNIEnv* env, jclass that, | 80 SWT_PTR bind (Callback callbackObject, Object object, String method, String signature, int argCount, boolean isStatic, boolean isArrayBased, SWT_PTR errorResult) |
59 jobject callbackObject, jobject object, jstring method, | |
60 jstring signature, jint argCount, jboolean isStatic, | |
61 jboolean isArrayBased, SWT_PTR errorResult) | |
62 { | 81 { |
63 int i; | 82 int i; |
64 jmethodID mid = null; | 83 jmethodID mid = null; |
65 jclass javaClass = that; | 84 jclass javaClass = that; |
66 const char* methodString = null; | 85 const char* methodString = null; |
69 if (jvm == null) | 88 if (jvm == null) |
70 (*env).GetJavaVM(env, &jvm); | 89 (*env).GetJavaVM(env, &jvm); |
71 | 90 |
72 if (!initialized) | 91 if (!initialized) |
73 { | 92 { |
74 memset(&callbackData, 0, sizeof(callbackData)); | 93 memset(&callbackData, 0, callbackData.sizeof); |
75 initialized = 1; | 94 initialized = 1; |
76 } | 95 } |
77 | 96 |
78 if (method) | 97 if (method) |
79 methodString = cast(/*const*/char*) (*env).GetStringUTFChars(env, | 98 methodString = cast(/*const*/char*) (*env).GetStringUTFChars(env, method, null); |
80 method, null); | |
81 | 99 |
82 if (signature) | 100 if (signature) |
83 sigString = cast(/*const*/char*) (*env).GetStringUTFChars(env, | 101 sigString = cast(/*const*/char*) (*env).GetStringUTFChars(env, signature, null); |
84 signature, null); | |
85 | 102 |
86 if (object && methodString && sigString) | 103 if (object && methodString && sigString) |
87 { | 104 { |
88 if (isStatic) | 105 if (isStatic) |
89 { | 106 { |
107 | 124 |
108 for (i = 0; i < MAX_CALLBACKS; i++) | 125 for (i = 0; i < MAX_CALLBACKS; i++) |
109 { | 126 { |
110 if (!callbackData[i].callback) | 127 if (!callbackData[i].callback) |
111 { | 128 { |
112 if ((callbackData[i].callback = (*env).NewGlobalRef(env, | 129 if ((callbackData[i].callback = (*env).NewGlobalRef(env, callbackObject)) == null) |
113 callbackObject)) == null) | |
114 goto fail; | 130 goto fail; |
115 | 131 |
116 if ((callbackData[i].object = (*env).NewGlobalRef(env, object)) == null) | 132 if ((callbackData[i].object = (*env).NewGlobalRef(env, object)) == null) |
117 goto fail; | 133 goto fail; |
118 | 134 |
131 | 147 |
132 if (callbackCode == null) | 148 if (callbackCode == null) |
133 { | 149 { |
134 version (Win32) | 150 version (Win32) |
135 { | 151 { |
136 callbackCode = VirtualAlloc(null, | 152 callbackCode = VirtualAlloc(null, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |
137 CALLBACK_THUNK_SIZE * MAX_CALLBACKS, | |
138 MEM_COMMIT, PAGE_EXECUTE_READWRITE); | |
139 if (callbackCode == null) | 153 if (callbackCode == null) |
140 return 0; | 154 return 0; |
141 } | 155 } |
142 | 156 |
143 else version (Win32_WCE) | 157 else version (Win32_WCE) |
144 { | 158 { |
145 callbackCode = VirtualAlloc(null, | 159 callbackCode = VirtualAlloc(null, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |
146 CALLBACK_THUNK_SIZE * MAX_CALLBACKS, | |
147 MEM_COMMIT, PAGE_EXECUTE_READWRITE); | |
148 if (callbackCode == null) | 160 if (callbackCode == null) |
149 return 0; | 161 return 0; |
150 } | 162 } |
151 | 163 |
152 else | 164 else |
153 { | 165 { |
154 callbackCode = mmap(null, | 166 callbackCode = mmap(null, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); |
155 CALLBACK_THUNK_SIZE * MAX_CALLBACKS, | |
156 PROT_EXEC | PROT_READ | PROT_WRITE, | |
157 MAP_PRIVATE | MAP_ANON, -1, 0); | |
158 if (callbackCode == MAP_FAILED) | 167 if (callbackCode == MAP_FAILED) |
159 return 0; | 168 return 0; |
160 } | 169 } |
161 } | 170 } |
162 code = cast(ubyte*) (callbackCode + (i * CALLBACK_THUNK_SIZE)); | 171 code = cast(ubyte*) (callbackCode + (i * CALLBACK_THUNK_SIZE)); |
169 code[j++] = 0xec; | 178 code[j++] = 0xec; |
170 | 179 |
171 version (darwin) | 180 version (darwin) |
172 { | 181 { |
173 /* darwin calling conventions require that the stack be aligned on a 16-byte boundary. */ | 182 /* darwin calling conventions require that the stack be aligned on a 16-byte boundary. */ |
174 k = (argCount + 3) * sizeof(SWT_PTR); | 183 k = (argCount + 3) * SWT_PTR.sizeof; |
175 pad = ((k + 15) & ~15) - k; | 184 pad = ((k + 15) & ~15) - k; |
176 if (pad > 0) | 185 if (pad > 0) |
177 { | 186 { |
178 //SUB ESP,pad - 3 bytes | 187 //SUB ESP,pad - 3 bytes |
179 code[j++] = 0x83; | 188 code[j++] = 0x83; |
181 code[j++] = pad; | 190 code[j++] = pad; |
182 } | 191 } |
183 } | 192 } |
184 | 193 |
185 // 3*argCount bytes | 194 // 3*argCount bytes |
186 for (k = (argCount + 1) * sizeof(SWT_PTR); k >= sizeof(SWT_PTR) * 2; k -= sizeof( | 195 for (k = (argCount + 1) * SWT_PTR.sizeof; k >= SWT_PTR.sizeof * 2; k -= SWT_PTR.sizeof) |
187 SWT_PTR)) | |
188 { | 196 { |
189 //PUSH SS:[EBP+k] | 197 //PUSH SS:[EBP+k] |
190 code[j++] = 0xff; | 198 code[j++] = 0xff; |
191 code[j++] = 0x75; | 199 code[j++] = 0x75; |
192 code[j++] = k; | 200 code[j++] = k; |
206 //PUSH i - 2 bytes | 214 //PUSH i - 2 bytes |
207 code[j++] = 0x6a; | 215 code[j++] = 0x6a; |
208 code[j++] = i; | 216 code[j++] = i; |
209 } | 217 } |
210 | 218 |
211 //MOV EAX callback - 1 + sizeof(SWT_PTR) bytes | 219 //MOV EAX callback - 1 + SWT_PTR.sizeof bytes |
212 code[j++] = 0xb8; | 220 code[j++] = 0xb8; |
213 (cast(SWT_PTR*) &code[j])[0] = cast(SWT_PTR) &callback; | 221 (cast(SWT_PTR*) &code[j])[0] = cast(SWT_PTR) &callback; |
214 j += sizeof(SWT_PTR); | 222 j += SWT_PTR.sizeof; |
215 | 223 |
216 //CALL EAX - 2 bytes | 224 //CALL EAX - 2 bytes |
217 code[j++] = 0xff; | 225 code[j++] = 0xff; |
218 code[j++] = 0xd0; | 226 code[j++] = 0xd0; |
219 | 227 |
220 //ADD ESP,(argCount + 1) * sizeof(SWT_PTR) - 3 bytes | 228 //ADD ESP,(argCount + 1) * SWT_PTR.sizeof - 3 bytes |
221 code[j++] = 0x83; | 229 code[j++] = 0x83; |
222 code[j++] = 0xc4; | 230 code[j++] = 0xc4; |
223 | 231 |
224 version (darwin) | 232 version (darwin) |
225 code[j++] = cast(ubyte) (pad + ((argCount + 1) * sizeof( | 233 code[j++] = cast(ubyte) (pad + ((argCount + 1) * SWT_PTR.sizeof)); |
226 SWT_PTR))); | |
227 else | 234 else |
228 code[j++] = cast(ubyte) ((argCount + 1) * sizeof(SWT_PTR)); | 235 code[j++] = cast(ubyte) ((argCount + 1) * SWT_PTR.sizeof); |
229 | 236 |
230 //POP EBP - 1 byte | 237 //POP EBP - 1 byte |
231 code[j++] = 0x5d; | 238 code[j++] = 0x5d; |
232 | 239 |
233 version (Win32) | 240 version (Win32) |
234 { | 241 { |
235 // RETN argCount * sizeof(SWT_PTR) - 3 bytes | 242 // RETN argCount * SWT_PTR.sizeof - 3 bytes |
236 code[j++] = 0xc2; | 243 code[j++] = 0xc2; |
237 code[j++] = cast(ubyte) (argCount * sizeof(SWT_PTR)); | 244 code[j++] = cast(ubyte) (argCount * SWT_PTR.sizeof); |
238 code[j++] = 0x00; | 245 code[j++] = 0x00; |
239 } | 246 } |
240 | 247 |
241 else version (Win32_WCE) | 248 else version (Win32_WCE) |
242 { | 249 { |
243 // RETN argCount * sizeof(SWT_PTR) - 3 bytes | 250 // RETN argCount * SWT_PTR.sizeof - 3 bytes |
244 code[j++] = 0xc2; | 251 code[j++] = 0xc2; |
245 code[j++] = cast(ubyte) (argCount * sizeof(SWT_PTR)); | 252 code[j++] = cast(ubyte) (argCount * SWT_PTR.sizeof); |
246 code[j++] = 0x00; | 253 code[j++] = 0x00; |
247 } | 254 } |
248 | 255 |
249 else | 256 else |
250 { | 257 { |
252 code[j++] = 0xc3; | 259 code[j++] = 0xc3; |
253 } | 260 } |
254 | 261 |
255 if (j > CALLBACK_THUNK_SIZE) | 262 if (j > CALLBACK_THUNK_SIZE) |
256 { | 263 { |
257 jclass | 264 jclass errorClass = (*env).FindClass(env, "java/lang/Error"); |
258 errorClass = (*env).FindClass(env, | |
259 "java/lang/Error"); | |
260 (*env).ThrowNew(env, errorClass, "Callback thunk overflow"); | 265 (*env).ThrowNew(env, errorClass, "Callback thunk overflow"); |
261 } | 266 } |
262 | 267 |
263 return cast(SWT_PTR) code; | 268 return cast(SWT_PTR) code; |
264 } | 269 } |
265 } | 270 } |
266 } | 271 } |
267 | 272 |
268 fail: | 273 fail: |
269 return 0; | 274 return 0; |
270 } | 275 } |