00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_callBack.cpp.incl"
00026
00027 void callBack::initialize(oop receiver, symbolOop selector) {
00028 assert(selector->is_symbol(), "must be symbol");
00029 Universe::set_callBack(receiver, selector);
00030 }
00031
00032 static char* store_byte(char* chunk, char b) {
00033 *chunk = b;
00034 return chunk + sizeof(char);
00035 }
00036
00037 static char* store_long(char* chunk, long l) {
00038 *((long*) chunk) = l;
00039 return chunk + sizeof(long);
00040 }
00041
00042 extern "C" int handlePascalCallBackStub();
00043 extern "C" int handleCCallBackStub();
00044
00045 void* callBack::registerPascalCall(int index, int nofArgs) {
00046 void* result = malloc(15);
00047 char* chunk = (char*) result;
00048
00049
00050 chunk = store_byte(chunk, '\xB9');
00051 chunk = store_long(chunk, index);
00052
00053
00054 chunk = store_byte(chunk, '\xBA');
00055 chunk = store_long(chunk, nofArgs * sizeof(int));
00056
00057
00058 chunk = store_byte(chunk, '\xE9');
00059 chunk = store_long(chunk, ((long) &handlePascalCallBackStub) - (4 + (long) chunk));
00060
00061 return result;
00062 }
00063
00064 void* callBack::registerCCall(int index) {
00065 void* result = malloc(10);
00066 char* chunk = (char*) result;
00067
00068
00069 chunk = store_byte(chunk, '\xB9');
00070 chunk = store_long(chunk, index);
00071
00072
00073 chunk = store_byte(chunk, '\xE9');
00074 chunk = store_long(chunk, ((long) &handleCCallBackStub) - (4 + (long) chunk));
00075
00076 return result;
00077 }
00078
00079 void callBack::unregister(void* block) {
00080 assert(block, "block is not valid");
00081 free((char*) block);
00082 }
00083
00084
00085
00086
00087
00088 typedef void* (__stdcall *call_out_func_4)(int a, int b, int c, int d);
00089
00090 extern "C" bool have_nlr_through_C;
00091
00092 extern "C" volatile void* handleCallBack(int index, int params) {
00093 DeltaProcess* proc = NULL;
00094
00095 if (Universe::callBack_receiver()->is_nil()) {
00096 warning("callBack receiver is not set");
00097 }
00098
00099 int low = get_unsigned_bitfield(params, 0, 16);
00100 int high = get_unsigned_bitfield(params, 16, 16);
00101
00102 if (DeltaProcess::active()->thread_id() != os::current_thread_id()) {
00103
00104
00105
00106 proc = Processes::find_from_thread_id(os::current_thread_id());
00107 assert(proc, "process must be present");
00108 DLLs::exit_async_call(&proc);
00109 }
00110
00111
00112 oop res = Delta::call(Universe::callBack_receiver(),
00113 Universe::callBack_selector(),
00114 as_smiOop(index),
00115 as_smiOop(high),
00116 as_smiOop(low));
00117
00118 assert(DeltaProcess::active()->thread_id() == os::current_thread_id(), "check for process torch");
00119
00120 void* result;
00121
00122
00123
00124 if (have_nlr_through_C) {
00125
00126 ErrorHandler::continue_nlr_in_delta();
00127 }
00128
00129 if (res->is_smi()) {
00130 result = (void*) smiOop(res)->value();
00131 } else if (res->is_proxy()) {
00132 result = (void*) proxyOop(res)->get_pointer();
00133 } else {
00134 warning("Wrong return type for call back, returning NULL");
00135 result = NULL;
00136 }
00137
00138
00139
00140
00141 if (proc) {
00142
00143 proc->transfer_and_continue();
00144 }
00145
00146
00147 return result;
00148 }