jamvm

view src/natives.c @ 402:24373fc1d951

Add additional tracing support.

2008-08-04 Andrew John Hughes <gnu_andrew@member.fsf.org>

* .hgignore: Updated with autogen.sh output.
* configure.ac: Add new trace options.
* src/class.c,
* src/excep.c,
* src/natives.c,
* src/resolve.c: Add trace support.
* src/jam.h,
* src/dll.c,
* src/os/linux/os.c: Add support for reporting
the linking error using dlerror.
author andrew
date Tue Aug 05 05:46:09 2008 +0100 (2008-08-05)
parents 262ba95a495c
children 907df5a02819
line source
1 /*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
3 * Robert Lougher <rob@lougher.org.uk>.
4 *
5 * This file is part of JamVM.
6 *
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.
11 *
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.
16 *
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.
20 */
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"
37 #include "symbol.h"
38 #include "excep.h"
40 /* Trace native method handling */
41 #ifdef TRACENATIVE
42 #define TRACE(fmt, ...) jam_printf(fmt, ## __VA_ARGS__)
43 #define TRACE(fmt, ...)
44 #endif
46 static int pd_offset;
48 void initialiseNatives() {
49 FieldBlock *pd = findField(java_lang_Class, SYMBOL(pd),
50 SYMBOL(sig_java_security_ProtectionDomain));
52 if(pd == NULL) {
53 jam_fprintf(stderr, "Error initialising VM (initialiseNatives)\n");
54 exitVM(1);
55 }
56 pd_offset = pd->offset;
57 }
59 /* java.lang.VMObject */
61 uintptr_t *getClass(Class *class, MethodBlock *mb, uintptr_t *ostack) {
62 Object *ob = (Object*)*ostack;
63 *ostack++ = (uintptr_t)ob->class;
64 return ostack;
65 }
67 uintptr_t *jamClone(Class *class, MethodBlock *mb, uintptr_t *ostack) {
68 Object *ob = (Object*)*ostack;
69 *ostack++ = (uintptr_t)cloneObject(ob);
70 return ostack;
71 }
73 /* static method wait(Ljava/lang/Object;JI)V */
74 uintptr_t *jamWait(Class *class, MethodBlock *mb, uintptr_t *ostack) {
75 Object *obj = (Object *)ostack[0];
76 long long ms = *((long long *)&ostack[1]);
77 int ns = ostack[3];
79 objectWait(obj, ms, ns);
80 return ostack;
81 }
83 /* static method notify(Ljava/lang/Object;)V */
84 uintptr_t *notify(Class *class, MethodBlock *mb, uintptr_t *ostack) {
85 Object *obj = (Object *)*ostack;
86 objectNotify(obj);
87 return ostack;
88 }
90 /* static method notifyAll(Ljava/lang/Object;)V */
91 uintptr_t *notifyAll(Class *class, MethodBlock *mb, uintptr_t *ostack) {
92 Object *obj = (Object *)*ostack;
93 objectNotifyAll(obj);
94 return ostack;
95 }
97 /* java.lang.VMSystem */
99 /* arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V */
100 uintptr_t *arraycopy(Class *class, MethodBlock *mb, uintptr_t *ostack) {
101 Object *src = (Object *)ostack[0];
102 int start1 = ostack[1];
103 Object *dest = (Object *)ostack[2];
104 int start2 = ostack[3];
105 int length = ostack[4];
107 if((src == NULL) || (dest == NULL))
108 signalException(java_lang_NullPointerException, NULL);
109 else {
110 ClassBlock *scb = CLASS_CB(src->class);
111 ClassBlock *dcb = CLASS_CB(dest->class);
112 char *sdata = ARRAY_DATA(src);
113 char *ddata = ARRAY_DATA(dest);
115 if((scb->name[0] != '[') || (dcb->name[0] != '['))
116 goto storeExcep;
118 if((start1 < 0) || (start2 < 0) || (length < 0)
119 || ((start1 + length) > ARRAY_LEN(src))
120 || ((start2 + length) > ARRAY_LEN(dest))) {
121 signalException(java_lang_ArrayIndexOutOfBoundsException, NULL);
122 return ostack;
123 }
125 if(isInstanceOf(dest->class, src->class)) {
126 int size;
128 switch(scb->name[1]) {
129 case 'B':
130 case 'Z':
131 size = 1;
132 break;
133 case 'C':
134 case 'S':
135 size = 2;
136 break;
137 case 'I':
138 case 'F':
139 size = 4;
140 break;
141 case 'L':
142 case '[':
143 size = sizeof(Object*);
144 break;
145 case 'J':
146 case 'D':
147 default:
148 size = 8;
149 break;
150 }
152 memmove(ddata + start2*size, sdata + start1*size, length*size);
153 } else {
154 Object **sob, **dob;
155 int i;
157 if(!(((scb->name[1] == 'L') || (scb->name[1] == '[')) &&
158 ((dcb->name[1] == 'L') || (dcb->name[1] == '['))))
159 goto storeExcep;
161 /* Not compatible array types, but elements may be compatible...
162 e.g. src = [Ljava/lang/Object, dest = [Ljava/lang/String, but
163 all src = Strings - check one by one...
164 */
166 if(scb->dim > dcb->dim)
167 goto storeExcep;
169 sob = &((Object**)sdata)[start1];
170 dob = &((Object**)ddata)[start2];
172 for(i = 0; i < length; i++) {
173 if((*sob != NULL) && !arrayStoreCheck(dest->class, (*sob)->class))
174 goto storeExcep;
175 *dob++ = *sob++;
176 }
177 }
178 }
179 return ostack;
181 storeExcep:
182 signalException(java_lang_ArrayStoreException, NULL);
183 return ostack;
184 }
186 uintptr_t *identityHashCode(Class *class, MethodBlock *mb, uintptr_t *ostack) {
187 Object *ob = (Object*)*ostack;
188 uintptr_t addr = ob == NULL ? 0 : getObjectHashcode(ob);
190 *ostack++ = addr & 0xffffffff;
191 return ostack;
192 }
194 /* java.lang.VMRuntime */
196 uintptr_t *availableProcessors(Class *class, MethodBlock *mb, uintptr_t *ostack) {
197 *ostack++ = nativeAvailableProcessors();
198 return ostack;
199 }
201 uintptr_t *freeMemory(Class *class, MethodBlock *mb, uintptr_t *ostack) {
202 *(u8*)ostack = freeHeapMem();
203 return ostack + 2;
204 }
206 uintptr_t *totalMemory(Class *class, MethodBlock *mb, uintptr_t *ostack) {
207 *(u8*)ostack = totalHeapMem();
208 return ostack + 2;
209 }
211 uintptr_t *maxMemory(Class *class, MethodBlock *mb, uintptr_t *ostack) {
212 *(u8*)ostack = maxHeapMem();
213 return ostack + 2;
214 }
216 uintptr_t *gc(Class *class, MethodBlock *mb, uintptr_t *ostack) {
217 gc1();
218 return ostack;
219 }
221 uintptr_t *runFinalization(Class *class, MethodBlock *mb, uintptr_t *ostack) {
222 runFinalizers();
223 return ostack;
224 }
226 uintptr_t *exitInternal(Class *class, MethodBlock *mb, uintptr_t *ostack) {
227 int status = ostack[0];
228 jamvm_exit(status);
229 /* keep compiler happy */
230 return 0;
231 }
233 uintptr_t *nativeLoad(Class *class, MethodBlock *mb, uintptr_t *ostack) {
234 char *name = String2Cstr((Object*)ostack[0]);
235 Object *class_loader = (Object *)ostack[1];
237 ostack[0] = resolveDll(name, class_loader);
238 sysFree(name);
240 return ostack+1;
241 }
243 uintptr_t *mapLibraryName(Class *class, MethodBlock *mb, uintptr_t *ostack) {
244 char *name = String2Cstr((Object*)ostack[0]);
245 char *lib = getDllName(name);
246 sysFree(name);
248 *ostack++ = (uintptr_t)Cstr2String(lib);
249 sysFree(lib);
251 return ostack;
252 }
254 uintptr_t *propertiesPreInit(Class *class, MethodBlock *mb, uintptr_t *ostack) {
255 Object *properties = (Object *)*ostack;
256 addDefaultProperties(properties);
257 return ostack;
258 }
260 uintptr_t *propertiesPostInit(Class *class, MethodBlock *mb, uintptr_t *ostack) {
261 Object *properties = (Object *)*ostack;
262 addCommandLineProperties(properties);
263 return ostack;
264 }
266 /* java.lang.VMClass */
268 #define GET_CLASS(vmClass) (Class*)vmClass
270 uintptr_t *isInstance(Class *class, MethodBlock *mb, uintptr_t *ostack) {
271 Class *clazz = GET_CLASS(ostack[0]);
272 Object *ob = (Object*)ostack[1];
274 *ostack++ = ob == NULL ? FALSE : (uintptr_t)isInstanceOf(clazz, ob->class);
275 return ostack;
276 }
278 uintptr_t *isAssignableFrom(Class *class, MethodBlock *mb, uintptr_t *ostack) {
279 Class *clazz = GET_CLASS(ostack[0]);
280 Class *clazz2 = (Class*)ostack[1];
282 if(clazz2 == NULL)
283 signalException(java_lang_NullPointerException, NULL);
284 else
285 *ostack++ = (uintptr_t)isInstanceOf(clazz, clazz2);
287 return ostack;
288 }
290 uintptr_t *isInterface(Class *class, MethodBlock *mb, uintptr_t *ostack) {
291 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
292 *ostack++ = IS_INTERFACE(cb) ? TRUE : FALSE;
293 return ostack;
294 }
296 uintptr_t *isPrimitive(Class *class, MethodBlock *mb, uintptr_t *ostack) {
297 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
298 *ostack++ = IS_PRIMITIVE(cb) ? TRUE : FALSE;
299 return ostack;
300 }
302 uintptr_t *isArray(Class *class, MethodBlock *mb, uintptr_t *ostack) {
303 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
304 *ostack++ = IS_ARRAY(cb) ? TRUE : FALSE;
305 return ostack;
306 }
308 uintptr_t *isMember(Class *class, MethodBlock *mb, uintptr_t *ostack) {
309 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
310 *ostack++ = IS_MEMBER(cb) ? TRUE : FALSE;
311 return ostack;
312 }
314 uintptr_t *isLocal(Class *class, MethodBlock *mb, uintptr_t *ostack) {
315 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
316 *ostack++ = IS_LOCAL(cb) ? TRUE : FALSE;
317 return ostack;
318 }
320 uintptr_t *isAnonymous(Class *class, MethodBlock *mb, uintptr_t *ostack) {
321 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
322 *ostack++ = IS_ANONYMOUS(cb) ? TRUE : FALSE;
323 return ostack;
324 }
326 uintptr_t *getEnclosingClass0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
327 Class *clazz = GET_CLASS(ostack[0]);
328 *ostack++ = (uintptr_t) getEnclosingClass(clazz);
329 return ostack;
330 }
332 uintptr_t *getEnclosingMethod0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
333 Class *clazz = GET_CLASS(ostack[0]);
334 *ostack++ = (uintptr_t) getEnclosingMethodObject(clazz);
335 return ostack;
336 }
338 uintptr_t *getEnclosingConstructor(Class *class, MethodBlock *mb, uintptr_t *ostack) {
339 Class *clazz = GET_CLASS(ostack[0]);
340 *ostack++ = (uintptr_t) getEnclosingConstructorObject(clazz);
341 return ostack;
342 }
344 uintptr_t *getClassSignature(Class *class, MethodBlock *mb, uintptr_t *ostack) {
345 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
346 Object *string = NULL;
348 if(cb->signature != NULL) {
349 char *dot_name = slash2dots(cb->signature);
350 string = createString(dot_name);
351 sysFree(dot_name);
352 }
354 *ostack++ = (uintptr_t)string;
355 return ostack;
356 }
358 uintptr_t *getSuperclass(Class *class, MethodBlock *mb, uintptr_t *ostack) {
359 ClassBlock *cb = CLASS_CB(GET_CLASS(ostack[0]));
360 *ostack++ = (uintptr_t) (IS_PRIMITIVE(cb) || IS_INTERFACE(cb) ? NULL : cb->super);
361 return ostack;
362 }
364 uintptr_t *getComponentType(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
365 Class *class = GET_CLASS(ostack[0]);
366 ClassBlock *cb = CLASS_CB(class);
367 Class *componentType = NULL;
369 if(IS_ARRAY(cb))
370 switch(cb->name[1]) {
371 case '[':
372 componentType = findArrayClassFromClass(&cb->name[1], class);
373 break;
375 default:
376 componentType = cb->element_class;
377 break;
378 }
380 *ostack++ = (uintptr_t) componentType;
381 return ostack;
382 }
384 uintptr_t *getName(Class *class, MethodBlock *mb, uintptr_t *ostack) {
385 char *dot_name = slash2dots(CLASS_CB((GET_CLASS(*ostack)))->name);
386 Object *string = createString(dot_name);
387 *ostack++ = (uintptr_t)string;
388 sysFree(dot_name);
389 return ostack;
390 }
392 uintptr_t *getDeclaredClasses(Class *class, MethodBlock *mb, uintptr_t *ostack) {
393 Class *clazz = GET_CLASS(ostack[0]);
394 int public = ostack[1];
395 *ostack++ = (uintptr_t) getClassClasses(clazz, public);
396 return ostack;
397 }
399 uintptr_t *getDeclaringClass0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
400 Class *clazz = GET_CLASS(ostack[0]);
401 *ostack++ = (uintptr_t) getDeclaringClass(clazz);
402 return ostack;
403 }
405 uintptr_t *getDeclaredConstructors(Class *class, MethodBlock *mb, uintptr_t *ostack) {
406 Class *clazz = GET_CLASS(ostack[0]);
407 int public = ostack[1];
408 *ostack++ = (uintptr_t) getClassConstructors(clazz, public);
409 return ostack;
410 }
412 uintptr_t *getDeclaredMethods(Class *class, MethodBlock *mb, uintptr_t *ostack) {
413 Class *clazz = GET_CLASS(ostack[0]);
414 int public = ostack[1];
415 *ostack++ = (uintptr_t) getClassMethods(clazz, public);
416 return ostack;
417 }
419 uintptr_t *getDeclaredFields(Class *class, MethodBlock *mb, uintptr_t *ostack) {
420 Class *clazz = GET_CLASS(ostack[0]);
421 int public = ostack[1];
422 *ostack++ = (uintptr_t) getClassFields(clazz, public);
423 return ostack;
424 }
426 uintptr_t *getClassDeclaredAnnotations(Class *class, MethodBlock *mb, uintptr_t *ostack) {
427 Class *clazz = GET_CLASS(ostack[0]);
428 *ostack++ = (uintptr_t) getClassAnnotations(clazz);
429 return ostack;
430 }
432 uintptr_t *getInterfaces(Class *class, MethodBlock *mb, uintptr_t *ostack) {
433 Class *clazz = GET_CLASS(ostack[0]);
434 *ostack++ = (uintptr_t) getClassInterfaces(clazz);
435 return ostack;
436 }
438 uintptr_t *getClassLoader(Class *class, MethodBlock *mb, uintptr_t *ostack) {
439 Class *clazz = GET_CLASS(*ostack);
440 *ostack++ = (uintptr_t)CLASS_CB(clazz)->class_loader;
441 return ostack;
442 }
444 uintptr_t *getClassModifiers(Class *class, MethodBlock *mb, uintptr_t *ostack) {
445 Class *clazz = GET_CLASS(ostack[0]);
446 int ignore_inner_attrs = ostack[1];
447 ClassBlock *cb = CLASS_CB(clazz);
449 if(!ignore_inner_attrs && cb->declaring_class)
450 *ostack++ = (uintptr_t)cb->inner_access_flags;
451 else
452 *ostack++ = (uintptr_t)cb->access_flags;
454 return ostack;
455 }
457 uintptr_t *forName0(uintptr_t *ostack, int resolve, Object *loader) {
458 Object *string = (Object *)ostack[0];
459 Class *class = NULL;
460 int len, i = 0;
461 char *cstr;
463 if(string == NULL) {
464 signalException(java_lang_NullPointerException, NULL);
465 return ostack;
466 }
468 cstr = String2Utf8(string);
469 len = strlen(cstr);
471 /* Check the classname to see if it's valid. It can be
472 a 'normal' class or an array class, starting with a [ */
474 if(cstr[0] == '[') {
475 for(; cstr[i] == '['; i++);
476 switch(cstr[i]) {
477 case 'Z':
478 case 'B':
479 case 'C':
480 case 'S':
481 case 'I':
482 case 'F':
483 case 'J':
484 case 'D':
485 if(len-i != 1)
486 goto out;
487 break;
488 case 'L':
489 if(cstr[i+1] == '[' || cstr[len-1] != ';')
490 goto out;
491 break;
492 default:
493 goto out;
494 break;
495 }
496 }
498 /* Scan the classname and convert it to internal form
499 by converting dots to slashes. Reject classnames
500 containing slashes, as this is an invalid character */
502 for(; i < len; i++) {
503 if(cstr[i] == '/')
504 goto out;
505 if(cstr[i] == '.')
506 cstr[i] = '/';
507 }
509 class = findClassFromClassLoader(cstr, loader);
511 out:
512 if(class == NULL) {
513 Object *e = exceptionOccurred();
514 clearException();
515 signalChainedException(java_lang_ClassNotFoundException, cstr, e);
516 } else
517 if(resolve)
518 initClass(class);
520 sysFree(cstr);
521 *ostack++ = (uintptr_t)class;
522 return ostack;
523 }
525 uintptr_t *forName(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
526 int init = ostack[1];
527 Object *loader = (Object*)ostack[2];
528 return forName0(ostack, init, loader);
529 }
531 uintptr_t *throwException(Class *class, MethodBlock *mb, uintptr_t *ostack) {
532 Object *excep = (Object *)ostack[0];
533 setException(excep);
534 return ostack;
535 }
537 uintptr_t *hasClassInitializer(Class *class, MethodBlock *mb, uintptr_t *ostack) {
538 Class *clazz = (Class*)ostack[0];
539 *ostack++ = findMethod(clazz, SYMBOL(class_init),
540 SYMBOL(___V)) == NULL ? FALSE : TRUE;
541 return ostack;
542 }
544 /* java.lang.VMThrowable */
546 uintptr_t *fillInStackTrace(Class *class, MethodBlock *mb, uintptr_t *ostack) {
547 *ostack++ = (uintptr_t) setStackTrace();
548 return ostack;
549 }
551 uintptr_t *getStackTrace(Class *class, MethodBlock *m, uintptr_t *ostack) {
552 Object *this = (Object *)*ostack;
553 *ostack++ = (uintptr_t) convertStackTrace(this);
554 return ostack;
555 }
557 /* gnu.classpath.VMStackWalker */
559 uintptr_t *getCallingClass(Class *class, MethodBlock *mb, uintptr_t *ostack) {
560 *ostack++ = (uintptr_t) getCallerCallerClass();
561 return ostack;
562 }
564 uintptr_t *getCallingClassLoader(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
565 Class *class = getCallerCallerClass();
567 *ostack++ = (uintptr_t) (class ? CLASS_CB(class)->class_loader : NULL);
568 return ostack;
569 }
571 uintptr_t *getClassContext(Class *class, MethodBlock *mb, uintptr_t *ostack) {
572 Class *class_class = findArrayClass("[Ljava/lang/Class;");
573 Object *array;
574 Frame *last;
576 if(class_class == NULL)
577 return ostack;
579 if((last = getCallerFrame(getExecEnv()->last_frame)) == NULL)
580 array = allocArray(class_class, 0, sizeof(Class*));
581 else {
582 Frame *bottom = last;
583 int depth = 0;
585 do {
586 for(; last->mb != NULL; last = last->prev, depth++);
587 } while((last = last->prev)->prev != NULL);
589 array = allocArray(class_class, depth, sizeof(Class*));
591 if(array != NULL) {
592 Class **data = ARRAY_DATA(array);
594 do {
595 for(; bottom->mb != NULL; bottom = bottom->prev)
596 *data++ = bottom->mb->class;
597 } while((bottom = bottom->prev)->prev != NULL);
598 }
599 }
601 *ostack++ = (uintptr_t)array;
602 return ostack;
603 }
605 uintptr_t *firstNonNullClassLoader(Class *class, MethodBlock *mb, uintptr_t *ostack) {
606 Frame *last = getExecEnv()->last_frame;
607 Object *loader = NULL;
609 do {
610 for(; last->mb != NULL; last = last->prev)
611 if((loader = CLASS_CB(last->mb->class)->class_loader) != NULL)
612 goto out;
613 } while((last = last->prev)->prev != NULL);
615 out:
616 *ostack++ = (uintptr_t)loader;
617 return ostack;
618 }
620 /* java.lang.VMClassLoader */
622 /* loadClass(Ljava/lang/String;I)Ljava/lang/Class; */
623 uintptr_t *loadClass(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
624 int resolve = ostack[1];
625 return forName0(ostack, resolve, NULL);
626 }
628 /* getPrimitiveClass(C)Ljava/lang/Class; */
629 uintptr_t *getPrimitiveClass(Class *class, MethodBlock *mb, uintptr_t *ostack) {
630 char prim_type = *ostack;
631 *ostack++ = (uintptr_t)findPrimitiveClass(prim_type);
632 return ostack;
633 }
635 uintptr_t *defineClass0(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
636 Object *class_loader = (Object *)ostack[0];
637 Object *string = (Object *)ostack[1];
638 Object *array = (Object *)ostack[2];
639 int offset = ostack[3];
640 int data_len = ostack[4];
641 uintptr_t pd = ostack[5];
642 Class *class = NULL;
644 if(array == NULL)
645 signalException(java_lang_NullPointerException, NULL);
646 else
647 if((offset < 0) || (data_len < 0) ||
648 ((offset + data_len) > ARRAY_LEN(array)))
649 signalException(java_lang_ArrayIndexOutOfBoundsException, NULL);
650 else {
651 char *data = ARRAY_DATA(array);
652 char *cstr = string ? String2Utf8(string) : NULL;
653 int len = string ? strlen(cstr) : 0;
654 int i;
656 for(i = 0; i < len; i++)
657 if(cstr[i]=='.') cstr[i]='/';
659 if((class = defineClass(cstr, data, offset, data_len, class_loader)) != NULL) {
660 INST_DATA(class)[pd_offset] = pd;
661 linkClass(class);
662 }
664 sysFree(cstr);
665 }
667 *ostack++ = (uintptr_t) class;
668 return ostack;
669 }
671 uintptr_t *findLoadedClass(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
672 Object *class_loader = (Object *)ostack[0];
673 Object *string = (Object *)ostack[1];
674 Class *class;
675 char *cstr;
676 int len, i;
678 if(string == NULL) {
679 signalException(java_lang_NullPointerException, NULL);
680 return ostack;
681 }
683 cstr = String2Cstr(string);
684 len = strlen(cstr);
686 for(i = 0; i < len; i++)
687 if(cstr[i]=='.') cstr[i]='/';
689 class = findHashedClass(cstr, class_loader);
691 sysFree(cstr);
692 *ostack++ = (uintptr_t) class;
693 return ostack;
694 }
696 uintptr_t *resolveClass0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
697 Class *clazz = (Class *)*ostack;
699 if(clazz == NULL)
700 signalException(java_lang_NullPointerException, NULL);
701 else
702 initClass(clazz);
704 return ostack;
705 }
707 uintptr_t *getBootClassPathSize(Class *class, MethodBlock *mb, uintptr_t *ostack) {
708 *ostack++ = bootClassPathSize();
709 return ostack;
710 }
712 uintptr_t *getBootClassPathResource(Class *class, MethodBlock *mb, uintptr_t *ostack) {
713 Object *string = (Object *) ostack[0];
714 char *filename = String2Cstr(string);
715 int index = ostack[1];
717 *ostack++ = (uintptr_t) bootClassPathResource(filename, index);
718 return ostack;
719 }
721 /* java.lang.reflect.Constructor */
723 uintptr_t *constructNative(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
724 Object *array = (Object*)ostack[1];
725 Class *decl_class = (Class*)ostack[2];
726 Object *param_types = (Object*)ostack[3];
727 ClassBlock *cb = CLASS_CB(decl_class);
728 MethodBlock *mb = &(cb->methods[ostack[4]]);
729 int no_access_check = ostack[5];
730 Object *ob;
732 if(cb->access_flags & ACC_ABSTRACT) {
733 signalException(java_lang_InstantiationError, cb->name);
734 return ostack;
735 }
737 /* Creating an instance of the class is an
738 active use; make sure it is initialised */
739 if(initClass(decl_class) == NULL)
740 return ostack;
742 if((ob = allocObject(decl_class)) != NULL) {
743 invoke(ob, mb, array, param_types, !no_access_check);
744 *ostack++ = (uintptr_t) ob;
745 }
747 return ostack;
748 }
750 uintptr_t *getMethodModifiers(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
751 Class *decl_class = (Class*)ostack[1];
752 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
753 *ostack++ = (uintptr_t) mb->access_flags;
754 return ostack;
755 }
757 uintptr_t *getMethodSignature(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
758 Class *decl_class = (Class*)ostack[1];
759 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
760 Object *string = NULL;
762 if(mb->signature != NULL) {
763 char *dot_name = slash2dots(mb->signature);
764 string = createString(dot_name);
765 sysFree(dot_name);
766 }
768 *ostack++ = (uintptr_t)string;
769 return ostack;
770 }
772 uintptr_t *getDefaultValue(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
773 Class *decl_class = (Class*)ostack[1];
774 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
775 *ostack++ = (uintptr_t)getMethodDefaultValue(mb);
776 return ostack;
777 }
779 uintptr_t *getMethodDeclaredAnnotations(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
780 Class *decl_class = (Class*)ostack[1];
781 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
782 *ostack++ = (uintptr_t)getMethodAnnotations(mb);
783 return ostack;
784 }
786 uintptr_t *getParameterAnnotations(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
787 Class *decl_class = (Class*)ostack[1];
788 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
789 *ostack++ = (uintptr_t)getMethodParameterAnnotations(mb);
790 return ostack;
791 }
793 uintptr_t *getFieldModifiers(Class *class, MethodBlock *mb, uintptr_t *ostack) {
794 Class *decl_class = (Class*)ostack[1];
795 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
796 *ostack++ = (uintptr_t) fb->access_flags;
797 return ostack;
798 }
800 uintptr_t *getFieldSignature(Class *class, MethodBlock *mb, uintptr_t *ostack) {
801 Class *decl_class = (Class*)ostack[1];
802 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
803 Object *string = NULL;
805 if(fb->signature != NULL) {
806 char *dot_name = slash2dots(fb->signature);
807 string = createString(dot_name);
808 sysFree(dot_name);
809 }
811 *ostack++ = (uintptr_t)string;
812 return ostack;
813 }
815 uintptr_t *getFieldDeclaredAnnotations(Class *class, MethodBlock *mb, uintptr_t *ostack) {
816 Class *decl_class = (Class*)ostack[1];
817 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
818 *ostack++ = (uintptr_t)getFieldAnnotations(fb);
819 return ostack;
820 }
822 Object *getAndCheckObject(uintptr_t *ostack, Class *type) {
823 Object *ob = (Object*)ostack[1];
825 if(ob == NULL) {
826 signalException(java_lang_NullPointerException, NULL);
827 return NULL;
828 }
830 if(!isInstanceOf(type, ob->class)) {
831 signalException(java_lang_IllegalArgumentException,
832 "object is not an instance of declaring class");
833 return NULL;
834 }
836 return ob;
837 }
839 uintptr_t *getPntr2Field(uintptr_t *ostack) {
840 Class *decl_class = (Class *)ostack[2];
841 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[4]]);
842 int no_access_check = ostack[5];
843 Object *ob;
845 if(!no_access_check) {
846 Class *caller = getCallerCallerClass();
847 if(!checkClassAccess(decl_class, caller) || !checkFieldAccess(fb, caller)) {
848 signalException(java_lang_IllegalAccessException, "field is not accessible");
849 return NULL;
850 }
851 }
853 if(fb->access_flags & ACC_STATIC) {
854 /* Setting/getting a static field of a class is an
855 active use; make sure it is initialised */
856 if(initClass(decl_class) == NULL)
857 return NULL;
858 return &fb->static_value;
859 }
861 if((ob = getAndCheckObject(ostack, decl_class)) == NULL)
862 return NULL;
864 return &(INST_DATA(ob)[fb->offset]);
865 }
867 uintptr_t *getField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
868 Class *field_type = (Class *)ostack[3];
869 uintptr_t *field;
871 /* If field is static, getPntr2Field also initialises the field's declaring class */
872 if((field = getPntr2Field(ostack)) != NULL)
873 *ostack++ = (uintptr_t) getReflectReturnObject(field_type, field);
875 return ostack;
876 }
878 uintptr_t *getPrimitiveField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
879 Class *field_type = (Class *)ostack[3];
880 int type_no = ostack[6];
882 ClassBlock *type_cb = CLASS_CB(field_type);
883 uintptr_t *field;
885 /* If field is static, getPntr2Field also initialises the field's declaring class */
886 if(((field = getPntr2Field(ostack)) != NULL) && (!(IS_PRIMITIVE(type_cb)) ||
887 ((ostack = widenPrimitiveValue(getPrimTypeIndex(type_cb), type_no, field, ostack)) == NULL)))
888 signalException(java_lang_IllegalArgumentException, "field type mismatch");
890 return ostack;
891 }
893 uintptr_t *setField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
894 Class *field_type = (Class *)ostack[3];
895 Object *value = (Object*)ostack[6];
896 uintptr_t *field;
898 /* If field is static, getPntr2Field also initialises the field's declaring class */
899 if(((field = getPntr2Field(ostack)) != NULL) &&
900 (unwrapAndWidenObject(field_type, value, field) == NULL))
901 signalException(java_lang_IllegalArgumentException, "field type mismatch");
903 return ostack;
904 }
906 uintptr_t *setPrimitiveField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
907 Class *field_type = (Class *)ostack[3];
908 int type_no = ostack[6];
910 ClassBlock *type_cb = CLASS_CB(field_type);
911 uintptr_t *field;
913 /* If field is static, getPntr2Field also initialises the field's declaring class */
914 if(((field = getPntr2Field(ostack)) != NULL) && (!(IS_PRIMITIVE(type_cb)) ||
915 (widenPrimitiveValue(type_no, getPrimTypeIndex(type_cb), &ostack[7], field) == NULL)))
916 signalException(java_lang_IllegalArgumentException, "field type mismatch");
918 return ostack;
919 }
921 /* java.lang.reflect.Method */
923 uintptr_t *invokeNative(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
924 Object *array = (Object*)ostack[2];
925 Class *decl_class = (Class*)ostack[3];
926 Object *param_types = (Object*)ostack[4];
927 Class *ret_type = (Class*)ostack[5];
928 ClassBlock *cb = CLASS_CB(decl_class);
929 MethodBlock *mb = &(cb->methods[ostack[6]]);
930 int no_access_check = ostack[7];
931 Object *ob = NULL;
932 uintptr_t *ret;
934 /* If it's a static method, class may not be initialised;
935 interfaces are also not normally initialised. */
936 if((mb->access_flags & ACC_STATIC) || IS_INTERFACE(cb))
937 if(initClass(decl_class) == NULL)
938 return ostack;
940 if(!(mb->access_flags & ACC_STATIC))
941 if(((ob = getAndCheckObject(ostack, decl_class)) == NULL) ||
942 ((mb = lookupVirtualMethod(ob, mb)) == NULL))
943 return ostack;
945 if((ret = (uintptr_t*) invoke(ob, mb, array, param_types, !no_access_check)) != NULL)
946 *ostack++ = (uintptr_t) getReflectReturnObject(ret_type, ret);
948 return ostack;
949 }
951 /* java.lang.VMString */
953 /* static method - intern(Ljava/lang/String;)Ljava/lang/String; */
954 uintptr_t *intern(Class *class, MethodBlock *mb, uintptr_t *ostack) {
955 Object *string = (Object*)ostack[0];
956 ostack[0] = (uintptr_t)findInternedString(string);
957 return ostack+1;
958 }
960 /* java.lang.VMThread */
962 /* static method currentThread()Ljava/lang/Thread; */
963 uintptr_t *currentThread(Class *class, MethodBlock *mb, uintptr_t *ostack) {
964 *ostack++ = (uintptr_t)getExecEnv()->thread;
965 return ostack;
966 }
968 /* static method create(Ljava/lang/Thread;J)V */
969 uintptr_t *create(Class *class, MethodBlock *mb, uintptr_t *ostack) {
970 Object *this = (Object *)ostack[0];
971 long long stack_size = *((long long*)&ostack[1]);
972 createJavaThread(this, stack_size);
973 return ostack;
974 }
976 /* static method sleep(JI)V */
977 uintptr_t *jamSleep(Class *class, MethodBlock *mb, uintptr_t *ostack) {
978 long long ms = *((long long *)&ostack[0]);
979 int ns = ostack[2];
980 Thread *thread = threadSelf();
982 threadSleep(thread, ms, ns);
983 return ostack;
984 }
986 /* instance method interrupt()V */
987 uintptr_t *interrupt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
988 Object *this = (Object *)*ostack;
989 Thread *thread = threadSelf0(this);
990 if(thread)
991 threadInterrupt(thread);
992 return ostack;
993 }
995 /* instance method isAlive()Z */
996 uintptr_t *isAlive(Class *class, MethodBlock *mb, uintptr_t *ostack) {
997 Object *this = (Object *)*ostack;
998 Thread *thread = threadSelf0(this);
999 *ostack++ = thread ? threadIsAlive(thread) : FALSE;
1000 return ostack;
1003 /* static method yield()V */
1004 uintptr_t *yield(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1005 Thread *thread = threadSelf();
1006 threadYield(thread);
1007 return ostack;
1010 /* instance method isInterrupted()Z */
1011 uintptr_t *isInterrupted(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1012 Object *this = (Object *)*ostack;
1013 Thread *thread = threadSelf0(this);
1014 *ostack++ = thread ? threadIsInterrupted(thread) : FALSE;
1015 return ostack;
1018 /* static method interrupted()Z */
1019 uintptr_t *interrupted(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1020 Thread *thread = threadSelf();
1021 *ostack++ = threadInterrupted(thread);
1022 return ostack;
1025 /* instance method nativeSetPriority(I)V */
1026 uintptr_t *nativeSetPriority(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1027 return ostack+1;
1030 /* instance method holdsLock(Ljava/lang/Object;)Z */
1031 uintptr_t *holdsLock(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1032 Object *ob = (Object *)ostack[0];
1033 if(ob == NULL)
1034 signalException(java_lang_NullPointerException, NULL);
1035 else
1036 *ostack++ = objectLockedByCurrent(ob);
1037 return ostack;
1040 /* instance method getState()Ljava/lang/String; */
1041 uintptr_t *getState(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1042 Object *this = (Object *)*ostack;
1043 Thread *thread = threadSelf0(this);
1044 char *state = thread ? getThreadStateString(thread) : "TERMINATED";
1046 *ostack++ = (uintptr_t)Cstr2String(state);
1047 return ostack;
1050 /* java.security.VMAccessController */
1052 /* instance method getStack()[[Ljava/lang/Object; */
1053 uintptr_t *getStack(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1054 Class *object_class = findArrayClass("[[Ljava/lang/Object;");
1055 Class *class_class = findArrayClass("[Ljava/lang/Class;");
1056 Class *string_class = findArrayClass("[Ljava/lang/String;");
1057 Object *stack, *names, *classes;
1058 Frame *frame;
1059 int depth;
1061 if(object_class == NULL || class_class == NULL || string_class == NULL)
1062 return ostack;
1064 frame = getExecEnv()->last_frame;
1065 depth = 0;
1067 do {
1068 for(; frame->mb != NULL; frame = frame->prev, depth++);
1069 } while((frame = frame->prev)->prev != NULL);
1071 stack = allocArray(object_class, 2, sizeof(Object*));
1072 classes = allocArray(class_class, depth, sizeof(Object*));
1073 names = allocArray(string_class, depth, sizeof(Object*));
1075 if(stack != NULL && names != NULL && classes != NULL) {
1076 Class **dcl = ARRAY_DATA(classes);
1077 Object **dnm = ARRAY_DATA(names);
1078 Object **stk = ARRAY_DATA(stack);
1080 frame = getExecEnv()->last_frame;
1082 do {
1083 for(; frame->mb != NULL; frame = frame->prev) {
1084 *dcl++ = frame->mb->class;
1085 *dnm++ = createString(frame->mb->name);
1087 } while((frame = frame->prev)->prev != NULL);
1089 stk[0] = classes;
1090 stk[1] = names;
1093 *ostack++ = (uintptr_t) stack;
1094 return ostack;
1097 uintptr_t *getThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1098 *ostack++ = getThreadsCount();
1099 return ostack;
1102 uintptr_t *getPeakThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1103 *ostack++ = getPeakThreadsCount();
1104 return ostack;
1107 uintptr_t *getTotalStartedThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1108 *(u8*)ostack = getTotalStartedThreadsCount();
1109 return ostack + 2;
1112 uintptr_t *resetPeakThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1113 resetPeakThreadsCount();
1114 return ostack;
1117 uintptr_t *findMonitorDeadlockedThreads(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1118 *ostack++ = (uintptr_t)NULL;
1119 return ostack;
1122 uintptr_t *getThreadInfoForId(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1123 long long id = *((long long *)&ostack[0]);
1124 int max_depth = ostack[2];
1126 Thread *thread = findThreadById(id);
1127 Object *info = NULL;
1129 if(thread != NULL) {
1130 Class *info_class = findSystemClass("java/lang/management/ThreadInfo");
1132 if(info_class != NULL) {
1133 MethodBlock *init = findMethod(info_class, SYMBOL(object_init),
1134 newUtf8("(Ljava/lang/Thread;JJLjava/lang/Object;"
1135 "Ljava/lang/Thread;JJZZ[Ljava/lang/StackTraceElement;)V"));
1136 if(init != NULL) {
1137 Frame *last;
1138 int in_native;
1139 Object *vmthrowable;
1140 int self = thread == threadSelf();
1142 if(!self)
1143 suspendThread(thread);
1145 vmthrowable = setStackTrace0(thread->ee, max_depth);
1147 last = thread->ee->last_frame;
1148 in_native = last->prev == NULL || last->mb->access_flags & ACC_NATIVE;
1150 if(!self)
1151 resumeThread(thread);
1153 if(vmthrowable != NULL) {
1154 Object *trace;
1155 if((info = allocObject(info_class)) != NULL &&
1156 (trace = convertStackTrace(vmthrowable)) != NULL) {
1158 Monitor *mon = thread->blocked_mon;
1159 Object *lock = mon != NULL ? mon->obj : NULL;
1160 Thread *owner = mon != NULL ? mon->owner : NULL;
1161 Object *lock_owner = owner != NULL ? owner->ee->thread : NULL;
1163 executeMethod(info, init, thread->ee->thread, thread->blocked_count, 0LL, lock,
1164 lock_owner, thread->waited_count, 0LL, in_native, FALSE, trace);
1171 *ostack++ = (uintptr_t)info;
1172 return ostack;
1175 /* sun.misc.Unsafe */
1177 static volatile uintptr_t spinlock = 0;
1179 void lockSpinLock() {
1180 while(!LOCKWORD_COMPARE_AND_SWAP(&spinlock, 0, 1));
1183 void unlockSpinLock() {
1184 LOCKWORD_WRITE(&spinlock, 0);
1187 uintptr_t *objectFieldOffset(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1188 FieldBlock *fb = fbFromReflectObject((Object*)ostack[1]);
1190 *(long long*)ostack = (long long)(uintptr_t)&INST_DATA((Object*)NULL)[fb->offset];
1191 return ostack + 2;
1194 uintptr_t *compareAndSwapInt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1195 long long offset = *((long long *)&ostack[2]);
1196 uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1197 uintptr_t expect = ostack[4];
1198 uintptr_t update = ostack[5];
1199 int result;
1201 #ifdef COMPARE_AND_SWAP
1202 result = COMPARE_AND_SWAP(addr, expect, update);
1203 #else
1204 lockSpinLock();
1205 if((result = (*addr == expect)))
1206 *addr = update;
1207 unlockSpinLock();
1208 #endif
1210 *ostack++ = result;
1211 return ostack;
1214 uintptr_t *compareAndSwapLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1215 long long offset = *((long long *)&ostack[2]);
1216 long long *addr = (long long*)((char*)ostack[1] + offset);
1217 long long expect = *((long long *)&ostack[4]);
1218 long long update = *((long long *)&ostack[6]);
1219 int result;
1221 #ifdef COMPARE_AND_SWAP_64
1222 result = COMPARE_AND_SWAP_64(addr, expect, update);
1223 #else
1224 lockSpinLock();
1225 if((result = (*addr == expect)))
1226 *addr = update;
1227 unlockSpinLock();
1228 #endif
1230 *ostack++ = result;
1231 return ostack;
1234 uintptr_t *putOrderedInt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1235 long long offset = *((long long *)&ostack[2]);
1236 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1237 uintptr_t value = ostack[4];
1239 *addr = value;
1240 return ostack;
1243 uintptr_t *putOrderedLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1244 long long offset = *((long long *)&ostack[2]);
1245 long long value = *((long long *)&ostack[4]);
1246 volatile long long *addr = (long long*)((char*)ostack[1] + offset);
1248 if(sizeof(uintptr_t) == 8)
1249 *addr = value;
1250 else {
1251 lockSpinLock();
1252 *addr = value;
1253 unlockSpinLock();
1256 return ostack;
1259 uintptr_t *putIntVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1260 long long offset = *((long long *)&ostack[2]);
1261 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1262 uintptr_t value = ostack[4];
1264 MBARRIER();
1265 *addr = value;
1267 return ostack;
1270 uintptr_t *getIntVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1271 long long offset = *((long long *)&ostack[2]);
1272 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1274 *ostack++ = *addr;
1275 MBARRIER();
1277 return ostack;
1280 uintptr_t *putLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1281 long long offset = *((long long *)&ostack[2]);
1282 long long value = *((long long *)&ostack[4]);
1283 long long *addr = (long long*)((char*)ostack[1] + offset);
1285 if(sizeof(uintptr_t) == 8)
1286 *addr = value;
1287 else {
1288 lockSpinLock();
1289 *addr = value;
1290 unlockSpinLock();
1293 return ostack;
1296 uintptr_t *getLongVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1297 long long offset = *((long long *)&ostack[2]);
1298 volatile long long *addr = (long long*)((char*)ostack[1] + offset);
1300 if(sizeof(uintptr_t) == 8)
1301 *(long long*)ostack = *addr;
1302 else {
1303 lockSpinLock();
1304 *(long long*)ostack = *addr;
1305 unlockSpinLock();
1308 return ostack + 2;
1311 uintptr_t *getLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1312 long long offset = *((long long *)&ostack[2]);
1313 long long *addr = (long long*)((char*)ostack[1] + offset);
1315 if(sizeof(uintptr_t) == 8)
1316 *(long long*)ostack = *addr;
1317 else {
1318 lockSpinLock();
1319 *(long long*)ostack = *addr;
1320 unlockSpinLock();
1323 return ostack + 2;
1326 uintptr_t *putObject(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1327 long long offset = *((long long *)&ostack[2]);
1328 uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1329 uintptr_t value = ostack[4];
1331 *addr = value;
1332 return ostack;
1335 uintptr_t *arrayBaseOffset(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1336 *ostack++ = (uintptr_t) ARRAY_DATA((Object*)NULL);
1337 return ostack;
1340 uintptr_t *arrayIndexScale(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1341 Class *array_class = (Class*)ostack[1];
1342 ClassBlock *cb = CLASS_CB(array_class);
1343 int scale = 0;
1345 if(cb->name[0] == '[')
1346 switch(cb->name[1]) {
1347 case 'I':
1348 case 'F':
1349 scale = 4;
1350 break;
1352 case '[':
1353 case 'L':
1354 scale = sizeof(Object*);
1355 break;
1357 case 'J':
1358 case 'D':
1359 scale = 8;
1360 break;
1363 *ostack++ = scale;
1364 return ostack;
1367 uintptr_t *unpark(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1368 return ostack;
1371 uintptr_t *park(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1372 return ostack;
1375 uintptr_t *vmSupportsCS8(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1376 *ostack++ = FALSE;
1377 return ostack;
1380 /* jamvm.java.lang.VMClassLoaderData */
1382 uintptr_t *nativeUnloadDll(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1383 unloaderUnloadDll((uintptr_t)*(long long*)&ostack[1]);
1384 return ostack;
1387 VMMethod vm_object[] = {
1388 {"getClass", getClass},
1389 {"clone", jamClone},
1390 {"wait", jamWait},
1391 {"notify", notify},
1392 {"notifyAll", notifyAll},
1393 {NULL, NULL}
1394 };
1396 VMMethod vm_system[] = {
1397 {"arraycopy", arraycopy},
1398 {"identityHashCode", identityHashCode},
1399 {NULL, NULL}
1400 };
1402 VMMethod vm_runtime[] = {
1403 {"availableProcessors", availableProcessors},
1404 {"freeMemory", freeMemory},
1405 {"totalMemory", totalMemory},
1406 {"maxMemory", maxMemory},
1407 {"gc", gc},
1408 {"runFinalization", runFinalization},
1409 {"exit", exitInternal},
1410 {"nativeLoad", nativeLoad},
1411 {"mapLibraryName", mapLibraryName},
1412 {NULL, NULL}
1413 };
1415 VMMethod vm_class[] = {
1416 {"isInstance", isInstance},
1417 {"isAssignableFrom", isAssignableFrom},
1418 {"isInterface", isInterface},
1419 {"isPrimitive", isPrimitive},
1420 {"isArray", isArray},
1421 {"isMemberClass", isMember},
1422 {"isLocalClass", isLocal},
1423 {"isAnonymousClass", isAnonymous},
1424 {"getEnclosingClass", getEnclosingClass0},
1425 {"getEnclosingMethod", getEnclosingMethod0},
1426 {"getEnclosingConstructor", getEnclosingConstructor},
1427 {"getClassSignature", getClassSignature},
1428 {"getSuperclass", getSuperclass},
1429 {"getComponentType", getComponentType},
1430 {"getName", getName},
1431 {"getDeclaredClasses", getDeclaredClasses},
1432 {"getDeclaringClass", getDeclaringClass0},
1433 {"getDeclaredConstructors", getDeclaredConstructors},
1434 {"getDeclaredMethods", getDeclaredMethods},
1435 {"getDeclaredFields", getDeclaredFields},
1436 {"getInterfaces", getInterfaces},
1437 {"getClassLoader", getClassLoader},
1438 {"getModifiers", getClassModifiers},
1439 {"forName", forName},
1440 {"throwException", throwException},
1441 {"hasClassInitializer", hasClassInitializer},
1442 {"getDeclaredAnnotations", getClassDeclaredAnnotations},
1443 {NULL, NULL}
1444 };
1446 VMMethod vm_string[] = {
1447 {"intern", intern},
1448 {NULL, NULL}
1449 };
1451 VMMethod vm_thread[] = {
1452 {"currentThread", currentThread},
1453 {"create", create},
1454 {"sleep", jamSleep},
1455 {"interrupt", interrupt},
1456 {"isAlive", isAlive},
1457 {"yield", yield},
1458 {"isInterrupted", isInterrupted},
1459 {"interrupted", interrupted},
1460 {"nativeSetPriority", nativeSetPriority},
1461 {"holdsLock", holdsLock},
1462 {"getState", getState},
1463 {NULL, NULL}
1464 };
1466 VMMethod vm_throwable[] = {
1467 {"fillInStackTrace", fillInStackTrace},
1468 {"getStackTrace", getStackTrace},
1469 {NULL, NULL}
1470 };
1472 VMMethod vm_classloader[] = {
1473 {"loadClass", loadClass},
1474 {"getPrimitiveClass", getPrimitiveClass},
1475 {"defineClass", defineClass0},
1476 {"findLoadedClass", findLoadedClass},
1477 {"resolveClass", resolveClass0},
1478 {"getBootClassPathSize", getBootClassPathSize},
1479 {"getBootClassPathResource", getBootClassPathResource},
1480 {NULL, NULL}
1481 };
1483 VMMethod vm_reflect_constructor[] = {
1484 {"constructNative", constructNative},
1485 {"getConstructorModifiers", getMethodModifiers},
1486 {"getSignature", getMethodSignature},
1487 {"getDeclaredAnnotationsNative", getMethodDeclaredAnnotations},
1488 {"getParameterAnnotationsNative", getParameterAnnotations},
1489 {NULL, NULL}
1490 };
1492 VMMethod vm_reflect_method[] = {
1493 {"invokeNative", invokeNative},
1494 {"getMethodModifiers", getMethodModifiers},
1495 {"getSignature", getMethodSignature},
1496 {"getDefaultValueNative", getDefaultValue},
1497 {"getDeclaredAnnotationsNative", getMethodDeclaredAnnotations},
1498 {"getParameterAnnotationsNative", getParameterAnnotations},
1499 {NULL, NULL}
1500 };
1502 VMMethod vm_reflect_field[] = {
1503 {"getFieldModifiers", getFieldModifiers},
1504 {"getSignature", getFieldSignature},
1505 {"getDeclaredAnnotationsNative", getFieldDeclaredAnnotations},
1506 {"getField", getField},
1507 {"setField", setField},
1508 {"setZField", setPrimitiveField},
1509 {"setBField", setPrimitiveField},
1510 {"setCField", setPrimitiveField},
1511 {"setSField", setPrimitiveField},
1512 {"setIField", setPrimitiveField},
1513 {"setFField", setPrimitiveField},
1514 {"setJField", setPrimitiveField},
1515 {"setDField", setPrimitiveField},
1516 {"getZField", getPrimitiveField},
1517 {"getBField", getPrimitiveField},
1518 {"getCField", getPrimitiveField},
1519 {"getSField", getPrimitiveField},
1520 {"getIField", getPrimitiveField},
1521 {"getFField", getPrimitiveField},
1522 {"getJField", getPrimitiveField},
1523 {"getDField", getPrimitiveField},
1524 {NULL, NULL}
1525 };
1527 VMMethod vm_system_properties[] = {
1528 {"preInit", propertiesPreInit},
1529 {"postInit", propertiesPostInit},
1530 {NULL, NULL}
1531 };
1533 VMMethod vm_stack_walker[] = {
1534 {"getClassContext", getClassContext},
1535 {"getCallingClass", getCallingClass},
1536 {"getCallingClassLoader", getCallingClassLoader},
1537 {"firstNonNullClassLoader", firstNonNullClassLoader},
1538 {NULL, NULL}
1539 };
1541 VMMethod sun_misc_unsafe[] = {
1542 {"objectFieldOffset", objectFieldOffset},
1543 {"compareAndSwapInt", compareAndSwapInt},
1544 {"compareAndSwapLong", compareAndSwapLong},
1545 {"compareAndSwapObject", compareAndSwapInt},
1546 {"putOrderedInt", putOrderedInt},
1547 {"putOrderedLong", putOrderedLong},
1548 {"putOrderedObject", putOrderedInt},
1549 {"putIntVolatile", putIntVolatile},
1550 {"getIntVolatile", getIntVolatile},
1551 {"putLongVolatile", putOrderedLong},
1552 {"putLong", putLong},
1553 {"getLongVolatile", getLongVolatile},
1554 {"getLong", getLong},
1555 {"putObjectVolatile", putIntVolatile},
1556 {"putObject", putObject},
1557 {"getObjectVolatile", getIntVolatile},
1558 {"arrayBaseOffset", arrayBaseOffset},
1559 {"arrayIndexScale", arrayIndexScale},
1560 {"unpark", unpark},
1561 {"park", park},
1562 {NULL, NULL}
1563 };
1565 VMMethod vm_access_controller[] = {
1566 {"getStack", getStack},
1567 {NULL, NULL}
1568 };
1570 VMMethod vm_threadmx_bean_impl[] = {
1571 {"getThreadCount", getThreadCount},
1572 {"getPeakThreadCount", getPeakThreadCount},
1573 {"getTotalStartedThreadCount", getTotalStartedThreadCount},
1574 {"resetPeakThreadCount", resetPeakThreadCount},
1575 {"getThreadInfoForId", getThreadInfoForId},
1576 {"findMonitorDeadlockedThreads",findMonitorDeadlockedThreads},
1577 {NULL, NULL}
1578 };
1580 VMMethod concurrent_atomic_long[] = {
1581 {"VMSupportsCS8", vmSupportsCS8},
1582 {NULL, NULL}
1583 };
1585 VMMethod vm_class_loader_data[] = {
1586 {"nativeUnloadDll", nativeUnloadDll},
1587 {NULL, NULL}
1588 };
1590 VMClass native_methods[] = {
1591 {"java/lang/VMClass", vm_class},
1592 {"java/lang/VMObject", vm_object},
1593 {"java/lang/VMThread", vm_thread},
1594 {"java/lang/VMSystem", vm_system},
1595 {"java/lang/VMString", vm_string},
1596 {"java/lang/VMRuntime", vm_runtime},
1597 {"java/lang/VMThrowable", vm_throwable},
1598 {"java/lang/VMClassLoader", vm_classloader},
1599 {"java/lang/reflect/Field", vm_reflect_field},
1600 {"java/lang/reflect/Method", vm_reflect_method},
1601 {"java/lang/reflect/Constructor", vm_reflect_constructor},
1602 {"java/security/VMAccessController", vm_access_controller},
1603 {"gnu/classpath/VMSystemProperties", vm_system_properties},
1604 {"gnu/classpath/VMStackWalker", vm_stack_walker},
1605 {"gnu/java/lang/management/VMThreadMXBeanImpl", vm_threadmx_bean_impl},
1606 {"sun/misc/Unsafe", sun_misc_unsafe},
1607 {"jamvm/java/lang/VMClassLoaderData$Unloader", vm_class_loader_data},
1608 {"java/util/concurrent/atomic/AtomicLong", concurrent_atomic_long},
1609 {NULL, NULL}
1610 };