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