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 }