Mercurial > projects > dwt-mac
comparison dwt/internal/c/callback.d @ 0:380af2bdd8e5
Upload of whole dwt tree
author | Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com> |
---|---|
date | Sat, 09 Aug 2008 17:00:02 +0200 |
parents | |
children | 8b48be5454ce |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:380af2bdd8e5 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * | |
11 * Port to the D Programming language: | |
12 * Jacob Carlborg <jacob.carlborg@gmail.com> | |
13 *******************************************************************************/ | |
14 module dwt.internal.c.callback; | |
15 | |
16 import dwt.internal.Callback; | |
17 | |
18 alias size_t SWT_PTR; | |
19 | |
20 struct CALLBACK_DATA | |
21 { | |
22 Callback callback; | |
23 jmethodID methodID; | |
24 Object object; | |
25 bool isStatic; | |
26 bool isArrayBased; | |
27 int argCount; | |
28 SWT_PTR errorResult; | |
29 } | |
30 | |
31 bool USE_ASSEMBLER = false; | |
32 | |
33 version (X86) | |
34 bool USE_ASSEMBLER = true; | |
35 | |
36 private | |
37 { | |
38 CALLBACK_DATA callbackData[MAX_CALLBACKS]; | |
39 int callbackEnabled = 1; | |
40 int callbackEntryCount = 0; | |
41 int initialized = 0; | |
42 } | |
43 | |
44 | |
45 SWT_PTR callback(int index, ...); | |
46 | |
47 static if (USE_ASSEMBLER) | |
48 { | |
49 version (Win32){} | |
50 else version (Win32_WCE){} | |
51 else | |
52 import tango.stdc.posix.sys.mman; | |
53 | |
54 ubyte* callbackCode = null; | |
55 int CALLBACK_THUNK_SIZE = 64; | |
56 } | |
57 | |
58 SWT_PTR Java_org_eclipse_swt_internal_Callback_bind (JNIEnv* env, jclass that, | |
59 jobject callbackObject, jobject object, jstring method, | |
60 jstring signature, jint argCount, jboolean isStatic, | |
61 jboolean isArrayBased, SWT_PTR errorResult) | |
62 { | |
63 int i; | |
64 jmethodID mid = null; | |
65 jclass javaClass = that; | |
66 const char* methodString = null; | |
67 const char* sigString = null; | |
68 | |
69 if (jvm == null) | |
70 (*env).GetJavaVM(env, &jvm); | |
71 | |
72 if (!initialized) | |
73 { | |
74 memset(&callbackData, 0, sizeof(callbackData)); | |
75 initialized = 1; | |
76 } | |
77 | |
78 if (method) | |
79 methodString = cast(/*const*/char*) (*env).GetStringUTFChars(env, | |
80 method, null); | |
81 | |
82 if (signature) | |
83 sigString = cast(/*const*/char*) (*env).GetStringUTFChars(env, | |
84 signature, null); | |
85 | |
86 if (object && methodString && sigString) | |
87 { | |
88 if (isStatic) | |
89 { | |
90 mid = (*env).GetStaticMethodID(env, object, methodString, sigString); | |
91 } | |
92 else | |
93 { | |
94 javaClass = (*env).GetObjectClass(env, object); | |
95 mid = (*env).GetMethodID(env, javaClass, methodString, sigString); | |
96 } | |
97 } | |
98 | |
99 if (method && methodString) | |
100 (*env).ReleaseStringUTFChars(env, method, methodString); | |
101 | |
102 if (signature && sigString) | |
103 (*env).ReleaseStringUTFChars(env, signature, sigString); | |
104 | |
105 if (mid == 0) | |
106 goto fail; | |
107 | |
108 for (i = 0; i < MAX_CALLBACKS; i++) | |
109 { | |
110 if (!callbackData[i].callback) | |
111 { | |
112 if ((callbackData[i].callback = (*env).NewGlobalRef(env, | |
113 callbackObject)) == null) | |
114 goto fail; | |
115 | |
116 if ((callbackData[i].object = (*env).NewGlobalRef(env, object)) == null) | |
117 goto fail; | |
118 | |
119 callbackData[i].isStatic = isStatic; | |
120 callbackData[i].isArrayBased = isArrayBased; | |
121 callbackData[i].argCount = argCount; | |
122 callbackData[i].errorResult = errorResult; | |
123 callbackData[i].methodID = mid; | |
124 | |
125 static if (!USE_ASSEMBLER) | |
126 return cast(SWT_PTR) fnx_array[argCount][i]; | |
127 | |
128 { | |
129 int j = 0, k, pad = 0; | |
130 ubyte* code; | |
131 | |
132 if (callbackCode == null) | |
133 { | |
134 version (Win32) | |
135 { | |
136 callbackCode = VirtualAlloc(null, | |
137 CALLBACK_THUNK_SIZE * MAX_CALLBACKS, | |
138 MEM_COMMIT, PAGE_EXECUTE_READWRITE); | |
139 if (callbackCode == null) | |
140 return 0; | |
141 } | |
142 | |
143 else version (Win32_WCE) | |
144 { | |
145 callbackCode = VirtualAlloc(null, | |
146 CALLBACK_THUNK_SIZE * MAX_CALLBACKS, | |
147 MEM_COMMIT, PAGE_EXECUTE_READWRITE); | |
148 if (callbackCode == null) | |
149 return 0; | |
150 } | |
151 | |
152 else | |
153 { | |
154 callbackCode = mmap(null, | |
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) | |
159 return 0; | |
160 } | |
161 } | |
162 code = cast(ubyte*) (callbackCode + (i * CALLBACK_THUNK_SIZE)); | |
163 | |
164 //PUSH EBP - 1 byte | |
165 code[j++] = 0x55; | |
166 | |
167 //MOV EBP,ESP - 2 bytes | |
168 code[j++] = 0x8b; | |
169 code[j++] = 0xec; | |
170 | |
171 version (darwin) | |
172 { | |
173 /* darwin calling conventions require that the stack be aligned on a 16-byte boundary. */ | |
174 k = (argCount + 3) * sizeof(SWT_PTR); | |
175 pad = ((k + 15) & ~15) - k; | |
176 if (pad > 0) | |
177 { | |
178 //SUB ESP,pad - 3 bytes | |
179 code[j++] = 0x83; | |
180 code[j++] = 0xec; | |
181 code[j++] = pad; | |
182 } | |
183 } | |
184 | |
185 // 3*argCount bytes | |
186 for (k = (argCount + 1) * sizeof(SWT_PTR); k >= sizeof(SWT_PTR) * 2; k -= sizeof( | |
187 SWT_PTR)) | |
188 { | |
189 //PUSH SS:[EBP+k] | |
190 code[j++] = 0xff; | |
191 code[j++] = 0x75; | |
192 code[j++] = k; | |
193 } | |
194 | |
195 if (i > 127) | |
196 { | |
197 //PUSH i - 5 bytes | |
198 code[j++] = 0x68; | |
199 code[j++] = ((i >> 0) & 0xFF); | |
200 code[j++] = ((i >> 8) & 0xFF); | |
201 code[j++] = ((i >> 16) & 0xFF); | |
202 code[j++] = ((i >> 24) & 0xFF); | |
203 } | |
204 else | |
205 { | |
206 //PUSH i - 2 bytes | |
207 code[j++] = 0x6a; | |
208 code[j++] = i; | |
209 } | |
210 | |
211 //MOV EAX callback - 1 + sizeof(SWT_PTR) bytes | |
212 code[j++] = 0xb8; | |
213 (cast(SWT_PTR*) &code[j])[0] = cast(SWT_PTR) &callback; | |
214 j += sizeof(SWT_PTR); | |
215 | |
216 //CALL EAX - 2 bytes | |
217 code[j++] = 0xff; | |
218 code[j++] = 0xd0; | |
219 | |
220 //ADD ESP,(argCount + 1) * sizeof(SWT_PTR) - 3 bytes | |
221 code[j++] = 0x83; | |
222 code[j++] = 0xc4; | |
223 | |
224 version (darwin) | |
225 code[j++] = cast(ubyte) (pad + ((argCount + 1) * sizeof( | |
226 SWT_PTR))); | |
227 else | |
228 code[j++] = cast(ubyte) ((argCount + 1) * sizeof(SWT_PTR)); | |
229 | |
230 //POP EBP - 1 byte | |
231 code[j++] = 0x5d; | |
232 | |
233 version (Win32) | |
234 { | |
235 // RETN argCount * sizeof(SWT_PTR) - 3 bytes | |
236 code[j++] = 0xc2; | |
237 code[j++] = cast(ubyte) (argCount * sizeof(SWT_PTR)); | |
238 code[j++] = 0x00; | |
239 } | |
240 | |
241 else version (Win32_WCE) | |
242 { | |
243 // RETN argCount * sizeof(SWT_PTR) - 3 bytes | |
244 code[j++] = 0xc2; | |
245 code[j++] = cast(ubyte) (argCount * sizeof(SWT_PTR)); | |
246 code[j++] = 0x00; | |
247 } | |
248 | |
249 else | |
250 { | |
251 // RETN - 1 byte | |
252 code[j++] = 0xc3; | |
253 } | |
254 | |
255 if (j > CALLBACK_THUNK_SIZE) | |
256 { | |
257 jclass | |
258 errorClass = (*env).FindClass(env, | |
259 "java/lang/Error"); | |
260 (*env).ThrowNew(env, errorClass, "Callback thunk overflow"); | |
261 } | |
262 | |
263 return cast(SWT_PTR) code; | |
264 } | |
265 } | |
266 } | |
267 | |
268 fail: | |
269 return 0; | |
270 } |