1 /* 2 * Copyright (c) 2002-2011 by XMLVM.org 3 * 4 * Project Info: http://www.xmlvm.org 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation; either version 2.1 of the License, or 9 * (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 * License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19 * USA. 20 */ 21 22 #ifndef __XMLVM_H__ 23 #define __XMLVM_H__ 24 25 #ifdef __EMSCRIPTEN__ 26 // Workaround definitions for Emscripten 27 // TODO: Determine if different solution is needed 28 29 #define POLLPRI 0 30 #define IP_MULTICAST_IF 32 31 #define IP_MULTICAST_TTL 33 32 #define IP_MULTICAST_LOOP 34 33 #define IP_ADD_MEMBERSHIP 35 34 #define IP_DROP_MEMBERSHIP 36 35 #define SO_OOBINLINE 0 36 37 #ifndef __linux__ 38 #define __linux__ 39 #endif 40 41 #endif 42 43 #ifdef __linux__ 44 #define LINUX 45 #endif 46 47 #include <math.h> 48 #include <stdlib.h> 49 #include <stdio.h> 50 #include <string.h> 51 #include <setjmp.h> 52 #include <pthread.h> 53 #if __OBJC__ || MACOS 54 #include <libkern/OSAtomic.h> 55 #endif 56 57 #if __OBJC__ || MACOS 58 #define XMLVM_SPINLOCK_T OSSpinLock 59 #define XMLVM_SPINLOCK_INIT(spin) spin = 0 60 #define XMLVM_SPINLOCK_LOCK(spin) OSSpinLockLock(&spin) 61 #define XMLVM_SPINLOCK_UNLOCK(spin) OSSpinLockUnlock(&spin) 62 #else 63 #define XMLVM_SPINLOCK_T pthread_spinlock_t 64 #define XMLVM_SPINLOCK_INIT(spin) pthread_spin_init(&spin, 0) 65 #define XMLVM_SPINLOCK_LOCK(spin) pthread_spin_lock(&spin) 66 #define XMLVM_SPINLOCK_UNLOCK(spin) pthread_spin_unlock(&spin) 67 #endif 68 69 #ifdef DEBUG 70 71 #define XMLVM_ENABLE_STACK_TRACES 72 #define XMLVM_ENABLE_NPE_CHECK 73 #define XMLVM_ENABLE_ARRAY_BOUNDS_CHECK 74 75 #endif 76 77 #ifdef XMLVM_NO_GC 78 79 #define XMLVM_MALLOC(size) malloc(size) 80 #define XMLVM_ATOMIC_MALLOC(size) malloc(size) 81 #define XMLVM_FREE(pointer) free(pointer) 82 #define XMLVM_FINALIZE(me, func) 83 #define XMLVM_WEAK_REF(ptr) 84 85 #else 86 87 #include "gc.h" 88 89 #define XMLVM_MALLOC(size) GC_MALLOC(size) 90 #define XMLVM_ATOMIC_MALLOC(size) GC_MALLOC_ATOMIC(size) 91 #define XMLVM_FREE(pointer) GC_FREE(pointer) 92 #define XMLVM_FINALIZE(me, func) GC_REGISTER_FINALIZER_NO_ORDER((void *)me, func, (void *)NULL, (GC_finalization_proc *)0, (void * *)0); 93 //#define XMLVM_WEAK_REF(ptr) GC_register_disappearing_link(ptr) 94 #define XMLVM_WEAK_REF(ptr) 95 96 #endif 97 98 99 #define XMLVM_BZERO(pointer, size) memset((pointer), 0, size) 100 #define XMLVM_MEMCPY(dest, src, size) memcpy(dest, src, size) 101 #define XMLVM_OFFSETOF(type, field) ((unsigned long) &(((type *) 0)->field)) 102 103 104 #define XMLVM_CLASS_INIT(class) \ 105 if (!__TIB_ ##class.classInitialized) __INIT_ ##class(); 106 107 #define XMLVM_FORWARD_DECL(class) \ 108 JAVA_OBJECT __NEW_ ##class(); \ 109 struct class; \ 110 typedef struct class class; \ 111 extern JAVA_OBJECT __CLASS_ ##class; 112 113 114 void staticInitializerLock(void* tibDefinition); 115 void staticInitializerUnlock(void* tibDefinition); 116 117 typedef struct XMLVM_STATIC_INITIALIZER_CONTROLLER { 118 pthread_mutex_t* initMutex; // a mutex locked while statically initalizing a class or classes 119 } XMLVM_STATIC_INITIALIZER_CONTROLLER; 120 121 typedef void JAVA_VOID; 122 typedef int JAVA_BOOLEAN; 123 typedef int JAVA_CHAR; 124 typedef int JAVA_BYTE; 125 typedef int JAVA_SHORT; 126 typedef int JAVA_INT; 127 typedef unsigned int JAVA_UINT; 128 typedef long long JAVA_LONG; 129 typedef unsigned long long JAVA_ULONG; 130 typedef float JAVA_FLOAT; 131 typedef double JAVA_DOUBLE; 132 typedef void* JAVA_OBJECT; 133 134 //TODO which values should we use for Double.INFINITY? 135 #define Infinity INFINITY 136 #define NaN NAN 137 138 typedef char JAVA_ARRAY_BYTE; 139 typedef char JAVA_ARRAY_BOOLEAN; 140 typedef unsigned short JAVA_ARRAY_CHAR; 141 typedef short JAVA_ARRAY_SHORT; 142 typedef int JAVA_ARRAY_INT; 143 typedef long long JAVA_ARRAY_LONG; 144 typedef float JAVA_ARRAY_FLOAT; 145 typedef double JAVA_ARRAY_DOUBLE; 146 typedef JAVA_OBJECT JAVA_ARRAY_OBJECT; 147 148 149 typedef union { 150 JAVA_OBJECT o; 151 JAVA_INT i; 152 JAVA_FLOAT f; 153 JAVA_DOUBLE d; 154 JAVA_LONG l; 155 } XMLVMElem; 156 157 158 extern const JAVA_ARRAY_CHAR* xmlvm_constant_pool_data[]; 159 extern const JAVA_INT xmlvm_constant_pool_length[]; 160 extern int xmlvm_constant_pool_size; 161 162 #define JAVA_NULL ((JAVA_OBJECT) 0) 163 164 typedef void (*VTABLE_PTR)(); 165 typedef void (*Func_V)(); 166 typedef void (*Func_VO)(JAVA_OBJECT o1); 167 typedef void (*Func_VOO)(JAVA_OBJECT o1, JAVA_OBJECT o2); 168 typedef void (*Func_VOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3); 169 typedef void (*Func_VOOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3, JAVA_OBJECT o4); 170 typedef void (*Func_VOOOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3, JAVA_OBJECT o4, JAVA_OBJECT o5); 171 typedef void (*Func_VOOOOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3, JAVA_OBJECT o4, JAVA_OBJECT o5, JAVA_OBJECT o6); 172 typedef void (*Func_VOB)(JAVA_OBJECT o1, JAVA_BOOLEAN o3); 173 typedef void (*Func_VOI)(JAVA_OBJECT o1, JAVA_INT i1); 174 typedef void (*Func_VOOB)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_BOOLEAN o3); 175 typedef void (*Func_VOOI)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_INT o3); 176 typedef void (*Func_VOID)(JAVA_OBJECT o1, JAVA_INT i1, JAVA_DOUBLE d1); 177 178 typedef JAVA_BOOLEAN (*Func_BOI)(JAVA_OBJECT o1, JAVA_INT i1); 179 180 typedef JAVA_OBJECT (*Func_O)(); 181 typedef JAVA_OBJECT (*Func_OO)(JAVA_OBJECT o1); 182 typedef JAVA_OBJECT (*Func_OOO)(JAVA_OBJECT o1, JAVA_OBJECT o2); 183 typedef JAVA_OBJECT (*Func_OOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3); 184 typedef JAVA_FLOAT (*Func_FOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3); 185 typedef JAVA_INT (*Func_IO)(JAVA_OBJECT o1); 186 typedef JAVA_INT (*Func_IOO)(JAVA_OBJECT o1, JAVA_OBJECT o2); 187 typedef JAVA_INT (*Func_IOI)(JAVA_OBJECT o1, JAVA_INT i1); 188 typedef JAVA_INT (*Func_IOOI)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_INT i1); 189 typedef JAVA_OBJECT (*Func_OOOI)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_INT i1); 190 typedef JAVA_OBJECT (*Func_OOII)(JAVA_OBJECT o1, JAVA_INT i1, JAVA_INT i2); 191 typedef JAVA_BOOLEAN (*Func_BO)(JAVA_OBJECT o1); 192 typedef JAVA_BOOLEAN (*Func_BOO)(JAVA_OBJECT o1, JAVA_OBJECT o2); 193 typedef JAVA_BOOLEAN (*Func_BOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3); 194 typedef JAVA_BOOLEAN (*Func_BOOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3, JAVA_OBJECT o4); 195 typedef JAVA_BOOLEAN (*Func_BOOOOO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3, JAVA_OBJECT o4, JAVA_OBJECT o5); 196 typedef JAVA_BOOLEAN (*Func_BOOOI)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_OBJECT o3, JAVA_INT o4); 197 typedef void (*Func_VOOIO)(JAVA_OBJECT o1, JAVA_OBJECT o2, JAVA_INT i1, JAVA_OBJECT o3); 198 199 #define java_lang_reflect_Modifier_PUBLIC 1 200 #define java_lang_reflect_Modifier_PRIVATE 2 201 #define java_lang_reflect_Modifier_PROTECTED 4 202 #define java_lang_reflect_Modifier_STATIC 8 203 #define java_lang_reflect_Modifier_FINAL 16 204 #define java_lang_reflect_Modifier_SYNCHRONIZED 32 205 #define java_lang_reflect_Modifier_VOLATILE 64 206 #define java_lang_reflect_Modifier_TRANSIENT 128 207 #define java_lang_reflect_Modifier_NATIVE 256 208 #define java_lang_reflect_Modifier_INTERFACE 512 209 #define java_lang_reflect_Modifier_ABSTRACT 1024 210 #define java_lang_reflect_Modifier_STRICT 2048 211 #define java_lang_reflect_Modifier_BRIDGE 64 212 #define java_lang_reflect_Modifier_VARARGS 128 213 #define java_lang_reflect_Modifier_SYNTHETIC 4096 214 #define java_lang_reflect_Modifier_ANNOTATION 8192 215 #define java_lang_reflect_Modifier_ENUM 16384 216 217 typedef struct { 218 const char* name; 219 JAVA_OBJECT* type; 220 JAVA_INT modifiers; 221 JAVA_INT offset; 222 JAVA_OBJECT* address; 223 const char* signature; 224 JAVA_OBJECT annotations; // XMLVMArray(byte) 225 } XMLVM_FIELD_REFLECTION_DATA; 226 227 typedef struct { 228 JAVA_OBJECT** parameterTypes; 229 int numParameterTypes; 230 JAVA_OBJECT* checkedExceptions; 231 int numCheckedExceptions; 232 int modifiers; 233 const char* signature; 234 JAVA_OBJECT annotations; 235 JAVA_OBJECT parameterAnnotations; 236 } XMLVM_CONSTRUCTOR_REFLECTION_DATA; 237 238 typedef struct { 239 const char* name; 240 JAVA_OBJECT** parameterTypes; 241 int numParameterTypes; 242 JAVA_OBJECT* checkedExceptions; 243 int numCheckedExceptions; 244 int modifiers; 245 const char* signature; 246 JAVA_OBJECT annotations; 247 JAVA_OBJECT parameterAnnotations; 248 } XMLVM_METHOD_REFLECTION_DATA; 249 250 #define XMLVM_TYPE_CLASS 1 251 #define XMLVM_TYPE_INTERFACE 2 252 #define XMLVM_TYPE_ENUM 4 253 #define XMLVM_TYPE_PRIMITIVE 8 254 #define XMLVM_TYPE_ARRAY 16 255 256 #define XMLVM_DEFINE_CLASS(name, vtableSize, itableSize) \ 257 typedef struct __TIB_DEFINITION_##name { \ 258 int classInitializationBegan; \ 259 int classInitialized; \ 260 JAVA_LONG initializerThreadId; \ 261 Func_V classInitializer; \ 262 const char* className; \ 263 const char* packageName; \ 264 const char* enclosingClassName; \ 265 const char* enclosingMethodName; \ 266 const char* signature; \ 267 struct __TIB_DEFINITION_TEMPLATE* extends; \ 268 int sizeInstance; \ 269 int flags; \ 270 JAVA_OBJECT clazz; \ 271 JAVA_OBJECT baseType; \ 272 JAVA_OBJECT arrayType; \ 273 XMLVM_FIELD_REFLECTION_DATA* declaredFields; \ 274 int numDeclaredFields; \ 275 XMLVM_CONSTRUCTOR_REFLECTION_DATA* declaredConstructors; \ 276 int numDeclaredConstructors; \ 277 Func_OOO constructorDispatcherFunc; \ 278 XMLVM_METHOD_REFLECTION_DATA* declaredMethods; \ 279 int numDeclaredMethods; \ 280 Func_OOOO methodDispatcherFunc; \ 281 Func_O newInstanceFunc; \ 282 int numInterfaces; \ 283 struct __TIB_DEFINITION_TEMPLATE* (*interfaces)[1]; \ 284 int numImplementedInterfaces; \ 285 struct __TIB_DEFINITION_TEMPLATE* (*implementedInterfaces)[1]; \ 286 VTABLE_PTR* itableBegin; \ 287 VTABLE_PTR vtable[vtableSize]; \ 288 VTABLE_PTR itable[itableSize]; \ 289 } __TIB_DEFINITION_##name; \ 290 \ 291 extern __TIB_DEFINITION_##name __TIB_##name; 292 293 XMLVM_DEFINE_CLASS(TEMPLATE, 0, 0) 294 295 int XMLVM_ISA(JAVA_OBJECT obj, JAVA_OBJECT clazz); 296 int xmlvm_java_string_cmp(JAVA_OBJECT s1, const char* s2); 297 const char* xmlvm_java_string_to_const_char(JAVA_OBJECT s); 298 JAVA_OBJECT xmlvm_create_java_string(const char* s); 299 JAVA_OBJECT xmlvm_create_java_string_array(int count, const char **s); 300 JAVA_OBJECT xmlvm_create_java_string_from_pool(int pool_id); 301 void xmlvm_clear_constant_pool_cache(); 302 303 #define XMLVM_SIZE_OF_OBJECT_VTABLE 11 304 305 306 //--------------------------------------------------------------------------------------------- 307 // XMLVMClass 308 309 // Generated by AugmentedCOutputProcess in file xmlvm-tib-list.c and used in Class.forName() 310 extern __TIB_DEFINITION_TEMPLATE* __xmlvm_tib_list[]; 311 extern int __xmlvm_num_tib; 312 313 extern JAVA_OBJECT __CLASS_boolean; 314 extern JAVA_OBJECT __CLASS_byte; 315 extern JAVA_OBJECT __CLASS_char; 316 extern JAVA_OBJECT __CLASS_short; 317 extern JAVA_OBJECT __CLASS_int; 318 extern JAVA_OBJECT __CLASS_long; 319 extern JAVA_OBJECT __CLASS_float; 320 extern JAVA_OBJECT __CLASS_double; 321 extern JAVA_OBJECT __CLASS_void; 322 323 extern JAVA_OBJECT __CLASS_boolean_1ARRAY; 324 extern JAVA_OBJECT __CLASS_byte_1ARRAY; 325 extern JAVA_OBJECT __CLASS_char_1ARRAY; 326 extern JAVA_OBJECT __CLASS_short_1ARRAY; 327 extern JAVA_OBJECT __CLASS_int_1ARRAY; 328 extern JAVA_OBJECT __CLASS_long_1ARRAY; 329 extern JAVA_OBJECT __CLASS_float_1ARRAY; 330 extern JAVA_OBJECT __CLASS_double_1ARRAY; 331 332 extern JAVA_OBJECT __CLASS_boolean_2ARRAY; 333 extern JAVA_OBJECT __CLASS_byte_2ARRAY; 334 extern JAVA_OBJECT __CLASS_char_2ARRAY; 335 extern JAVA_OBJECT __CLASS_short_2ARRAY; 336 extern JAVA_OBJECT __CLASS_int_2ARRAY; 337 extern JAVA_OBJECT __CLASS_long_2ARRAY; 338 extern JAVA_OBJECT __CLASS_float_2ARRAY; 339 extern JAVA_OBJECT __CLASS_double_2ARRAY; 340 341 extern JAVA_OBJECT __CLASS_boolean_3ARRAY; 342 extern JAVA_OBJECT __CLASS_byte_3ARRAY; 343 extern JAVA_OBJECT __CLASS_char_3ARRAY; 344 extern JAVA_OBJECT __CLASS_short_3ARRAY; 345 extern JAVA_OBJECT __CLASS_int_3ARRAY; 346 extern JAVA_OBJECT __CLASS_long_3ARRAY; 347 extern JAVA_OBJECT __CLASS_float_3ARRAY; 348 extern JAVA_OBJECT __CLASS_double_3ARRAY; 349 350 JAVA_OBJECT XMLVM_CREATE_CLASS_OBJECT(void* tib); 351 JAVA_OBJECT XMLVM_CREATE_ARRAY_CLASS_OBJECT(JAVA_OBJECT baseType); 352 353 extern JAVA_OBJECT __CLASS_org_xmlvm_runtime_RedTypeMarker; 354 355 356 //--------------------------------------------------------------------------------------------- 357 // XMLVMArray 358 359 JAVA_OBJECT XMLVMArray_createSingleDimension(JAVA_OBJECT type, int size); 360 JAVA_OBJECT XMLVMArray_createSingleDimensionWithData(JAVA_OBJECT type, int size, void* data); 361 JAVA_OBJECT XMLVMArray_createMultiDimensions(JAVA_OBJECT type, JAVA_OBJECT dimensions); 362 JAVA_OBJECT XMLVMArray_createFromString(const char* str); 363 void XMLVMArray_fillArray(JAVA_OBJECT array, void* data); 364 JAVA_INT XMLVMArray_count(JAVA_OBJECT array); 365 366 XMLVM_DEFINE_CLASS(boolean, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 367 XMLVM_DEFINE_CLASS(byte, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 368 XMLVM_DEFINE_CLASS(char, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 369 XMLVM_DEFINE_CLASS(short, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 370 XMLVM_DEFINE_CLASS(int, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 371 XMLVM_DEFINE_CLASS(long, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 372 XMLVM_DEFINE_CLASS(float, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 373 XMLVM_DEFINE_CLASS(double, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 374 XMLVM_DEFINE_CLASS(void, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 375 376 void __INIT_boolean(); 377 void __INIT_byte(); 378 void __INIT_char(); 379 void __INIT_short(); 380 void __INIT_int(); 381 void __INIT_long(); 382 void __INIT_float(); 383 void __INIT_double(); 384 void __INIT_void(); 385 386 XMLVM_DEFINE_CLASS(java_lang_Object_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 387 XMLVM_DEFINE_CLASS(boolean_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 388 XMLVM_DEFINE_CLASS(byte_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 389 XMLVM_DEFINE_CLASS(char_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 390 XMLVM_DEFINE_CLASS(short_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 391 XMLVM_DEFINE_CLASS(int_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 392 XMLVM_DEFINE_CLASS(long_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 393 XMLVM_DEFINE_CLASS(float_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 394 XMLVM_DEFINE_CLASS(double_ARRAYTYPE, XMLVM_SIZE_OF_OBJECT_VTABLE, 0) 395 396 #include "org_xmlvm_runtime_XMLVMArray.h" 397 #include "java_lang_Thread.h" 398 399 #define XMLVM_JMP_BUF jmp_buf 400 401 #ifndef XMLVM_ASM_JS 402 #define XMLVM_SETJMP(env) setjmp(env) 403 #define XMLVM_LONGJMP(env) longjmp(env, 0) 404 #else 405 #define XMLVM_SETJMP(env) 0 406 #define XMLVM_LONGJMP(env) 407 #endif 408 409 // This exception value is only used for the main thread. 410 // Since a call to Thread.currentThread() contains try-catch blocks, this must 411 // be defined before the "main" java.lang.Thread is defined. 412 extern XMLVM_JMP_BUF xmlvm_exception_env_main_thread; 413 414 #define XMLVM_NOT_IMPLEMENTED() XMLVM_ERROR("Not implemented", __FILE__, __FUNCTION__, __LINE__) 415 #define XMLVM_UNIMPLEMENTED_NATIVE_METHOD() XMLVM_ERROR("Unimplemented native method", __FILE__, __FUNCTION__, __LINE__) 416 #define XMLVM_INTERNAL_ERROR() XMLVM_ERROR("Internal error", __FILE__, __FUNCTION__, __LINE__) 417 #define XMLVM_RED_CLASS_DEPENDENCY() XMLVM_ERROR("Unsatisfied red class dependency", __FILE__, __FUNCTION__, __LINE__) 418 419 void xmlvm_unimplemented_native_method(); 420 void xmlvm_unhandled_exception(); 421 void XMLVM_ERROR(const char* msg, const char* file, const char* function, int line); 422 423 424 //--------------------------------------------------------------------------------------------- 425 // Stack traces 426 427 428 #ifdef XMLVM_ENABLE_STACK_TRACES 429 430 typedef struct XMLVM_STACK_TRACE_ELEMENT { 431 char* className; 432 char* methodName; 433 char* fileName; 434 int lineNumber; 435 } XMLVM_STACK_TRACE_ELEMENT; 436 437 typedef struct XMLVM_STACK_TRACE_LINK { 438 // "struct" is needed here since the typedef is not yet declared. 439 struct XMLVM_STACK_TRACE_LINK* nextLink; 440 XMLVM_STACK_TRACE_ELEMENT* element; 441 XMLVM_STACK_TRACE_ELEMENT* currentLocation; 442 } XMLVM_STACK_TRACE_LINK; 443 444 typedef struct XMLVM_STACK_TRACE_CURRENT { 445 int stackSize; 446 XMLVM_STACK_TRACE_LINK* topOfStack; 447 } XMLVM_STACK_TRACE_CURRENT; 448 449 #define XMLVM_ENTER_METHOD(className, methodName, fileName) \ 450 XMLVM_STACK_TRACE_CURRENT* threadStack = getCurrentStackTrace(); \ 451 int threadStackSize = threadStack->stackSize; \ 452 xmlvmEnterMethod(threadStack, className, methodName, fileName); 453 #define XMLVM_SOURCE_POSITION(fileName, lineNumber) \ 454 xmlvmSourcePosition(threadStack, fileName, lineNumber); 455 #define XMLVM_EXIT_METHOD() \ 456 xmlvmExitMethod(threadStack); 457 #define XMLVM_UNWIND_EXCEPTION() \ 458 xmlvmUnwindException(threadStack, threadStackSize); 459 460 void createStackForNewThread(JAVA_LONG threadId); 461 void destroyStackForExitingThread(JAVA_LONG threadId); 462 XMLVM_STACK_TRACE_CURRENT* getCurrentStackTrace(); 463 void xmlvmEnterMethod(XMLVM_STACK_TRACE_CURRENT* threadStack, const char* className, const char* methodName, const char* fileName); 464 void xmlvmSourcePosition(XMLVM_STACK_TRACE_CURRENT* threadStack, const char* fileName, int lineNumber); 465 void xmlvmExitMethod(XMLVM_STACK_TRACE_CURRENT* threadStack); 466 void xmlvmUnwindException(XMLVM_STACK_TRACE_CURRENT* threadStack, int unwindToStackSize); 467 468 #else 469 470 #define XMLVM_ENTER_METHOD(className, methodName, fileName) 471 #define XMLVM_SOURCE_POSITION(fileName, lineNumber) 472 #define XMLVM_EXIT_METHOD() 473 #define XMLVM_UNWIND_EXCEPTION() 474 475 #endif 476 477 //--------------------------------------------------------------------------------------------- 478 // Reflection logging 479 480 #ifdef XMLVM_ENABLE_CLASS_LOGGING 481 482 void xmlvmClassUsed(const char *prefix, const char *className); 483 484 #define XMLVM_REFLECTION_USED(className) \ 485 xmlvmClassUsed("R", className); 486 487 #define XMLVM_CLASS_USED(className) \ 488 xmlvmClassUsed("C", className); 489 490 #else 491 492 #define XMLVM_REFLECTION_USED(className) 493 #define XMLVM_CLASS_USED(className) 494 495 #endif 496 497 498 //--------------------------------------------------------------------------------------------- 499 #define XMLVM_TRY_BEGIN(uniqueId) \ 500 volatile XMLVM_JMP_BUF local_env_##uniqueId; \ 501 volatile java_lang_Thread* curThread_##uniqueId = (java_lang_Thread*)java_lang_Thread_currentThread__(); \ 502 XMLVM_MEMCPY(local_env_##uniqueId, curThread_##uniqueId->fields.java_lang_Thread.xmlvmExceptionEnv_, sizeof(XMLVM_JMP_BUF)); \ 503 if (!XMLVM_SETJMP(curThread_##uniqueId->fields.java_lang_Thread.xmlvmExceptionEnv_)) { 504 #define XMLVM_TRY_END } 505 #define XMLVM_CATCH_BEGIN(uniqueId) \ 506 else { \ 507 XMLVM_UNWIND_EXCEPTION() \ 508 XMLVM_MEMCPY(curThread_##uniqueId->fields.java_lang_Thread.xmlvmExceptionEnv_, local_env_##uniqueId, sizeof(XMLVM_JMP_BUF)); 509 #define XMLVM_CATCH_SPECIFIC(uniqueId, type, target) \ 510 if (!__TIB_##type.classInitialized) __INIT_##type(); \ 511 if (XMLVM_ISA(curThread_##uniqueId->fields.java_lang_Thread.xmlvmException_, __CLASS_##type)) goto label##target; 512 #define XMLVM_CATCH_END(uniqueId) \ 513 XMLVM_LONGJMP(curThread_##uniqueId->fields.java_lang_Thread.xmlvmExceptionEnv_); \ 514 } 515 #define XMLVM_RESTORE_EXCEPTION_ENV(uniqueId) \ 516 XMLVM_MEMCPY(curThread_##uniqueId->fields.java_lang_Thread.xmlvmExceptionEnv_, local_env_##uniqueId, sizeof(XMLVM_JMP_BUF)); 517 518 // Throw an exception that has already been initialized and constructed 519 #define XMLVM_THROW_CUSTOM(exception) { \ 520 java_lang_Thread* macroCurThread = (java_lang_Thread*)java_lang_Thread_currentThread__(); \ 521 macroCurThread->fields.java_lang_Thread.xmlvmException_ = exception; \ 522 XMLVM_LONGJMP(macroCurThread->fields.java_lang_Thread.xmlvmExceptionEnv_); \ 523 } 524 // Throw an exception which is automatically constructed with the default constructor 525 #define XMLVM_THROW(exceptionType) { \ 526 java_lang_Thread* macroCurThread = (java_lang_Thread*)java_lang_Thread_currentThread__(); \ 527 macroCurThread->fields.java_lang_Thread.xmlvmException_ = __NEW_##exceptionType(); \ 528 exceptionType##___INIT___(macroCurThread->fields.java_lang_Thread.xmlvmException_); \ 529 XMLVM_LONGJMP(macroCurThread->fields.java_lang_Thread.xmlvmExceptionEnv_); \ 530 } 531 // Throw an exception which is automatically constructed with a String parameter derived from the C String 532 #define XMLVM_THROW_WITH_CSTRING(exceptionType, errorMsg) { \ 533 java_lang_Thread* macroCurThread = (java_lang_Thread*)java_lang_Thread_currentThread__(); \ 534 macroCurThread->fields.java_lang_Thread.xmlvmException_ = __NEW_##exceptionType(); \ 535 exceptionType##___INIT____java_lang_String(macroCurThread->fields.java_lang_Thread.xmlvmException_, xmlvm_create_java_string(errorMsg)); \ 536 XMLVM_LONGJMP(macroCurThread->fields.java_lang_Thread.xmlvmExceptionEnv_); \ 537 } 538 539 #ifdef XMLVM_ENABLE_NPE_CHECK 540 541 #define XMLVM_CHECK_NPE(register) \ 542 if (_r##register.o == JAVA_NULL) { \ 543 XMLVM_THROW(java_lang_NullPointerException) \ 544 } 545 546 #else 547 548 #define XMLVM_CHECK_NPE(register) 549 550 #endif // XMLVM_ENABLE_NPE_CHECK 551 552 553 #ifdef XMLVM_ENABLE_ARRAY_BOUNDS_CHECK 554 555 #define XMLVM_CHECK_ARRAY_BOUNDS(arr, idx) \ 556 if ((idx < 0) || (idx >= ((org_xmlvm_runtime_XMLVMArray*) arr)->fields.org_xmlvm_runtime_XMLVMArray.length_)) { \ 557 XMLVM_THROW(java_lang_ArrayIndexOutOfBoundsException) \ 558 } 559 560 #else 561 562 #define XMLVM_CHECK_ARRAY_BOUNDS(arr, idx) 563 564 #endif // XMLVM_ENABLE_ARRAY_BOUNDS_CHECK 565 566 567 void xmlvm_init(); 568 void xmlvm_destroy(java_lang_Thread* mainThread); 569 570 // A list of Java instances which are currently referenced by non-C types. 571 // This is used to avoid premature garbage collection. 572 JAVA_OBJECT reference_array; 573 574 #endif 575