Mercurial > projects > dwt-mac
view dwt/internal/c/callback.d @ 7:e831403a80a9
Add 'cast' to casts
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Wed, 27 Aug 2008 14:30:35 +0200 |
parents | 8b48be5454ce |
children | 30a762abda2a |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2000, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * * Port to the D Programming language: * Jacob Carlborg <jacob.carlborg@gmail.com> *******************************************************************************/ module dwt.internal.c.callback; /** * Callback implementation. */ import dwt.dwthelper.utils; import dwt.internal.Callback; /* Header */ version cast(Win32) { import tango.sys.win32.UserGdi; import tango.sys.win32.Types; } else version cast(Win32_WCE) { import tango.sys.win32.UserGdi; import tango.sys.win32.Types; } else alias RETURN_TYPE SWT_PTR; /* Implementation */ alias size_t SWT_PTR; struct CALLBACK_DATA { Callback callback; jmethodID methodID; Object object; bool isStatic; bool isArrayBased; int argCount; SWT_PTR errorResult; } bool USE_ASSEMBLER = false; version cast(X86) bool USE_ASSEMBLER = true; private { CALLBACK_DATA callbackData[MAX_CALLBACKS]; int callbackEnabled = 1; int callbackEntryCount = 0; int initialized = 0; } SWT_PTR callback(int index, ...); static if (USE_ASSEMBLER) { version cast(Win32){} else version cast(Win32_WCE){} else import tango.stdc.posix.sys.mman; ubyte* callbackCode = null; int CALLBACK_THUNK_SIZE = 64; } SWT_PTR bind (Callback callbackObject, Object object, String method, String signature, int argCount, boolean isStatic, boolean isArrayBased, SWT_PTR errorResult) { int i; jmethodID mid = null; jclass javaClass = that; const char* methodString = null; const char* sigString = null; if (jvm == null) (*env).GetJavaVM(env, &jvm); if (!initialized) { memset(&callbackData, 0, callbackData.sizeof); initialized = 1; } if (method) methodString = cast(/*const*/char*) (*env).GetStringUTFChars(env, method, null); if (signature) sigString = cast(/*const*/char*) (*env).GetStringUTFChars(env, signature, null); if (object && methodString && sigString) { if (isStatic) { mid = (*env).GetStaticMethodID(env, object, methodString, sigString); } else { javaClass = (*env).GetObjectClass(env, object); mid = (*env).GetMethodID(env, javaClass, methodString, sigString); } } if (method && methodString) (*env).ReleaseStringUTFChars(env, method, methodString); if (signature && sigString) (*env).ReleaseStringUTFChars(env, signature, sigString); if (mid == 0) goto fail; for (i = 0; i < MAX_CALLBACKS; i++) { if (!callbackData[i].callback) { if ((callbackData[i].callback = (*env).NewGlobalRef(env, callbackObject)) == null) goto fail; if ((callbackData[i].object = (*env).NewGlobalRef(env, object)) == null) goto fail; callbackData[i].isStatic = isStatic; callbackData[i].isArrayBased = isArrayBased; callbackData[i].argCount = argCount; callbackData[i].errorResult = errorResult; callbackData[i].methodID = mid; static if (!USE_ASSEMBLER) return cast(SWT_PTR) fnx_array[argCount][i]; { int j = 0, k, pad = 0; ubyte* code; if (callbackCode == null) { version cast(Win32) { callbackCode = VirtualAlloc(null, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (callbackCode == null) return 0; } else version cast(Win32_WCE) { callbackCode = VirtualAlloc(null, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (callbackCode == null) return 0; } else { callbackCode = mmap(null, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (callbackCode == MAP_FAILED) return 0; } } code = cast(ubyte*) (callbackCode + (i * CALLBACK_THUNK_SIZE)); //PUSH EBP - 1 byte code[j++] = 0x55; //MOV EBP,ESP - 2 bytes code[j++] = 0x8b; code[j++] = 0xec; version (darwin) { /* darwin calling conventions require that the stack be aligned on a 16-byte boundary. */ k = (argCount + 3) * SWT_PTR.sizeof; pad = ((k + 15) & ~15) - k; if (pad > 0) { //SUB ESP,pad - 3 bytes code[j++] = 0x83; code[j++] = 0xec; code[j++] = pad; } } // 3*argCount bytes for (k = (argCount + 1) * SWT_PTR.sizeof; k >= SWT_PTR.sizeof * 2; k -= SWT_PTR.sizeof) { //PUSH SS:[EBP+k] code[j++] = 0xff; code[j++] = 0x75; code[j++] = k; } if (i > 127) { //PUSH i - 5 bytes code[j++] = 0x68; code[j++] = ((i >> 0) & 0xFF); code[j++] = ((i >> 8) & 0xFF); code[j++] = ((i >> 16) & 0xFF); code[j++] = ((i >> 24) & 0xFF); } else { //PUSH i - 2 bytes code[j++] = 0x6a; code[j++] = i; } //MOV EAX callback - 1 + SWT_PTR.sizeof bytes code[j++] = 0xb8; (cast(SWT_PTR*) &code[j])[0] = cast(SWT_PTR) &callback; j += SWT_PTR.sizeof; //CALL EAX - 2 bytes code[j++] = 0xff; code[j++] = 0xd0; //ADD ESP,(argCount + 1) * SWT_PTR.sizeof - 3 bytes code[j++] = 0x83; code[j++] = 0xc4; version (darwin) code[j++] = cast(ubyte) (pad + ((argCount + 1) * SWT_PTR.sizeof)); else code[j++] = cast(ubyte) ((argCount + 1) * SWT_PTR.sizeof); //POP EBP - 1 byte code[j++] = 0x5d; version cast(Win32) { // RETN argCount * SWT_PTR.sizeof - 3 bytes code[j++] = 0xc2; code[j++] = cast(ubyte) (argCount * SWT_PTR.sizeof); code[j++] = 0x00; } else version cast(Win32_WCE) { // RETN argCount * SWT_PTR.sizeof - 3 bytes code[j++] = 0xc2; code[j++] = cast(ubyte) (argCount * SWT_PTR.sizeof); code[j++] = 0x00; } else { // RETN - 1 byte code[j++] = 0xc3; } if (j > CALLBACK_THUNK_SIZE) { jclass errorClass = (*env).FindClass(env, "java/lang/Error"); (*env).ThrowNew(env, errorClass, "Callback thunk overflow"); } return cast(SWT_PTR) code; } } } fail: return 0; }