Fix LDC, LDC_W, and INSTANCEOF opcodes, more debugging
[jamvm-avr32-jem.git] / src / natives.c
blobc9b05c089e90c156f32ce5ab3a27bfce41a821be
1 /*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007
3 * Robert Lougher <rob@lougher.org.uk>.
5 * This file is part of JamVM.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #ifdef NO_JNI
23 #error to use classpath, Jam must be compiled with JNI!
24 #endif
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <string.h>
30 #include <errno.h>
32 #include "jam.h"
33 #include "alloc.h"
34 #include "thread.h"
35 #include "lock.h"
36 #include "natives.h"
38 static int pd_offset;
40 void initialiseNatives() {
41 FieldBlock *pd = findField(java_lang_Class, "pd", "Ljava/security/ProtectionDomain;");
43 if(pd == NULL) {
44 jam_fprintf(stderr, "Error initialising VM (initialiseNatives)\n");
45 exitVM(1);
47 pd_offset = pd->offset;
50 /* java.lang.VMObject */
52 uintptr_t *getClass(Class *class, MethodBlock *mb, uintptr_t *ostack) {
53 Object *ob = (Object*)*ostack;
54 *ostack++ = (uintptr_t)ob->class;
55 return ostack;
58 uintptr_t *jamClone(Class *class, MethodBlock *mb, uintptr_t *ostack) {
59 Object *ob = (Object*)*ostack;
60 *ostack++ = (uintptr_t)cloneObject(ob);
61 return ostack;
64 /* static method wait(Ljava/lang/Object;JI)V */
65 uintptr_t *jamWait(Class *class, MethodBlock *mb, uintptr_t *ostack) {
66 Object *obj = (Object *)ostack[0];
67 long long ms = *((long long *)&ostack[1]);
68 int ns = ostack[3];
70 objectWait(obj, ms, ns);
71 return ostack;
74 /* static method notify(Ljava/lang/Object;)V */
75 uintptr_t *notify(Class *class, MethodBlock *mb, uintptr_t *ostack) {
76 Object *obj = (Object *)*ostack;
77 objectNotify(obj);
78 return ostack;
81 /* static method notifyAll(Ljava/lang/Object;)V */
82 uintptr_t *notifyAll(Class *class, MethodBlock *mb, uintptr_t *ostack) {
83 Object *obj = (Object *)*ostack;
84 objectNotifyAll(obj);
85 return ostack;
88 /* java.lang.VMSystem */
90 /* arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V */
91 uintptr_t *arraycopy(Class *class, MethodBlock *mb, uintptr_t *ostack) {
92 Object *src = (Object *)ostack[0];
93 int start1 = ostack[1];
94 Object *dest = (Object *)ostack[2];
95 int start2 = ostack[3];
96 int length = ostack[4];
98 if((src == NULL) || (dest == NULL))
99 signalException("java/lang/NullPointerException", NULL);
100 else {
101 ClassBlock *scb = CLASS_CB(src->class);
102 ClassBlock *dcb = CLASS_CB(dest->class);
103 char *sdata = ARRAY_DATA(src);
104 char *ddata = ARRAY_DATA(dest);
106 if((scb->name[0] != '[') || (dcb->name[0] != '['))
107 goto storeExcep;
109 if((start1 < 0) || (start2 < 0) || (length < 0)
110 || ((start1 + length) > ARRAY_LEN(src))
111 || ((start2 + length) > ARRAY_LEN(dest))) {
112 signalException("java/lang/ArrayIndexOutOfBoundsException", NULL);
113 return ostack;
116 if(isInstanceOf(dest->class, src->class)) {
117 int size;
119 switch(scb->name[1]) {
120 case 'B':
121 case 'Z':
122 size = 1;
123 break;
124 case 'C':
125 case 'S':
126 size = 2;
127 break;
128 case 'I':
129 case 'F':
130 size = 4;
131 break;
132 case 'L':
133 case '[':
134 size = sizeof(Object*);
135 break;
136 case 'J':
137 case 'D':
138 default:
139 size = 8;
140 break;
143 memmove(ddata + start2*size, sdata + start1*size, length*size);
144 } else {
145 Object **sob, **dob;
146 int i;
148 if(!(((scb->name[1] == 'L') || (scb->name[1] == '[')) &&
149 ((dcb->name[1] == 'L') || (dcb->name[1] == '['))))
150 goto storeExcep;
152 /* Not compatible array types, but elements may be compatible...
153 e.g. src = [Ljava/lang/Object, dest = [Ljava/lang/String, but
154 all src = Strings - check one by one...
157 if(scb->dim > dcb->dim)
158 goto storeExcep;
160 sob = &((Object**)sdata)[start1];
161 dob = &((Object**)ddata)[start2];
163 for(i = 0; i < length; i++) {
164 #if JAM_ON_STACK
165 if((*sob != NULL) && !arrayStoreCheck(dest->class, (*sob)->class))
166 goto storeExcep;
167 #else
168 #define OBJECT_GRAIN 8
169 #define IS_OBJECT(ptr) !(((uintptr_t)(ptr))&(OBJECT_GRAIN-1))
170 //reference array contains only JEM type refs now
171 Object* obj = JAM_OBJECT((uintptr_t*)*sob);
172 if(!IS_OBJECT(obj))
173 obj = JAM_ARRAY((uintptr_t*)*sob);
174 if((*sob != NULL) && !arrayStoreCheck(dest->class, obj->class))
175 goto storeExcep;
176 #endif
177 *dob++ = *sob++;
181 return ostack;
183 storeExcep:
184 signalException("java/lang/ArrayStoreException", NULL);
185 return ostack;
188 uintptr_t *identityHashCode(Class *class, MethodBlock *mb, uintptr_t *ostack) {
189 Object *ob = (Object*)*ostack;
190 uintptr_t addr = ob == NULL ? 0 : getObjectHashcode(ob);
192 *ostack++ = addr & 0xffffffff;
193 return ostack;
196 /* java.lang.VMRuntime */
198 uintptr_t *availableProcessors(Class *class, MethodBlock *mb, uintptr_t *ostack) {
199 *ostack++ = nativeAvailableProcessors();
200 return ostack;
203 uintptr_t *freeMemory(Class *class, MethodBlock *mb, uintptr_t *ostack) {
204 *(u8*)ostack = freeHeapMem();
205 return ostack + 2;
208 uintptr_t *totalMemory(Class *class, MethodBlock *mb, uintptr_t *ostack) {
209 *(u8*)ostack = totalHeapMem();
210 return ostack + 2;
213 uintptr_t *maxMemory(Class *class, MethodBlock *mb, uintptr_t *ostack) {
214 *(u8*)ostack = maxHeapMem();
215 return ostack + 2;
218 uintptr_t *gc(Class *class, MethodBlock *mb, uintptr_t *ostack) {
219 gc1();
220 return ostack;
223 uintptr_t *runFinalization(Class *class, MethodBlock *mb, uintptr_t *ostack) {
224 runFinalizers();
225 return ostack;
228 uintptr_t *exitInternal(Class *class, MethodBlock *mb, uintptr_t *ostack) {
229 int status = ostack[0];
230 jamvm_exit(status);
231 /* keep compiler happy */
232 return 0;
235 uintptr_t *nativeLoad(Class *class, MethodBlock *mb, uintptr_t *ostack) {
236 char *name = String2Cstr((Object*)ostack[0]);
237 Object *class_loader = (Object *)ostack[1];
239 ostack[0] = resolveDll(name, class_loader);
240 sysFree(name);
242 return ostack+1;
245 uintptr_t *mapLibraryName(Class *class, MethodBlock *mb, uintptr_t *ostack) {
246 char *name = String2Cstr((Object*)ostack[0]);
247 char *lib = getDllName(name);
248 sysFree(name);
250 *ostack++ = (uintptr_t)Cstr2String(lib);
251 sysFree(lib);
253 return ostack;
256 uintptr_t *propertiesPreInit(Class *class, MethodBlock *mb, uintptr_t *ostack) {
257 Object *properties = (Object *)*ostack;
258 addDefaultProperties(properties);
259 return ostack;
262 uintptr_t *propertiesPostInit(Class *class, MethodBlock *mb, uintptr_t *ostack) {
263 Object *properties = (Object *)*ostack;
264 addCommandLineProperties(properties);
265 return ostack;
268 /* java.lang.VMClass */
270 #define GET_CLASS(vmClass) (Class*)vmClass
272 uintptr_t *isInstance(Class *class, MethodBlock *mb, uintptr_t *ostack) {
273 Class *clazz = GET_CLASS(ostack[0]);
274 Object *ob = (Object*)ostack[1];
276 *ostack++ = ob == NULL ? FALSE : (uintptr_t)isInstanceOf(clazz, ob->class);
277 return ostack;
280 uintptr_t *isAssignableFrom(Class *class, MethodBlock *mb, uintptr_t *ostack) {
281 Class *clazz = GET_CLASS(ostack[0]);
282 Class *clazz2 = (Class*)ostack[1];
284 if(clazz2 == NULL)
285 signalException("java/lang/NullPointerException", NULL);
286 else
287 *ostack++ = (uintptr_t)isInstanceOf(clazz, clazz2);
289 return ostack;
292 uintptr_t *isInterface(Class *class, MethodBlock *mb, uintptr_t *ostack) {
293 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
294 *ostack++ = IS_INTERFACE(cb) ? TRUE : FALSE;
295 return ostack;
298 uintptr_t *isPrimitive(Class *class, MethodBlock *mb, uintptr_t *ostack) {
299 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
300 *ostack++ = IS_PRIMITIVE(cb) ? TRUE : FALSE;
301 return ostack;
304 uintptr_t *isArray(Class *class, MethodBlock *mb, uintptr_t *ostack) {
305 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
306 *ostack++ = IS_ARRAY(cb) ? TRUE : FALSE;
307 return ostack;
310 uintptr_t *isMember(Class *class, MethodBlock *mb, uintptr_t *ostack) {
311 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
312 *ostack++ = IS_MEMBER(cb) ? TRUE : FALSE;
313 return ostack;
316 uintptr_t *isLocal(Class *class, MethodBlock *mb, uintptr_t *ostack) {
317 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
318 *ostack++ = IS_LOCAL(cb) ? TRUE : FALSE;
319 return ostack;
322 uintptr_t *isAnonymous(Class *class, MethodBlock *mb, uintptr_t *ostack) {
323 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
324 *ostack++ = IS_ANONYMOUS(cb) ? TRUE : FALSE;
325 return ostack;
328 uintptr_t *getEnclosingClass0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
329 Class *clazz = GET_CLASS(ostack[0]);
330 *ostack++ = (uintptr_t) getEnclosingClass(clazz);
331 return ostack;
334 uintptr_t *getEnclosingMethod0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
335 Class *clazz = GET_CLASS(ostack[0]);
336 *ostack++ = (uintptr_t) getEnclosingMethodObject(clazz);
337 return ostack;
340 uintptr_t *getEnclosingConstructor(Class *class, MethodBlock *mb, uintptr_t *ostack) {
341 Class *clazz = GET_CLASS(ostack[0]);
342 *ostack++ = (uintptr_t) getEnclosingConstructorObject(clazz);
343 return ostack;
346 uintptr_t *getClassSignature(Class *class, MethodBlock *mb, uintptr_t *ostack) {
347 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
348 Object *string = NULL;
350 if(cb->signature != NULL) {
351 char *dot_name = slash2dots(cb->signature);
352 string = createString(dot_name);
353 sysFree(dot_name);
356 *ostack++ = (uintptr_t)string;
357 return ostack;
360 uintptr_t *getSuperclass(Class *class, MethodBlock *mb, uintptr_t *ostack) {
361 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
362 *ostack++ = (uintptr_t) (IS_PRIMITIVE(cb) || IS_INTERFACE(cb) ? NULL : cb->super);
363 return ostack;
366 uintptr_t *getComponentType(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
367 Class *class = GET_CLASS(ostack[0]);
368 ClassBlock *cb = CLASS_CB(class);
369 Class *componentType = NULL;
371 if(IS_ARRAY(cb))
372 switch(cb->name[1]) {
373 case '[':
374 componentType = findArrayClassFromClass(&cb->name[1], class);
375 break;
377 default:
378 componentType = cb->element_class;
379 break;
382 *ostack++ = (uintptr_t) componentType;
383 return ostack;
386 uintptr_t *getName(Class *class, MethodBlock *mb, uintptr_t *ostack) {
387 char *dot_name = slash2dots(CLASS_CB((GET_CLASS(*ostack)))->name);
388 Object *string = createString(dot_name);
389 *ostack++ = (uintptr_t)string;
390 sysFree(dot_name);
391 return ostack;
394 uintptr_t *getDeclaredClasses(Class *class, MethodBlock *mb, uintptr_t *ostack) {
395 Class *clazz = GET_CLASS(ostack[0]);
396 int public = ostack[1];
397 *ostack++ = (uintptr_t) getClassClasses(clazz, public);
398 return ostack;
401 uintptr_t *getDeclaringClass0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
402 Class *clazz = GET_CLASS(ostack[0]);
403 *ostack++ = (uintptr_t) getDeclaringClass(clazz);
404 return ostack;
407 uintptr_t *getDeclaredConstructors(Class *class, MethodBlock *mb, uintptr_t *ostack) {
408 Class *clazz = GET_CLASS(ostack[0]);
409 int public = ostack[1];
410 *ostack++ = (uintptr_t) getClassConstructors(clazz, public);
411 return ostack;
414 uintptr_t *getDeclaredMethods(Class *class, MethodBlock *mb, uintptr_t *ostack) {
415 Class *clazz = GET_CLASS(ostack[0]);
416 int public = ostack[1];
417 *ostack++ = (uintptr_t) getClassMethods(clazz, public);
418 return ostack;
421 uintptr_t *getDeclaredFields(Class *class, MethodBlock *mb, uintptr_t *ostack) {
422 Class *clazz = GET_CLASS(ostack[0]);
423 int public = ostack[1];
424 *ostack++ = (uintptr_t) getClassFields(clazz, public);
425 return ostack;
428 uintptr_t *getClassDeclaredAnnotations(Class *class, MethodBlock *mb, uintptr_t *ostack) {
429 Class *clazz = GET_CLASS(ostack[0]);
430 *ostack++ = (uintptr_t) getClassAnnotations(clazz);
431 return ostack;
434 uintptr_t *getInterfaces(Class *class, MethodBlock *mb, uintptr_t *ostack) {
435 Class *clazz = GET_CLASS(ostack[0]);
436 *ostack++ = (uintptr_t) getClassInterfaces(clazz);
437 return ostack;
440 uintptr_t *getClassLoader(Class *class, MethodBlock *mb, uintptr_t *ostack) {
441 Class *clazz = GET_CLASS(*ostack);
442 *ostack++ = (uintptr_t)CLASS_CB(clazz)->class_loader;
443 return ostack;
446 uintptr_t *getClassModifiers(Class *class, MethodBlock *mb, uintptr_t *ostack) {
447 Class *clazz = GET_CLASS(ostack[0]);
448 int ignore_inner_attrs = ostack[1];
449 ClassBlock *cb = CLASS_CB(clazz);
451 if(!ignore_inner_attrs && cb->declaring_class)
452 *ostack++ = (uintptr_t)cb->inner_access_flags;
453 else
454 *ostack++ = (uintptr_t)cb->access_flags;
456 return ostack;
459 uintptr_t *forName0(uintptr_t *ostack, int resolve, Object *loader) {
460 Object *string = (Object *)ostack[0];
461 Class *class = NULL;
462 int len, i = 0;
463 char *cstr;
465 if(string == NULL) {
466 signalException("java/lang/NullPointerException", NULL);
467 return ostack;
470 cstr = String2Utf8(string);
471 len = strlen(cstr);
473 /* Check the classname to see if it's valid. It can be
474 a 'normal' class or an array class, starting with a [ */
476 if(cstr[0] == '[') {
477 for(; cstr[i] == '['; i++);
478 switch(cstr[i]) {
479 case 'Z':
480 case 'B':
481 case 'C':
482 case 'S':
483 case 'I':
484 case 'F':
485 case 'J':
486 case 'D':
487 if(len-i != 1)
488 goto out;
489 break;
490 case 'L':
491 if(cstr[i+1] == '[' || cstr[len-1] != ';')
492 goto out;
493 break;
494 default:
495 goto out;
496 break;
500 /* Scan the classname and convert it to internal form
501 by converting dots to slashes. Reject classnames
502 containing slashes, as this is an invalid character */
504 for(; i < len; i++) {
505 if(cstr[i] == '/')
506 goto out;
507 if(cstr[i] == '.')
508 cstr[i] = '/';
511 class = findClassFromClassLoader(cstr, loader);
513 out:
514 if(class == NULL) {
515 Object *e = exceptionOccurred();
516 clearException();
517 signalChainedException("java/lang/ClassNotFoundException", cstr, e);
518 } else
519 if(resolve)
520 initClass(class);
522 sysFree(cstr);
523 *ostack++ = (uintptr_t)class;
524 return ostack;
527 uintptr_t *forName(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
528 int init = ostack[1];
529 Object *loader = (Object*)ostack[2];
530 return forName0(ostack, init, loader);
533 uintptr_t *throwException(Class *class, MethodBlock *mb, uintptr_t *ostack) {
534 Object *excep = (Object *)ostack[0];
535 setException(excep);
536 return ostack;
539 uintptr_t *hasClassInitializer(Class *class, MethodBlock *mb, uintptr_t *ostack) {
540 Class *clazz = (Class*)ostack[0];
541 *ostack++ = findMethod(clazz, "<clinit>", "()V") == NULL ? FALSE : TRUE;
542 return ostack;
545 /* java.lang.VMThrowable */
547 uintptr_t *fillInStackTrace(Class *class, MethodBlock *mb, uintptr_t *ostack) {
548 *ostack++ = (uintptr_t) setStackTrace();
549 return ostack;
552 uintptr_t *getStackTrace(Class *class, MethodBlock *m, uintptr_t *ostack) {
553 Object *this = (Object *)*ostack;
554 *ostack++ = (uintptr_t) convertStackTrace(this);
555 return ostack;
558 /* gnu.classpath.VMStackWalker */
560 uintptr_t *getCallingClass(Class *class, MethodBlock *mb, uintptr_t *ostack) {
561 *ostack++ = (uintptr_t) getCallerCallerClass();
562 return ostack;
565 uintptr_t *getCallingClassLoader(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
566 Class *class = getCallerCallerClass();
568 *ostack++ = (uintptr_t) (class ? CLASS_CB(class)->class_loader : NULL);
569 return ostack;
572 uintptr_t *getClassContext(Class *class, MethodBlock *mb, uintptr_t *ostack) {
573 Class *class_class = findArrayClass("[Ljava/lang/Class;");
574 Object *array;
575 Frame *last;
577 if(class_class == NULL)
578 return ostack;
580 if((last = getCallerFrame(getExecEnv()->last_frame)) == NULL)
581 array = allocArray(class_class, 0, sizeof(Class*));
582 else {
583 Frame *bottom = last;
584 int depth = 0;
586 do {
587 for(; last->mb != NULL; last = last->prev, depth++);
588 } while((last = last->prev)->prev != NULL);
590 array = allocArray(class_class, depth, sizeof(Class*));
592 if(array != NULL) {
593 Class **data = ARRAY_DATA(array);
595 do {
596 for(; bottom->mb != NULL; bottom = bottom->prev)
597 *data++ = bottom->mb->class;
598 } while((bottom = bottom->prev)->prev != NULL);
602 *ostack++ = (uintptr_t)array;
603 return ostack;
606 uintptr_t *firstNonNullClassLoader(Class *class, MethodBlock *mb, uintptr_t *ostack) {
607 Frame *last = getExecEnv()->last_frame;
608 Object *loader = NULL;
610 do {
611 for(; last->mb != NULL; last = last->prev)
612 if((loader = CLASS_CB(last->mb->class)->class_loader) != NULL)
613 goto out;
614 } while((last = last->prev)->prev != NULL);
616 out:
617 *ostack++ = (uintptr_t)loader;
618 return ostack;
621 /* java.lang.VMClassLoader */
623 /* loadClass(Ljava/lang/String;I)Ljava/lang/Class; */
624 uintptr_t *loadClass(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
625 int resolve = ostack[1];
626 return forName0(ostack, resolve, NULL);
629 /* getPrimitiveClass(C)Ljava/lang/Class; */
630 uintptr_t *getPrimitiveClass(Class *class, MethodBlock *mb, uintptr_t *ostack) {
631 char prim_type = *ostack;
632 *ostack++ = (uintptr_t)findPrimitiveClass(prim_type);
633 return ostack;
636 uintptr_t *defineClass0(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
637 Object *class_loader = (Object *)ostack[0];
638 Object *string = (Object *)ostack[1];
639 Object *array = (Object *)ostack[2];
640 int offset = ostack[3];
641 int data_len = ostack[4];
642 uintptr_t pd = ostack[5];
643 Class *class = NULL;
645 if(array == NULL)
646 signalException("java/lang/NullPointerException", NULL);
647 else
648 if((offset < 0) || (data_len < 0) ||
649 ((offset + data_len) > ARRAY_LEN(array)))
650 signalException("java/lang/ArrayIndexOutOfBoundsException", NULL);
651 else {
652 char *data = ARRAY_DATA(array);
653 char *cstr = string ? String2Utf8(string) : NULL;
654 int len = string ? strlen(cstr) : 0;
655 int i;
657 for(i = 0; i < len; i++)
658 if(cstr[i]=='.') cstr[i]='/';
660 if((class = defineClass(cstr, data, offset, data_len, class_loader)) != NULL) {
661 INST_DATA(class)[pd_offset] = pd;
662 linkClass(class);
665 sysFree(cstr);
668 *ostack++ = (uintptr_t) class;
669 return ostack;
672 uintptr_t *findLoadedClass(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
673 Object *class_loader = (Object *)ostack[0];
674 Object *string = (Object *)ostack[1];
675 Class *class;
676 char *cstr;
677 int len, i;
679 if(string == NULL) {
680 signalException("java/lang/NullPointerException", NULL);
681 return ostack;
684 cstr = String2Cstr(string);
685 len = strlen(cstr);
687 for(i = 0; i < len; i++)
688 if(cstr[i]=='.') cstr[i]='/';
690 class = findHashedClass(cstr, class_loader);
692 sysFree(cstr);
693 *ostack++ = (uintptr_t) class;
694 return ostack;
697 uintptr_t *resolveClass0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
698 Class *clazz = (Class *)*ostack;
699 initClass(clazz);
700 return ostack;
703 uintptr_t *getBootClassPathSize(Class *class, MethodBlock *mb, uintptr_t *ostack) {
704 *ostack++ = bootClassPathSize();
705 return ostack;
708 uintptr_t *getBootClassPathResource(Class *class, MethodBlock *mb, uintptr_t *ostack) {
709 Object *string = (Object *) ostack[0];
710 char *filename = String2Cstr(string);
711 int index = ostack[1];
713 *ostack++ = (uintptr_t) bootClassPathResource(filename, index);
714 return ostack;
717 /* java.lang.reflect.Constructor */
719 uintptr_t *constructNative(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
720 Object *array = (Object*)ostack[1];
721 Class *decl_class = (Class*)ostack[2];
722 Object *param_types = (Object*)ostack[3];
723 ClassBlock *cb = CLASS_CB(decl_class);
724 MethodBlock *mb = &(cb->methods[ostack[4]]);
725 int no_access_check = ostack[5];
726 Object *ob = NULL;
728 if(cb->access_flags & ACC_ABSTRACT)
729 signalException("java/lang/InstantiationError", cb->name);
730 else
731 ob = allocObject(mb->class);
733 if(ob) invoke(ob, mb, array, param_types, !no_access_check);
735 *ostack++ = (uintptr_t) ob;
736 return ostack;
739 uintptr_t *getMethodModifiers(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
740 Class *decl_class = (Class*)ostack[1];
741 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
742 *ostack++ = (uintptr_t) mb->access_flags;
743 return ostack;
746 uintptr_t *getMethodSignature(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
747 Class *decl_class = (Class*)ostack[1];
748 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
749 Object *string = NULL;
751 if(mb->signature != NULL) {
752 char *dot_name = slash2dots(mb->signature);
753 string = createString(dot_name);
754 sysFree(dot_name);
757 *ostack++ = (uintptr_t)string;
758 return ostack;
761 uintptr_t *getDefaultValue(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
762 Class *decl_class = (Class*)ostack[1];
763 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
764 *ostack++ = (uintptr_t)getMethodDefaultValue(mb);
765 return ostack;
768 uintptr_t *getMethodDeclaredAnnotations(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
769 Class *decl_class = (Class*)ostack[1];
770 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
771 *ostack++ = (uintptr_t)getMethodAnnotations(mb);
772 return ostack;
775 uintptr_t *getParameterAnnotations(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
776 Class *decl_class = (Class*)ostack[1];
777 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
778 *ostack++ = (uintptr_t)getMethodParameterAnnotations(mb);
779 return ostack;
782 uintptr_t *getFieldModifiers(Class *class, MethodBlock *mb, uintptr_t *ostack) {
783 Class *decl_class = (Class*)ostack[1];
784 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
785 *ostack++ = (uintptr_t) fb->access_flags;
786 return ostack;
789 uintptr_t *getFieldSignature(Class *class, MethodBlock *mb, uintptr_t *ostack) {
790 Class *decl_class = (Class*)ostack[1];
791 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
792 Object *string = NULL;
794 if(fb->signature != NULL) {
795 char *dot_name = slash2dots(fb->signature);
796 string = createString(dot_name);
797 sysFree(dot_name);
800 *ostack++ = (uintptr_t)string;
801 return ostack;
804 uintptr_t *getFieldDeclaredAnnotations(Class *class, MethodBlock *mb, uintptr_t *ostack) {
805 Class *decl_class = (Class*)ostack[1];
806 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
807 *ostack++ = (uintptr_t)getFieldAnnotations(fb);
808 return ostack;
811 Object *getAndCheckObject(uintptr_t *ostack, Class *type) {
812 Object *ob = (Object*)ostack[1];
814 if(ob == NULL) {
815 signalException("java/lang/NullPointerException", NULL);
816 return NULL;
819 if(!isInstanceOf(type, ob->class)) {
820 signalException("java/lang/IllegalArgumentException",
821 "object is not an instance of declaring class");
822 return NULL;
825 return ob;
828 uintptr_t *getPntr2Field(uintptr_t *ostack) {
829 Class *decl_class = (Class *)ostack[2];
830 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[4]]);
831 int no_access_check = ostack[5];
832 Object *ob;
834 if(!no_access_check) {
835 Class *caller = getCallerCallerClass();
836 if(!checkClassAccess(decl_class, caller) || !checkFieldAccess(fb, caller)) {
837 signalException("java/lang/IllegalAccessException", "field is not accessible");
838 return NULL;
842 if(fb->access_flags & ACC_STATIC) {
843 initClass(decl_class);
844 return &fb->static_value;
847 if((ob = getAndCheckObject(ostack, decl_class)) == NULL)
848 return NULL;
850 return &(INST_DATA(ob)[fb->offset]);
853 uintptr_t *getField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
854 Class *field_type = (Class *)ostack[3];
855 uintptr_t *field;
857 /* If field is static, getPntr2Field also initialises the field's declaring class */
858 if((field = getPntr2Field(ostack)) != NULL)
859 *ostack++ = (uintptr_t) getReflectReturnObject(field_type, field);
861 return ostack;
864 uintptr_t *getPrimitiveField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
865 Class *field_type = (Class *)ostack[3];
866 int type_no = ostack[6];
868 ClassBlock *type_cb = CLASS_CB(field_type);
869 uintptr_t *field;
871 /* If field is static, getPntr2Field also initialises the field's declaring class */
872 if(((field = getPntr2Field(ostack)) != NULL) && (!(IS_PRIMITIVE(type_cb)) ||
873 ((ostack = widenPrimitiveValue(getPrimTypeIndex(type_cb), type_no, field, ostack)) == NULL)))
874 signalException("java/lang/IllegalArgumentException", "field type mismatch");
876 return ostack;
879 uintptr_t *setField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
880 Class *field_type = (Class *)ostack[3];
881 Object *value = (Object*)ostack[6];
882 uintptr_t *field;
884 /* If field is static, getPntr2Field also initialises the field's declaring class */
885 if(((field = getPntr2Field(ostack)) != NULL) &&
886 (unwrapAndWidenObject(field_type, value, field) == NULL))
887 signalException("java/lang/IllegalArgumentException", "field type mismatch");
889 return ostack;
892 uintptr_t *setPrimitiveField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
893 Class *field_type = (Class *)ostack[3];
894 int type_no = ostack[6];
896 ClassBlock *type_cb = CLASS_CB(field_type);
897 uintptr_t *field;
899 /* If field is static, getPntr2Field also initialises the field's declaring class */
900 if(((field = getPntr2Field(ostack)) != NULL) && (!(IS_PRIMITIVE(type_cb)) ||
901 (widenPrimitiveValue(type_no, getPrimTypeIndex(type_cb), &ostack[7], field) == NULL)))
902 signalException("java/lang/IllegalArgumentException", "field type mismatch");
904 return ostack;
907 /* java.lang.reflect.Method */
909 uintptr_t *invokeNative(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
910 Object *array = (Object*)ostack[2];
911 Class *decl_class = (Class*)ostack[3];
912 Object *param_types = (Object*)ostack[4];
913 Class *ret_type = (Class*)ostack[5];
914 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[6]]);
915 int no_access_check = ostack[7];
916 Object *ob = NULL;
917 uintptr_t *ret;
919 /* If it's a static method, class may not be initialised */
920 if(mb->access_flags & ACC_STATIC)
921 initClass(decl_class);
922 else {
923 /* Interfaces are not normally initialised. */
924 if(IS_INTERFACE(CLASS_CB(decl_class)))
925 initClass(decl_class);
927 if(((ob = getAndCheckObject(ostack, decl_class)) == NULL) ||
928 ((mb = lookupVirtualMethod(ob, mb)) == NULL))
929 return ostack;
932 if((ret = (uintptr_t*) invoke(ob, mb, array, param_types, !no_access_check)) != NULL)
933 *ostack++ = (uintptr_t) getReflectReturnObject(ret_type, ret);
935 return ostack;
938 /* java.lang.VMString */
940 /* static method - intern(Ljava/lang/String;)Ljava/lang/String; */
941 uintptr_t *intern(Class *class, MethodBlock *mb, uintptr_t *ostack) {
942 Object *string = (Object*)ostack[0];
943 ostack[0] = (uintptr_t)findInternedString(string);
944 return ostack+1;
947 /* java.lang.VMThread */
949 /* static method currentThread()Ljava/lang/Thread; */
950 uintptr_t *currentThread(Class *class, MethodBlock *mb, uintptr_t *ostack) {
951 *ostack++ = (uintptr_t)getExecEnv()->thread;
952 return ostack;
955 /* static method create(Ljava/lang/Thread;J)V */
956 uintptr_t *create(Class *class, MethodBlock *mb, uintptr_t *ostack) {
957 Object *this = (Object *)ostack[0];
958 long long stack_size = *((long long*)&ostack[1]);
959 createJavaThread(this, stack_size);
960 return ostack;
963 /* static method sleep(JI)V */
964 uintptr_t *jamSleep(Class *class, MethodBlock *mb, uintptr_t *ostack) {
965 long long ms = *((long long *)&ostack[0]);
966 int ns = ostack[2];
967 Thread *thread = threadSelf();
969 threadSleep(thread, ms, ns);
970 return ostack;
973 /* instance method interrupt()V */
974 uintptr_t *interrupt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
975 Object *this = (Object *)*ostack;
976 Thread *thread = threadSelf0(this);
977 if(thread)
978 threadInterrupt(thread);
979 return ostack;
982 /* instance method isAlive()Z */
983 uintptr_t *isAlive(Class *class, MethodBlock *mb, uintptr_t *ostack) {
984 Object *this = (Object *)*ostack;
985 Thread *thread = threadSelf0(this);
986 *ostack++ = thread ? threadIsAlive(thread) : FALSE;
987 return ostack;
990 /* static method yield()V */
991 uintptr_t *yield(Class *class, MethodBlock *mb, uintptr_t *ostack) {
992 Thread *thread = threadSelf();
993 threadYield(thread);
994 return ostack;
997 /* instance method isInterrupted()Z */
998 uintptr_t *isInterrupted(Class *class, MethodBlock *mb, uintptr_t *ostack) {
999 Object *this = (Object *)*ostack;
1000 Thread *thread = threadSelf0(this);
1001 *ostack++ = thread ? threadIsInterrupted(thread) : FALSE;
1002 return ostack;
1005 /* static method interrupted()Z */
1006 uintptr_t *interrupted(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1007 Thread *thread = threadSelf();
1008 *ostack++ = threadInterrupted(thread);
1009 return ostack;
1012 /* instance method nativeSetPriority(I)V */
1013 uintptr_t *nativeSetPriority(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1014 return ostack+1;
1017 /* instance method holdsLock(Ljava/lang/Object;)Z */
1018 uintptr_t *holdsLock(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1019 Object *ob = (Object *)ostack[0];
1020 if(ob == NULL)
1021 signalException("java/lang/NullPointerException", NULL);
1022 else
1023 *ostack++ = objectLockedByCurrent(ob);
1024 return ostack;
1027 /* instance method getState()Ljava/lang/String; */
1028 uintptr_t *getState(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1029 Object *this = (Object *)*ostack;
1030 Thread *thread = threadSelf0(this);
1031 char *state = thread ? getThreadStateString(thread) : "TERMINATED";
1033 *ostack++ = (uintptr_t)Cstr2String(state);
1034 return ostack;
1037 /* java.security.VMAccessController */
1039 /* instance method getStack()[[Ljava/lang/Object; */
1040 uintptr_t *getStack(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1041 Class *object_class = findArrayClass("[[Ljava/lang/Object;");
1042 Class *class_class = findArrayClass("[Ljava/lang/Class;");
1043 Class *string_class = findArrayClass("[Ljava/lang/String;");
1044 Object *stack, *names, *classes;
1045 Frame *frame;
1046 int depth;
1048 if(object_class == NULL || class_class == NULL || string_class == NULL)
1049 return ostack;
1051 frame = getExecEnv()->last_frame;
1052 depth = 0;
1054 do {
1055 for(; frame->mb != NULL; frame = frame->prev, depth++);
1056 } while((frame = frame->prev)->prev != NULL);
1058 stack = allocArray(object_class, 2, sizeof(Object*));
1059 classes = allocArray(class_class, depth, sizeof(Object*));
1060 names = allocArray(string_class, depth, sizeof(Object*));
1062 if(stack != NULL && names != NULL && classes != NULL) {
1063 Class **dcl = ARRAY_DATA(classes);
1064 Object **dnm = ARRAY_DATA(names);
1065 Object **stk = ARRAY_DATA(stack);
1067 frame = getExecEnv()->last_frame;
1069 do {
1070 for(; frame->mb != NULL; frame = frame->prev) {
1071 *dcl++ = frame->mb->class;
1072 *dnm++ = createString(frame->mb->name);
1074 } while((frame = frame->prev)->prev != NULL);
1076 stk[0] = classes;
1077 stk[1] = names;
1080 *ostack++ = (uintptr_t) stack;
1081 return ostack;
1084 uintptr_t *getThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1085 *ostack++ = getThreadsCount();
1086 return ostack;
1089 uintptr_t *getPeakThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1090 *ostack++ = getPeakThreadsCount();
1091 return ostack;
1094 uintptr_t *getTotalStartedThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1095 *(u8*)ostack = getTotalStartedThreadsCount();
1096 return ostack + 2;
1099 uintptr_t *resetPeakThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1100 resetPeakThreadsCount();
1101 return ostack;
1104 uintptr_t *findMonitorDeadlockedThreads(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1105 *ostack++ = (uintptr_t)NULL;
1106 return ostack;
1109 uintptr_t *getThreadInfoForId(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1110 long long id = *((long long *)&ostack[0]);
1111 int max_depth = ostack[2];
1113 Thread *thread = findThreadById(id);
1114 Object *info = NULL;
1116 if(thread != NULL) {
1117 Class *info_class = findSystemClass("java/lang/management/ThreadInfo");
1119 if(info_class != NULL) {
1120 MethodBlock *init = findMethod(info_class, "<init>",
1121 "(Ljava/lang/Thread;JJLjava/lang/Object;"
1122 "Ljava/lang/Thread;JJZZ[Ljava/lang/StackTraceElement;)V");
1123 if(init != NULL) {
1124 Frame *last;
1125 int in_native;
1126 Object *vmthrowable;
1127 int self = thread == threadSelf();
1129 if(!self)
1130 suspendThread(thread);
1132 vmthrowable = setStackTrace0(thread->ee, max_depth);
1134 last = thread->ee->last_frame;
1135 in_native = last->prev == NULL || last->mb->access_flags & ACC_NATIVE;
1137 if(!self)
1138 resumeThread(thread);
1140 if(vmthrowable != NULL) {
1141 Object *trace;
1142 if((info = allocObject(info_class)) != NULL &&
1143 (trace = convertStackTrace(vmthrowable)) != NULL) {
1145 Monitor *mon = thread->blocked_mon;
1146 Object *lock = mon != NULL ? mon->obj : NULL;
1147 Thread *owner = mon != NULL ? mon->owner : NULL;
1148 Object *lock_owner = owner != NULL ? owner->ee->thread : NULL;
1150 executeMethod(info, init, thread->ee->thread, thread->blocked_count, 0LL, lock,
1151 lock_owner, thread->waited_count, 0LL, in_native, FALSE, trace);
1158 *ostack++ = (uintptr_t)info;
1159 return ostack;
1162 /* sun.misc.Unsafe */
1164 static volatile uintptr_t spinlock = 0;
1166 void lockSpinLock() {
1167 while(!LOCKWORD_COMPARE_AND_SWAP(&spinlock, 0, 1));
1170 void unlockSpinLock() {
1171 LOCKWORD_WRITE(&spinlock, 0);
1174 uintptr_t *objectFieldOffset(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1175 FieldBlock *fb = fbFromReflectObject((Object*)ostack[1]);
1177 *(long long*)ostack = (long long)(uintptr_t)&INST_DATA((Object*)NULL)[fb->offset];
1178 return ostack + 2;
1181 uintptr_t *compareAndSwapInt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1182 long long offset = *((long long *)&ostack[2]);
1183 uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1184 uintptr_t expect = ostack[4];
1185 uintptr_t update = ostack[5];
1186 int result;
1188 #ifdef COMPARE_AND_SWAP
1189 result = COMPARE_AND_SWAP(addr, expect, update);
1190 #else
1191 lockSpinLock();
1192 if((result = (*addr == expect)))
1193 *addr = update;
1194 unlockSpinLock();
1195 #endif
1197 *ostack++ = result;
1198 return ostack;
1201 uintptr_t *compareAndSwapLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1202 long long offset = *((long long *)&ostack[2]);
1203 long long *addr = (long long*)((char*)ostack[1] + offset);
1204 long long expect = *((long long *)&ostack[4]);
1205 long long update = *((long long *)&ostack[6]);
1206 int result;
1208 #ifdef COMPARE_AND_SWAP_64
1209 result = COMPARE_AND_SWAP_64(addr, expect, update);
1210 #else
1211 lockSpinLock();
1212 if((result = (*addr == expect)))
1213 *addr = update;
1214 unlockSpinLock();
1215 #endif
1217 *ostack++ = result;
1218 return ostack;
1221 uintptr_t *putOrderedInt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1222 long long offset = *((long long *)&ostack[2]);
1223 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1224 uintptr_t value = ostack[4];
1226 *addr = value;
1227 return ostack;
1230 uintptr_t *putOrderedLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1231 long long offset = *((long long *)&ostack[2]);
1232 long long value = *((long long *)&ostack[4]);
1233 volatile long long *addr = (long long*)((char*)ostack[1] + offset);
1235 if(sizeof(uintptr_t) == 8)
1236 *addr = value;
1237 else {
1238 lockSpinLock();
1239 *addr = value;
1240 unlockSpinLock();
1243 return ostack;
1246 uintptr_t *putIntVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1247 long long offset = *((long long *)&ostack[2]);
1248 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1249 uintptr_t value = ostack[4];
1251 MBARRIER();
1252 *addr = value;
1254 return ostack;
1257 uintptr_t *getIntVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1258 long long offset = *((long long *)&ostack[2]);
1259 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1261 *ostack++ = *addr;
1262 MBARRIER();
1264 return ostack;
1267 uintptr_t *putLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1268 long long offset = *((long long *)&ostack[2]);
1269 long long value = *((long long *)&ostack[4]);
1270 long long *addr = (long long*)((char*)ostack[1] + offset);
1272 if(sizeof(uintptr_t) == 8)
1273 *addr = value;
1274 else {
1275 lockSpinLock();
1276 *addr = value;
1277 unlockSpinLock();
1280 return ostack;
1283 uintptr_t *getLongVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1284 long long offset = *((long long *)&ostack[2]);
1285 volatile long long *addr = (long long*)((char*)ostack[1] + offset);
1287 if(sizeof(uintptr_t) == 8)
1288 *(long long*)ostack = *addr;
1289 else {
1290 lockSpinLock();
1291 *(long long*)ostack = *addr;
1292 unlockSpinLock();
1295 return ostack + 2;
1298 uintptr_t *getLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1299 long long offset = *((long long *)&ostack[2]);
1300 long long *addr = (long long*)((char*)ostack[1] + offset);
1302 if(sizeof(uintptr_t) == 8)
1303 *(long long*)ostack = *addr;
1304 else {
1305 lockSpinLock();
1306 *(long long*)ostack = *addr;
1307 unlockSpinLock();
1310 return ostack + 2;
1313 uintptr_t *putObject(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1314 long long offset = *((long long *)&ostack[2]);
1315 uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1316 uintptr_t value = ostack[4];
1318 *addr = value;
1319 return ostack;
1322 uintptr_t *arrayBaseOffset(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1323 *ostack++ = (uintptr_t) ARRAY_DATA((Object*)NULL);
1324 return ostack;
1327 uintptr_t *arrayIndexScale(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1328 Class *array_class = (Class*)ostack[1];
1329 ClassBlock *cb = CLASS_CB(array_class);
1330 int scale = 0;
1332 if(cb->name[0] == '[')
1333 switch(cb->name[1]) {
1334 case 'I':
1335 case 'F':
1336 scale = 4;
1337 break;
1339 case '[':
1340 case 'L':
1341 scale = sizeof(Object*);
1342 break;
1344 case 'J':
1345 case 'D':
1346 scale = 8;
1347 break;
1350 *ostack++ = scale;
1351 return ostack;
1354 uintptr_t *unpark(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1355 return ostack;
1358 uintptr_t *park(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1359 return ostack;
1362 uintptr_t *vmSupportsCS8(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1363 *ostack++ = FALSE;
1364 return ostack;
1367 VMMethod vm_object[] = {
1368 {"getClass", getClass},
1369 {"clone", jamClone},
1370 {"wait", jamWait},
1371 {"notify", notify},
1372 {"notifyAll", notifyAll},
1373 {NULL, NULL}
1376 VMMethod vm_system[] = {
1377 {"arraycopy", arraycopy},
1378 {"identityHashCode", identityHashCode},
1379 {NULL, NULL}
1382 VMMethod vm_runtime[] = {
1383 {"availableProcessors", availableProcessors},
1384 {"freeMemory", freeMemory},
1385 {"totalMemory", totalMemory},
1386 {"maxMemory", maxMemory},
1387 {"gc", gc},
1388 {"runFinalization", runFinalization},
1389 {"exit", exitInternal},
1390 {"nativeLoad", nativeLoad},
1391 {"mapLibraryName", mapLibraryName},
1392 {NULL, NULL}
1395 VMMethod vm_class[] = {
1396 {"isInstance", isInstance},
1397 {"isAssignableFrom", isAssignableFrom},
1398 {"isInterface", isInterface},
1399 {"isPrimitive", isPrimitive},
1400 {"isArray", isArray},
1401 {"isMemberClass", isMember},
1402 {"isLocalClass", isLocal},
1403 {"isAnonymousClass", isAnonymous},
1404 {"getEnclosingClass", getEnclosingClass0},
1405 {"getEnclosingMethod", getEnclosingMethod0},
1406 {"getEnclosingConstructor", getEnclosingConstructor},
1407 {"getClassSignature", getClassSignature},
1408 {"getSuperclass", getSuperclass},
1409 {"getComponentType", getComponentType},
1410 {"getName", getName},
1411 {"getDeclaredClasses", getDeclaredClasses},
1412 {"getDeclaringClass", getDeclaringClass0},
1413 {"getDeclaredConstructors", getDeclaredConstructors},
1414 {"getDeclaredMethods", getDeclaredMethods},
1415 {"getDeclaredFields", getDeclaredFields},
1416 {"getInterfaces", getInterfaces},
1417 {"getClassLoader", getClassLoader},
1418 {"getModifiers", getClassModifiers},
1419 {"forName", forName},
1420 {"throwException", throwException},
1421 {"hasClassInitializer", hasClassInitializer},
1422 {"getDeclaredAnnotations", getClassDeclaredAnnotations},
1423 {NULL, NULL}
1426 VMMethod vm_string[] = {
1427 {"intern", intern},
1428 {NULL, NULL}
1431 VMMethod vm_thread[] = {
1432 {"currentThread", currentThread},
1433 {"create", create},
1434 {"sleep", jamSleep},
1435 {"interrupt", interrupt},
1436 {"isAlive", isAlive},
1437 {"yield", yield},
1438 {"isInterrupted", isInterrupted},
1439 {"interrupted", interrupted},
1440 {"nativeSetPriority", nativeSetPriority},
1441 {"holdsLock", holdsLock},
1442 {"getState", getState},
1443 {NULL, NULL}
1446 VMMethod vm_throwable[] = {
1447 {"fillInStackTrace", fillInStackTrace},
1448 {"getStackTrace", getStackTrace},
1449 {NULL, NULL}
1452 VMMethod vm_classloader[] = {
1453 {"loadClass", loadClass},
1454 {"getPrimitiveClass", getPrimitiveClass},
1455 {"defineClass", defineClass0},
1456 {"findLoadedClass", findLoadedClass},
1457 {"resolveClass", resolveClass0},
1458 {"getBootClassPathSize", getBootClassPathSize},
1459 {"getBootClassPathResource", getBootClassPathResource},
1460 {NULL, NULL}
1463 VMMethod vm_reflect_constructor[] = {
1464 {"constructNative", constructNative},
1465 {"getConstructorModifiers", getMethodModifiers},
1466 {"getSignature", getMethodSignature},
1467 {"getDeclaredAnnotationsNative", getMethodDeclaredAnnotations},
1468 {"getParameterAnnotationsNative", getParameterAnnotations},
1469 {NULL, NULL}
1472 VMMethod vm_reflect_method[] = {
1473 {"invokeNative", invokeNative},
1474 {"getMethodModifiers", getMethodModifiers},
1475 {"getSignature", getMethodSignature},
1476 {"getDefaultValueNative", getDefaultValue},
1477 {"getDeclaredAnnotationsNative", getMethodDeclaredAnnotations},
1478 {"getParameterAnnotationsNative", getParameterAnnotations},
1479 {NULL, NULL}
1482 VMMethod vm_reflect_field[] = {
1483 {"getFieldModifiers", getFieldModifiers},
1484 {"getSignature", getFieldSignature},
1485 {"getDeclaredAnnotationsNative", getFieldDeclaredAnnotations},
1486 {"getField", getField},
1487 {"setField", setField},
1488 {"setZField", setPrimitiveField},
1489 {"setBField", setPrimitiveField},
1490 {"setCField", setPrimitiveField},
1491 {"setSField", setPrimitiveField},
1492 {"setIField", setPrimitiveField},
1493 {"setFField", setPrimitiveField},
1494 {"setJField", setPrimitiveField},
1495 {"setDField", setPrimitiveField},
1496 {"getZField", getPrimitiveField},
1497 {"getBField", getPrimitiveField},
1498 {"getCField", getPrimitiveField},
1499 {"getSField", getPrimitiveField},
1500 {"getIField", getPrimitiveField},
1501 {"getFField", getPrimitiveField},
1502 {"getJField", getPrimitiveField},
1503 {"getDField", getPrimitiveField},
1504 {NULL, NULL}
1507 VMMethod vm_system_properties[] = {
1508 {"preInit", propertiesPreInit},
1509 {"postInit", propertiesPostInit},
1510 {NULL, NULL}
1513 VMMethod vm_stack_walker[] = {
1514 {"getClassContext", getClassContext},
1515 {"getCallingClass", getCallingClass},
1516 {"getCallingClassLoader", getCallingClassLoader},
1517 {"firstNonNullClassLoader", firstNonNullClassLoader},
1518 {NULL, NULL}
1521 VMMethod sun_misc_unsafe[] = {
1522 {"objectFieldOffset", objectFieldOffset},
1523 {"compareAndSwapInt", compareAndSwapInt},
1524 {"compareAndSwapLong", compareAndSwapLong},
1525 {"compareAndSwapObject", compareAndSwapInt},
1526 {"putOrderedInt", putOrderedInt},
1527 {"putOrderedLong", putOrderedLong},
1528 {"putOrderedObject", putOrderedInt},
1529 {"putIntVolatile", putIntVolatile},
1530 {"getIntVolatile", getIntVolatile},
1531 {"putLongVolatile", putOrderedLong},
1532 {"putLong", putLong},
1533 {"getLongVolatile", getLongVolatile},
1534 {"getLong", getLong},
1535 {"putObjectVolatile", putIntVolatile},
1536 {"putObject", putObject},
1537 {"getObjectVolatile", getIntVolatile},
1538 {"arrayBaseOffset", arrayBaseOffset},
1539 {"arrayIndexScale", arrayIndexScale},
1540 {"unpark", unpark},
1541 {"park", park},
1542 {NULL, NULL}
1545 VMMethod vm_access_controller[] = {
1546 {"getStack", getStack},
1547 {NULL, NULL}
1550 VMMethod vm_threadmx_bean_impl[] = {
1551 {"getThreadCount", getThreadCount},
1552 {"getPeakThreadCount", getPeakThreadCount},
1553 {"getTotalStartedThreadCount", getTotalStartedThreadCount},
1554 {"resetPeakThreadCount", resetPeakThreadCount},
1555 {"getThreadInfoForId", getThreadInfoForId},
1556 {"findMonitorDeadlockedThreads",findMonitorDeadlockedThreads},
1557 {NULL, NULL}
1560 VMMethod concurrent_atomic_long[] = {
1561 {"VMSupportsCS8", vmSupportsCS8},
1562 {NULL, NULL}
1565 VMClass native_methods[] = {
1566 {"java/lang/VMClass", vm_class},
1567 {"java/lang/VMObject", vm_object},
1568 {"java/lang/VMThread", vm_thread},
1569 {"java/lang/VMSystem", vm_system},
1570 {"java/lang/VMString", vm_string},
1571 {"java/lang/VMRuntime", vm_runtime},
1572 {"java/lang/VMThrowable", vm_throwable},
1573 {"java/lang/VMClassLoader", vm_classloader},
1574 {"java/lang/reflect/Field", vm_reflect_field},
1575 {"java/lang/reflect/Method", vm_reflect_method},
1576 {"java/lang/reflect/Constructor", vm_reflect_constructor},
1577 {"java/security/VMAccessController", vm_access_controller},
1578 {"gnu/classpath/VMSystemProperties", vm_system_properties},
1579 {"gnu/classpath/VMStackWalker", vm_stack_walker},
1580 {"gnu/java/lang/management/VMThreadMXBeanImpl", vm_threadmx_bean_impl},
1581 {"sun/misc/Unsafe", sun_misc_unsafe},
1582 {"java/util/concurrent/atomic/AtomicLong", concurrent_atomic_long},
1583 {NULL, NULL}