jamvm
view src/natives.c @ 403:907df5a02819
Fix storage of protection domain for OpenJDK.
2008-08-04 Andrew John Hughes <gnu_andrew@member.fsf.org>
* src/class.c,
* src/jam.h:
Change signature of defineClass to include
protection domain.
* src/jni.c: Fix call to defineClass to send
NULL protection domain as HotSpot does.
* src/natives.c: Send protection domain directly
to defineClass on OpenJDK as there is no field to
inject it into.
2008-08-04 Andrew John Hughes <gnu_andrew@member.fsf.org>
* src/class.c,
* src/jam.h:
Change signature of defineClass to include
protection domain.
* src/jni.c: Fix call to defineClass to send
NULL protection domain as HotSpot does.
* src/natives.c: Send protection domain directly
to defineClass on OpenJDK as there is no field to
inject it into.
| author | andrew |
|---|---|
| date | Tue Aug 05 06:03:08 2008 +0100 (2008-08-05) |
| parents | 24373fc1d951 |
| children | f70700d622a8 |
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 #ifdef WITH_JAVA_RUNTIME_LIBRARY_CLASSPATH
642 uintptr_t pd = ostack[5];
643 #elif WITH_JAVA_RUNTIME_LIBRARY_OPENJDK
644 Object* pd = ostack[5];
645 #endif
646 Class *class = NULL;
648 if(array == NULL)
649 signalException(java_lang_NullPointerException, NULL);
650 else
651 if((offset < 0) || (data_len < 0) ||
652 ((offset + data_len) > ARRAY_LEN(array)))
653 signalException(java_lang_ArrayIndexOutOfBoundsException, NULL);
654 else {
655 char *data = ARRAY_DATA(array);
656 char *cstr = string ? String2Utf8(string) : NULL;
657 int len = string ? strlen(cstr) : 0;
658 int i;
660 for(i = 0; i < len; i++)
661 if(cstr[i]=='.') cstr[i]='/';
663 #ifdef WITH_JAVA_RUNTIME_LIBRARY_CLASSPATH
664 if((class = defineClass(cstr, data, offset, data_len, class_loader, NULL)) != NULL) {
665 INST_DATA(class)[pd_offset] = pd;
666 #elif WITH_JAVA_RUNTIME_LIBRARY_OPENJDK
667 if((class = defineClass(cstr, data, offset, data_len, class_loader, pd)) != NULL) {
668 #endif
669 linkClass(class);
670 }
672 sysFree(cstr);
673 }
675 *ostack++ = (uintptr_t) class;
676 return ostack;
677 }
679 uintptr_t *findLoadedClass(Class *clazz, MethodBlock *mb, uintptr_t *ostack) {
680 Object *class_loader = (Object *)ostack[0];
681 Object *string = (Object *)ostack[1];
682 Class *class;
683 char *cstr;
684 int len, i;
686 if(string == NULL) {
687 signalException(java_lang_NullPointerException, NULL);
688 return ostack;
689 }
691 cstr = String2Cstr(string);
692 len = strlen(cstr);
694 for(i = 0; i < len; i++)
695 if(cstr[i]=='.') cstr[i]='/';
697 class = findHashedClass(cstr, class_loader);
699 sysFree(cstr);
700 *ostack++ = (uintptr_t) class;
701 return ostack;
702 }
704 uintptr_t *resolveClass0(Class *class, MethodBlock *mb, uintptr_t *ostack) {
705 Class *clazz = (Class *)*ostack;
707 if(clazz == NULL)
708 signalException(java_lang_NullPointerException, NULL);
709 else
710 initClass(clazz);
712 return ostack;
713 }
715 uintptr_t *getBootClassPathSize(Class *class, MethodBlock *mb, uintptr_t *ostack) {
716 *ostack++ = bootClassPathSize();
717 return ostack;
718 }
720 uintptr_t *getBootClassPathResource(Class *class, MethodBlock *mb, uintptr_t *ostack) {
721 Object *string = (Object *) ostack[0];
722 char *filename = String2Cstr(string);
723 int index = ostack[1];
725 *ostack++ = (uintptr_t) bootClassPathResource(filename, index);
726 return ostack;
727 }
729 /* java.lang.reflect.Constructor */
731 uintptr_t *constructNative(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
732 Object *array = (Object*)ostack[1];
733 Class *decl_class = (Class*)ostack[2];
734 Object *param_types = (Object*)ostack[3];
735 ClassBlock *cb = CLASS_CB(decl_class);
736 MethodBlock *mb = &(cb->methods[ostack[4]]);
737 int no_access_check = ostack[5];
738 Object *ob;
740 if(cb->access_flags & ACC_ABSTRACT) {
741 signalException(java_lang_InstantiationError, cb->name);
742 return ostack;
743 }
745 /* Creating an instance of the class is an
746 active use; make sure it is initialised */
747 if(initClass(decl_class) == NULL)
748 return ostack;
750 if((ob = allocObject(decl_class)) != NULL) {
751 invoke(ob, mb, array, param_types, !no_access_check);
752 *ostack++ = (uintptr_t) ob;
753 }
755 return ostack;
756 }
758 uintptr_t *getMethodModifiers(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
759 Class *decl_class = (Class*)ostack[1];
760 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
761 *ostack++ = (uintptr_t) mb->access_flags;
762 return ostack;
763 }
765 uintptr_t *getMethodSignature(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
766 Class *decl_class = (Class*)ostack[1];
767 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
768 Object *string = NULL;
770 if(mb->signature != NULL) {
771 char *dot_name = slash2dots(mb->signature);
772 string = createString(dot_name);
773 sysFree(dot_name);
774 }
776 *ostack++ = (uintptr_t)string;
777 return ostack;
778 }
780 uintptr_t *getDefaultValue(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
781 Class *decl_class = (Class*)ostack[1];
782 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
783 *ostack++ = (uintptr_t)getMethodDefaultValue(mb);
784 return ostack;
785 }
787 uintptr_t *getMethodDeclaredAnnotations(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
788 Class *decl_class = (Class*)ostack[1];
789 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
790 *ostack++ = (uintptr_t)getMethodAnnotations(mb);
791 return ostack;
792 }
794 uintptr_t *getParameterAnnotations(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
795 Class *decl_class = (Class*)ostack[1];
796 MethodBlock *mb = &(CLASS_CB(decl_class)->methods[ostack[2]]);
797 *ostack++ = (uintptr_t)getMethodParameterAnnotations(mb);
798 return ostack;
799 }
801 uintptr_t *getFieldModifiers(Class *class, MethodBlock *mb, uintptr_t *ostack) {
802 Class *decl_class = (Class*)ostack[1];
803 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
804 *ostack++ = (uintptr_t) fb->access_flags;
805 return ostack;
806 }
808 uintptr_t *getFieldSignature(Class *class, MethodBlock *mb, uintptr_t *ostack) {
809 Class *decl_class = (Class*)ostack[1];
810 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
811 Object *string = NULL;
813 if(fb->signature != NULL) {
814 char *dot_name = slash2dots(fb->signature);
815 string = createString(dot_name);
816 sysFree(dot_name);
817 }
819 *ostack++ = (uintptr_t)string;
820 return ostack;
821 }
823 uintptr_t *getFieldDeclaredAnnotations(Class *class, MethodBlock *mb, uintptr_t *ostack) {
824 Class *decl_class = (Class*)ostack[1];
825 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[2]]);
826 *ostack++ = (uintptr_t)getFieldAnnotations(fb);
827 return ostack;
828 }
830 Object *getAndCheckObject(uintptr_t *ostack, Class *type) {
831 Object *ob = (Object*)ostack[1];
833 if(ob == NULL) {
834 signalException(java_lang_NullPointerException, NULL);
835 return NULL;
836 }
838 if(!isInstanceOf(type, ob->class)) {
839 signalException(java_lang_IllegalArgumentException,
840 "object is not an instance of declaring class");
841 return NULL;
842 }
844 return ob;
845 }
847 uintptr_t *getPntr2Field(uintptr_t *ostack) {
848 Class *decl_class = (Class *)ostack[2];
849 FieldBlock *fb = &(CLASS_CB(decl_class)->fields[ostack[4]]);
850 int no_access_check = ostack[5];
851 Object *ob;
853 if(!no_access_check) {
854 Class *caller = getCallerCallerClass();
855 if(!checkClassAccess(decl_class, caller) || !checkFieldAccess(fb, caller)) {
856 signalException(java_lang_IllegalAccessException, "field is not accessible");
857 return NULL;
858 }
859 }
861 if(fb->access_flags & ACC_STATIC) {
862 /* Setting/getting a static field of a class is an
863 active use; make sure it is initialised */
864 if(initClass(decl_class) == NULL)
865 return NULL;
866 return &fb->static_value;
867 }
869 if((ob = getAndCheckObject(ostack, decl_class)) == NULL)
870 return NULL;
872 return &(INST_DATA(ob)[fb->offset]);
873 }
875 uintptr_t *getField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
876 Class *field_type = (Class *)ostack[3];
877 uintptr_t *field;
879 /* If field is static, getPntr2Field also initialises the field's declaring class */
880 if((field = getPntr2Field(ostack)) != NULL)
881 *ostack++ = (uintptr_t) getReflectReturnObject(field_type, field);
883 return ostack;
884 }
886 uintptr_t *getPrimitiveField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
887 Class *field_type = (Class *)ostack[3];
888 int type_no = ostack[6];
890 ClassBlock *type_cb = CLASS_CB(field_type);
891 uintptr_t *field;
893 /* If field is static, getPntr2Field also initialises the field's declaring class */
894 if(((field = getPntr2Field(ostack)) != NULL) && (!(IS_PRIMITIVE(type_cb)) ||
895 ((ostack = widenPrimitiveValue(getPrimTypeIndex(type_cb), type_no, field, ostack)) == NULL)))
896 signalException(java_lang_IllegalArgumentException, "field type mismatch");
898 return ostack;
899 }
901 uintptr_t *setField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
902 Class *field_type = (Class *)ostack[3];
903 Object *value = (Object*)ostack[6];
904 uintptr_t *field;
906 /* If field is static, getPntr2Field also initialises the field's declaring class */
907 if(((field = getPntr2Field(ostack)) != NULL) &&
908 (unwrapAndWidenObject(field_type, value, field) == NULL))
909 signalException(java_lang_IllegalArgumentException, "field type mismatch");
911 return ostack;
912 }
914 uintptr_t *setPrimitiveField(Class *class, MethodBlock *mb, uintptr_t *ostack) {
915 Class *field_type = (Class *)ostack[3];
916 int type_no = ostack[6];
918 ClassBlock *type_cb = CLASS_CB(field_type);
919 uintptr_t *field;
921 /* If field is static, getPntr2Field also initialises the field's declaring class */
922 if(((field = getPntr2Field(ostack)) != NULL) && (!(IS_PRIMITIVE(type_cb)) ||
923 (widenPrimitiveValue(type_no, getPrimTypeIndex(type_cb), &ostack[7], field) == NULL)))
924 signalException(java_lang_IllegalArgumentException, "field type mismatch");
926 return ostack;
927 }
929 /* java.lang.reflect.Method */
931 uintptr_t *invokeNative(Class *class, MethodBlock *mb2, uintptr_t *ostack) {
932 Object *array = (Object*)ostack[2];
933 Class *decl_class = (Class*)ostack[3];
934 Object *param_types = (Object*)ostack[4];
935 Class *ret_type = (Class*)ostack[5];
936 ClassBlock *cb = CLASS_CB(decl_class);
937 MethodBlock *mb = &(cb->methods[ostack[6]]);
938 int no_access_check = ostack[7];
939 Object *ob = NULL;
940 uintptr_t *ret;
942 /* If it's a static method, class may not be initialised;
943 interfaces are also not normally initialised. */
944 if((mb->access_flags & ACC_STATIC) || IS_INTERFACE(cb))
945 if(initClass(decl_class) == NULL)
946 return ostack;
948 if(!(mb->access_flags & ACC_STATIC))
949 if(((ob = getAndCheckObject(ostack, decl_class)) == NULL) ||
950 ((mb = lookupVirtualMethod(ob, mb)) == NULL))
951 return ostack;
953 if((ret = (uintptr_t*) invoke(ob, mb, array, param_types, !no_access_check)) != NULL)
954 *ostack++ = (uintptr_t) getReflectReturnObject(ret_type, ret);
956 return ostack;
957 }
959 /* java.lang.VMString */
961 /* static method - intern(Ljava/lang/String;)Ljava/lang/String; */
962 uintptr_t *intern(Class *class, MethodBlock *mb, uintptr_t *ostack) {
963 Object *string = (Object*)ostack[0];
964 ostack[0] = (uintptr_t)findInternedString(string);
965 return ostack+1;
966 }
968 /* java.lang.VMThread */
970 /* static method currentThread()Ljava/lang/Thread; */
971 uintptr_t *currentThread(Class *class, MethodBlock *mb, uintptr_t *ostack) {
972 *ostack++ = (uintptr_t)getExecEnv()->thread;
973 return ostack;
974 }
976 /* static method create(Ljava/lang/Thread;J)V */
977 uintptr_t *create(Class *class, MethodBlock *mb, uintptr_t *ostack) {
978 Object *this = (Object *)ostack[0];
979 long long stack_size = *((long long*)&ostack[1]);
980 createJavaThread(this, stack_size);
981 return ostack;
982 }
984 /* static method sleep(JI)V */
985 uintptr_t *jamSleep(Class *class, MethodBlock *mb, uintptr_t *ostack) {
986 long long ms = *((long long *)&ostack[0]);
987 int ns = ostack[2];
988 Thread *thread = threadSelf();
990 threadSleep(thread, ms, ns);
991 return ostack;
992 }
994 /* instance method interrupt()V */
995 uintptr_t *interrupt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
996 Object *this = (Object *)*ostack;
997 Thread *thread = threadSelf0(this);
998 if(thread)
999 threadInterrupt(thread);
1000 return ostack;
1001 }
1003 /* instance method isAlive()Z */
1004 uintptr_t *isAlive(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1005 Object *this = (Object *)*ostack;
1006 Thread *thread = threadSelf0(this);
1007 *ostack++ = thread ? threadIsAlive(thread) : FALSE;
1008 return ostack;
1009 }
1011 /* static method yield()V */
1012 uintptr_t *yield(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1013 Thread *thread = threadSelf();
1014 threadYield(thread);
1015 return ostack;
1016 }
1018 /* instance method isInterrupted()Z */
1019 uintptr_t *isInterrupted(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1020 Object *this = (Object *)*ostack;
1021 Thread *thread = threadSelf0(this);
1022 *ostack++ = thread ? threadIsInterrupted(thread) : FALSE;
1023 return ostack;
1024 }
1026 /* static method interrupted()Z */
1027 uintptr_t *interrupted(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1028 Thread *thread = threadSelf();
1029 *ostack++ = threadInterrupted(thread);
1030 return ostack;
1031 }
1033 /* instance method nativeSetPriority(I)V */
1034 uintptr_t *nativeSetPriority(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1035 return ostack+1;
1036 }
1038 /* instance method holdsLock(Ljava/lang/Object;)Z */
1039 uintptr_t *holdsLock(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1040 Object *ob = (Object *)ostack[0];
1041 if(ob == NULL)
1042 signalException(java_lang_NullPointerException, NULL);
1043 else
1044 *ostack++ = objectLockedByCurrent(ob);
1045 return ostack;
1046 }
1048 /* instance method getState()Ljava/lang/String; */
1049 uintptr_t *getState(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1050 Object *this = (Object *)*ostack;
1051 Thread *thread = threadSelf0(this);
1052 char *state = thread ? getThreadStateString(thread) : "TERMINATED";
1054 *ostack++ = (uintptr_t)Cstr2String(state);
1055 return ostack;
1056 }
1058 /* java.security.VMAccessController */
1060 /* instance method getStack()[[Ljava/lang/Object; */
1061 uintptr_t *getStack(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1062 Class *object_class = findArrayClass("[[Ljava/lang/Object;");
1063 Class *class_class = findArrayClass("[Ljava/lang/Class;");
1064 Class *string_class = findArrayClass("[Ljava/lang/String;");
1065 Object *stack, *names, *classes;
1066 Frame *frame;
1067 int depth;
1069 if(object_class == NULL || class_class == NULL || string_class == NULL)
1070 return ostack;
1072 frame = getExecEnv()->last_frame;
1073 depth = 0;
1075 do {
1076 for(; frame->mb != NULL; frame = frame->prev, depth++);
1077 } while((frame = frame->prev)->prev != NULL);
1079 stack = allocArray(object_class, 2, sizeof(Object*));
1080 classes = allocArray(class_class, depth, sizeof(Object*));
1081 names = allocArray(string_class, depth, sizeof(Object*));
1083 if(stack != NULL && names != NULL && classes != NULL) {
1084 Class **dcl = ARRAY_DATA(classes);
1085 Object **dnm = ARRAY_DATA(names);
1086 Object **stk = ARRAY_DATA(stack);
1088 frame = getExecEnv()->last_frame;
1090 do {
1091 for(; frame->mb != NULL; frame = frame->prev) {
1092 *dcl++ = frame->mb->class;
1093 *dnm++ = createString(frame->mb->name);
1094 }
1095 } while((frame = frame->prev)->prev != NULL);
1097 stk[0] = classes;
1098 stk[1] = names;
1099 }
1101 *ostack++ = (uintptr_t) stack;
1102 return ostack;
1103 }
1105 uintptr_t *getThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1106 *ostack++ = getThreadsCount();
1107 return ostack;
1108 }
1110 uintptr_t *getPeakThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1111 *ostack++ = getPeakThreadsCount();
1112 return ostack;
1113 }
1115 uintptr_t *getTotalStartedThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1116 *(u8*)ostack = getTotalStartedThreadsCount();
1117 return ostack + 2;
1118 }
1120 uintptr_t *resetPeakThreadCount(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1121 resetPeakThreadsCount();
1122 return ostack;
1123 }
1125 uintptr_t *findMonitorDeadlockedThreads(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1126 *ostack++ = (uintptr_t)NULL;
1127 return ostack;
1128 }
1130 uintptr_t *getThreadInfoForId(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1131 long long id = *((long long *)&ostack[0]);
1132 int max_depth = ostack[2];
1134 Thread *thread = findThreadById(id);
1135 Object *info = NULL;
1137 if(thread != NULL) {
1138 Class *info_class = findSystemClass("java/lang/management/ThreadInfo");
1140 if(info_class != NULL) {
1141 MethodBlock *init = findMethod(info_class, SYMBOL(object_init),
1142 newUtf8("(Ljava/lang/Thread;JJLjava/lang/Object;"
1143 "Ljava/lang/Thread;JJZZ[Ljava/lang/StackTraceElement;)V"));
1144 if(init != NULL) {
1145 Frame *last;
1146 int in_native;
1147 Object *vmthrowable;
1148 int self = thread == threadSelf();
1150 if(!self)
1151 suspendThread(thread);
1153 vmthrowable = setStackTrace0(thread->ee, max_depth);
1155 last = thread->ee->last_frame;
1156 in_native = last->prev == NULL || last->mb->access_flags & ACC_NATIVE;
1158 if(!self)
1159 resumeThread(thread);
1161 if(vmthrowable != NULL) {
1162 Object *trace;
1163 if((info = allocObject(info_class)) != NULL &&
1164 (trace = convertStackTrace(vmthrowable)) != NULL) {
1166 Monitor *mon = thread->blocked_mon;
1167 Object *lock = mon != NULL ? mon->obj : NULL;
1168 Thread *owner = mon != NULL ? mon->owner : NULL;
1169 Object *lock_owner = owner != NULL ? owner->ee->thread : NULL;
1171 executeMethod(info, init, thread->ee->thread, thread->blocked_count, 0LL, lock,
1172 lock_owner, thread->waited_count, 0LL, in_native, FALSE, trace);
1173 }
1174 }
1175 }
1176 }
1177 }
1179 *ostack++ = (uintptr_t)info;
1180 return ostack;
1181 }
1183 /* sun.misc.Unsafe */
1185 static volatile uintptr_t spinlock = 0;
1187 void lockSpinLock() {
1188 while(!LOCKWORD_COMPARE_AND_SWAP(&spinlock, 0, 1));
1189 }
1191 void unlockSpinLock() {
1192 LOCKWORD_WRITE(&spinlock, 0);
1193 }
1195 uintptr_t *objectFieldOffset(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1196 FieldBlock *fb = fbFromReflectObject((Object*)ostack[1]);
1198 *(long long*)ostack = (long long)(uintptr_t)&INST_DATA((Object*)NULL)[fb->offset];
1199 return ostack + 2;
1200 }
1202 uintptr_t *compareAndSwapInt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1203 long long offset = *((long long *)&ostack[2]);
1204 uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1205 uintptr_t expect = ostack[4];
1206 uintptr_t update = ostack[5];
1207 int result;
1209 #ifdef COMPARE_AND_SWAP
1210 result = COMPARE_AND_SWAP(addr, expect, update);
1211 #else
1212 lockSpinLock();
1213 if((result = (*addr == expect)))
1214 *addr = update;
1215 unlockSpinLock();
1216 #endif
1218 *ostack++ = result;
1219 return ostack;
1220 }
1222 uintptr_t *compareAndSwapLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1223 long long offset = *((long long *)&ostack[2]);
1224 long long *addr = (long long*)((char*)ostack[1] + offset);
1225 long long expect = *((long long *)&ostack[4]);
1226 long long update = *((long long *)&ostack[6]);
1227 int result;
1229 #ifdef COMPARE_AND_SWAP_64
1230 result = COMPARE_AND_SWAP_64(addr, expect, update);
1231 #else
1232 lockSpinLock();
1233 if((result = (*addr == expect)))
1234 *addr = update;
1235 unlockSpinLock();
1236 #endif
1238 *ostack++ = result;
1239 return ostack;
1240 }
1242 uintptr_t *putOrderedInt(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1243 long long offset = *((long long *)&ostack[2]);
1244 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1245 uintptr_t value = ostack[4];
1247 *addr = value;
1248 return ostack;
1249 }
1251 uintptr_t *putOrderedLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1252 long long offset = *((long long *)&ostack[2]);
1253 long long value = *((long long *)&ostack[4]);
1254 volatile long long *addr = (long long*)((char*)ostack[1] + offset);
1256 if(sizeof(uintptr_t) == 8)
1257 *addr = value;
1258 else {
1259 lockSpinLock();
1260 *addr = value;
1261 unlockSpinLock();
1262 }
1264 return ostack;
1265 }
1267 uintptr_t *putIntVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1268 long long offset = *((long long *)&ostack[2]);
1269 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1270 uintptr_t value = ostack[4];
1272 MBARRIER();
1273 *addr = value;
1275 return ostack;
1276 }
1278 uintptr_t *getIntVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1279 long long offset = *((long long *)&ostack[2]);
1280 volatile uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1282 *ostack++ = *addr;
1283 MBARRIER();
1285 return ostack;
1286 }
1288 uintptr_t *putLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1289 long long offset = *((long long *)&ostack[2]);
1290 long long value = *((long long *)&ostack[4]);
1291 long long *addr = (long long*)((char*)ostack[1] + offset);
1293 if(sizeof(uintptr_t) == 8)
1294 *addr = value;
1295 else {
1296 lockSpinLock();
1297 *addr = value;
1298 unlockSpinLock();
1299 }
1301 return ostack;
1302 }
1304 uintptr_t *getLongVolatile(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1305 long long offset = *((long long *)&ostack[2]);
1306 volatile long long *addr = (long long*)((char*)ostack[1] + offset);
1308 if(sizeof(uintptr_t) == 8)
1309 *(long long*)ostack = *addr;
1310 else {
1311 lockSpinLock();
1312 *(long long*)ostack = *addr;
1313 unlockSpinLock();
1314 }
1316 return ostack + 2;
1317 }
1319 uintptr_t *getLong(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1320 long long offset = *((long long *)&ostack[2]);
1321 long long *addr = (long long*)((char*)ostack[1] + offset);
1323 if(sizeof(uintptr_t) == 8)
1324 *(long long*)ostack = *addr;
1325 else {
1326 lockSpinLock();
1327 *(long long*)ostack = *addr;
1328 unlockSpinLock();
1329 }
1331 return ostack + 2;
1332 }
1334 uintptr_t *putObject(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1335 long long offset = *((long long *)&ostack[2]);
1336 uintptr_t *addr = (uintptr_t*)((char *)ostack[1] + offset);
1337 uintptr_t value = ostack[4];
1339 *addr = value;
1340 return ostack;
1341 }
1343 uintptr_t *arrayBaseOffset(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1344 *ostack++ = (uintptr_t) ARRAY_DATA((Object*)NULL);
1345 return ostack;
1346 }
1348 uintptr_t *arrayIndexScale(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1349 Class *array_class = (Class*)ostack[1];
1350 ClassBlock *cb = CLASS_CB(array_class);
1351 int scale = 0;
1353 if(cb->name[0] == '[')
1354 switch(cb->name[1]) {
1355 case 'I':
1356 case 'F':
1357 scale = 4;
1358 break;
1360 case '[':
1361 case 'L':
1362 scale = sizeof(Object*);
1363 break;
1365 case 'J':
1366 case 'D':
1367 scale = 8;
1368 break;
1369 }
1371 *ostack++ = scale;
1372 return ostack;
1373 }
1375 uintptr_t *unpark(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1376 return ostack;
1377 }
1379 uintptr_t *park(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1380 return ostack;
1381 }
1383 uintptr_t *vmSupportsCS8(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1384 *ostack++ = FALSE;
1385 return ostack;
1386 }
1388 /* jamvm.java.lang.VMClassLoaderData */
1390 uintptr_t *nativeUnloadDll(Class *class, MethodBlock *mb, uintptr_t *ostack) {
1391 unloaderUnloadDll((uintptr_t)*(long long*)&ostack[1]);
1392 return ostack;
1393 }
1395 VMMethod vm_object[] = {
1396 {"getClass", getClass},
1397 {"clone", jamClone},
1398 {"wait", jamWait},
1399 {"notify", notify},
1400 {"notifyAll", notifyAll},
1401 {NULL, NULL}
1402 };
1404 VMMethod vm_system[] = {
1405 {"arraycopy", arraycopy},
1406 {"identityHashCode", identityHashCode},
1407 {NULL, NULL}
1408 };
1410 VMMethod vm_runtime[] = {
1411 {"availableProcessors", availableProcessors},
1412 {"freeMemory", freeMemory},
1413 {"totalMemory", totalMemory},
1414 {"maxMemory", maxMemory},
1415 {"gc", gc},
1416 {"runFinalization", runFinalization},
1417 {"exit", exitInternal},
1418 {"nativeLoad", nativeLoad},
1419 {"mapLibraryName", mapLibraryName},
1420 {NULL, NULL}
1421 };
1423 VMMethod vm_class[] = {
1424 {"isInstance", isInstance},
1425 {"isAssignableFrom", isAssignableFrom},
1426 {"isInterface", isInterface},
1427 {"isPrimitive", isPrimitive},
1428 {"isArray", isArray},
1429 {"isMemberClass", isMember},
1430 {"isLocalClass", isLocal},
1431 {"isAnonymousClass", isAnonymous},
1432 {"getEnclosingClass", getEnclosingClass0},
1433 {"getEnclosingMethod", getEnclosingMethod0},
1434 {"getEnclosingConstructor", getEnclosingConstructor},
1435 {"getClassSignature", getClassSignature},
1436 {"getSuperclass", getSuperclass},
1437 {"getComponentType", getComponentType},
1438 {"getName", getName},
1439 {"getDeclaredClasses", getDeclaredClasses},
1440 {"getDeclaringClass", getDeclaringClass0},
1441 {"getDeclaredConstructors", getDeclaredConstructors},
1442 {"getDeclaredMethods", getDeclaredMethods},
1443 {"getDeclaredFields", getDeclaredFields},
1444 {"getInterfaces", getInterfaces},
1445 {"getClassLoader", getClassLoader},
1446 {"getModifiers", getClassModifiers},
1447 {"forName", forName},
1448 {"throwException", throwException},
1449 {"hasClassInitializer", hasClassInitializer},
1450 {"getDeclaredAnnotations", getClassDeclaredAnnotations},
1451 {NULL, NULL}
1452 };
1454 VMMethod vm_string[] = {
1455 {"intern", intern},
1456 {NULL, NULL}
1457 };
1459 VMMethod vm_thread[] = {
1460 {"currentThread", currentThread},
1461 {"create", create},
1462 {"sleep", jamSleep},
1463 {"interrupt", interrupt},
1464 {"isAlive", isAlive},
1465 {"yield", yield},
1466 {"isInterrupted", isInterrupted},
1467 {"interrupted", interrupted},
1468 {"nativeSetPriority", nativeSetPriority},
1469 {"holdsLock", holdsLock},
1470 {"getState", getState},
1471 {NULL, NULL}
1472 };
1474 VMMethod vm_throwable[] = {
1475 {"fillInStackTrace", fillInStackTrace},
1476 {"getStackTrace", getStackTrace},
1477 {NULL, NULL}
1478 };
1480 VMMethod vm_classloader[] = {
1481 {"loadClass", loadClass},
1482 {"getPrimitiveClass", getPrimitiveClass},
1483 {"defineClass", defineClass0},
1484 {"findLoadedClass", findLoadedClass},
1485 {"resolveClass", resolveClass0},
1486 {"getBootClassPathSize", getBootClassPathSize},
1487 {"getBootClassPathResource", getBootClassPathResource},
1488 {NULL, NULL}
1489 };
1491 VMMethod vm_reflect_constructor[] = {
1492 {"constructNative", constructNative},
1493 {"getConstructorModifiers", getMethodModifiers},
1494 {"getSignature", getMethodSignature},
1495 {"getDeclaredAnnotationsNative", getMethodDeclaredAnnotations},
1496 {"getParameterAnnotationsNative", getParameterAnnotations},
1497 {NULL, NULL}
1498 };
1500 VMMethod vm_reflect_method[] = {
1501 {"invokeNative", invokeNative},
1502 {"getMethodModifiers", getMethodModifiers},
1503 {"getSignature", getMethodSignature},
1504 {"getDefaultValueNative", getDefaultValue},
1505 {"getDeclaredAnnotationsNative", getMethodDeclaredAnnotations},
1506 {"getParameterAnnotationsNative", getParameterAnnotations},
1507 {NULL, NULL}
1508 };
1510 VMMethod vm_reflect_field[] = {
1511 {"getFieldModifiers", getFieldModifiers},
1512 {"getSignature", getFieldSignature},
1513 {"getDeclaredAnnotationsNative", getFieldDeclaredAnnotations},
1514 {"getField", getField},
1515 {"setField", setField},
1516 {"setZField", setPrimitiveField},
1517 {"setBField", setPrimitiveField},
1518 {"setCField", setPrimitiveField},
1519 {"setSField", setPrimitiveField},
1520 {"setIField", setPrimitiveField},
1521 {"setFField", setPrimitiveField},
1522 {"setJField", setPrimitiveField},
1523 {"setDField", setPrimitiveField},
1524 {"getZField", getPrimitiveField},
1525 {"getBField", getPrimitiveField},
1526 {"getCField", getPrimitiveField},
1527 {"getSField", getPrimitiveField},
1528 {"getIField", getPrimitiveField},
1529 {"getFField", getPrimitiveField},
1530 {"getJField", getPrimitiveField},
1531 {"getDField", getPrimitiveField},
1532 {NULL, NULL}
1533 };
1535 VMMethod vm_system_properties[] = {
1536 {"preInit", propertiesPreInit},
1537 {"postInit", propertiesPostInit},
1538 {NULL, NULL}
1539 };
1541 VMMethod vm_stack_walker[] = {
1542 {"getClassContext", getClassContext},
1543 {"getCallingClass", getCallingClass},
1544 {"getCallingClassLoader", getCallingClassLoader},
1545 {"firstNonNullClassLoader", firstNonNullClassLoader},
1546 {NULL, NULL}
1547 };
1549 VMMethod sun_misc_unsafe[] = {
1550 {"objectFieldOffset", objectFieldOffset},
1551 {"compareAndSwapInt", compareAndSwapInt},
1552 {"compareAndSwapLong", compareAndSwapLong},
1553 {"compareAndSwapObject", compareAndSwapInt},
1554 {"putOrderedInt", putOrderedInt},
1555 {"putOrderedLong", putOrderedLong},
1556 {"putOrderedObject", putOrderedInt},
1557 {"putIntVolatile", putIntVolatile},
1558 {"getIntVolatile", getIntVolatile},
1559 {"putLongVolatile", putOrderedLong},
1560 {"putLong", putLong},
1561 {"getLongVolatile", getLongVolatile},
1562 {"getLong", getLong},
1563 {"putObjectVolatile", putIntVolatile},
1564 {"putObject", putObject},
1565 {"getObjectVolatile", getIntVolatile},
1566 {"arrayBaseOffset", arrayBaseOffset},
1567 {"arrayIndexScale", arrayIndexScale},
1568 {"unpark", unpark},
1569 {"park", park},
1570 {NULL, NULL}
1571 };
1573 VMMethod vm_access_controller[] = {
1574 {"getStack", getStack},
1575 {NULL, NULL}
1576 };
1578 VMMethod vm_threadmx_bean_impl[] = {
1579 {"getThreadCount", getThreadCount},
1580 {"getPeakThreadCount", getPeakThreadCount},
1581 {"getTotalStartedThreadCount", getTotalStartedThreadCount},
1582 {"resetPeakThreadCount", resetPeakThreadCount},
1583 {"getThreadInfoForId", getThreadInfoForId},
1584 {"findMonitorDeadlockedThreads",findMonitorDeadlockedThreads},
1585 {NULL, NULL}
1586 };
1588 VMMethod concurrent_atomic_long[] = {
1589 {"VMSupportsCS8", vmSupportsCS8},
1590 {NULL, NULL}
1591 };
1593 VMMethod vm_class_loader_data[] = {
1594 {"nativeUnloadDll", nativeUnloadDll},
1595 {NULL, NULL}
1596 };
1598 VMClass native_methods[] = {
1599 {"java/lang/VMClass", vm_class},
1600 {"java/lang/VMObject", vm_object},
1601 {"java/lang/VMThread", vm_thread},
1602 {"java/lang/VMSystem", vm_system},
1603 {"java/lang/VMString", vm_string},
1604 {"java/lang/VMRuntime", vm_runtime},
1605 {"java/lang/VMThrowable", vm_throwable},
1606 {"java/lang/VMClassLoader", vm_classloader},
1607 {"java/lang/reflect/Field", vm_reflect_field},
1608 {"java/lang/reflect/Method", vm_reflect_method},
1609 {"java/lang/reflect/Constructor", vm_reflect_constructor},
1610 {"java/security/VMAccessController", vm_access_controller},
1611 {"gnu/classpath/VMSystemProperties", vm_system_properties},
1612 {"gnu/classpath/VMStackWalker", vm_stack_walker},
1613 {"gnu/java/lang/management/VMThreadMXBeanImpl", vm_threadmx_bean_impl},
1614 {"sun/misc/Unsafe", sun_misc_unsafe},
1615 {"jamvm/java/lang/VMClassLoaderData$Unloader", vm_class_loader_data},
1616 {"java/util/concurrent/atomic/AtomicLong", concurrent_atomic_long},
1617 {NULL, NULL}
1618 };
