1 /* native/native.c - table of native functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
31 The .hh files created with the header file generator are all
32 included here as are the C functions implementing these methods.
34 $Id: native.c 1888 2005-01-27 21:04:09Z motse $
48 /* Include files for IO functions */
52 #include <sys/types.h>
59 #include "cacao/cacao.h"
60 #include "mm/memory.h"
61 #include "native/jni.h"
62 #include "native/native.h"
63 #include "native/include/java_lang_Throwable.h"
64 #include "toolbox/logging.h"
65 #include "vm/builtin.h"
66 #include "vm/exceptions.h"
67 #include "vm/global.h"
68 #include "vm/loader.h"
69 #include "vm/options.h"
70 #include "vm/tables.h"
71 #include "vm/jit/asmpart.h"
72 #include "vm/jit/jit.h"
75 /* include table of native functions ******************************************/
79 #include "native/vm/GtkComponentPeer.c"
80 #include "native/vm/GtkScrollPanePeer.c"
81 #include "native/vm/GtkFileDialogPeer.c"
84 #include "nativetable.inc"
87 /* for java-string to char conversion */
88 #define MAXSTRINGSIZE 1000
91 /******************** systemclasses required for native methods ***************/
93 classinfo *class_java_lang_Class;
94 classinfo *class_java_lang_VMClass;
95 classinfo *class_java_lang_System;
96 classinfo *class_java_lang_ClassLoader;
97 classinfo *class_gnu_java_lang_SystemClassLoader;
98 classinfo *class_java_lang_SecurityManager;
99 classinfo *class_java_lang_Double;
100 classinfo *class_java_lang_Float;
101 classinfo *class_java_lang_Long;
102 classinfo *class_java_lang_Byte;
103 classinfo *class_java_lang_Short;
104 classinfo *class_java_lang_Boolean;
105 classinfo *class_java_lang_Void;
106 classinfo *class_java_lang_Character;
107 classinfo *class_java_lang_Integer;
109 methodinfo *method_vmclass_init;
112 /* the system classloader object */
113 struct java_lang_ClassLoader *SystemClassLoader = NULL;
115 /* for raising exceptions from native methods */
116 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
117 java_objectheader* _exceptionptr = NULL;
121 /** Create a new ProtectionDomain object for a classpath_info structure.
122 This object will be used for every java.lang.class object who represents a
123 class which has been loaded from the location this classpath_info structure
125 static inline void create_ProtectionDomain(struct classpath_info *cpi) {
136 /* create a new java.io.File object */
137 c = class_new(utf_new_char_classname("java/io/File"));
139 if (!class_load(c) || !class_link(c)) {
140 log_text("unable to find java.io.File");
141 throw_main_exception_exit();
144 mid = class_resolvemethod(c, utf_new_char("<init>"), utf_new_char("(Ljava/lang/String;)V"));
147 log_text("unable to find constructor in java.io.File");
151 obj = builtin_new (c);
152 asm_calljavafunction(mid,obj,javastring_new(utf_new_char(cpi->path)),NULL,NULL);
154 if (*exceptionptr != NULL) {
155 utf_display((*exceptionptr)->vftbl->class->name);
161 /* get URL of CodeSource from java.io.File object */
162 mid = class_resolvemethod(c, utf_new_char("toURL"), utf_new_char("()Ljava/net/URL;"));
165 log_text("unable to find toURL in java.io.File");
169 url = asm_calljavafunction(mid,obj,url,NULL,NULL);
171 if (*exceptionptr != NULL) {
172 utf_display((*exceptionptr)->vftbl->class->name);
178 /* create a new java.security.CodeSource object */
179 c = class_new(utf_new_char_classname("java/security/CodeSource"));
181 if (!class_load(c) || !class_link(c)) {
182 log_text("unable to find java.security.CodeSource");
183 throw_main_exception_exit();
186 mid = class_resolvemethod(c,
187 utf_new_char("<init>"),
188 utf_new_char("(Ljava/net/URL;[Ljava/security/cert/Certificate;)V"));
191 log_text("unable to find constructor in java.security.CodeSource");
195 cs = builtin_new (c);
196 asm_calljavafunction(mid,cs,url,NULL,NULL);
198 if (*exceptionptr != NULL) {
199 utf_display((*exceptionptr)->vftbl->class->name);
205 /* create a new java.security.PermissionCollection object */
208 classpc = class_new(utf_new_char_classname("java/security/PermissionCollection"));
210 if (!class_load(c) || !class_link(c)) {
211 log_text("unable to find java.security.PermissionCollection");
212 throw_main_exception_exit();
215 mid = class_resolvemethod(classpc, utf_new_char("<init>"),
216 utf_new_char("()V"));
219 log_text("unable to find constructor in java.security.PermissionCollection");
223 pc = builtin_new (classpc);
224 asm_calljavafunction(mid,pc,NULL,NULL,NULL);
226 if (*exceptionptr != NULL) {
227 utf_display((*exceptionptr)->vftbl->class->name);
233 /* add AllPermission - todo: this should not be the default behaviour */
234 c = class_new(utf_new_char_classname("java/security/AllPermission"));
236 if (!class_load(c) || !class_link(c)) {
237 log_text("unable to find java.security.AllPermission");
238 throw_main_exception_exit();
241 mid = class_resolvemethod(c,
242 utf_new_char("<init>"),
243 utf_new_char("()V"));
246 log_text("unable to find constructor in java.security.AllPermission");
251 obj = builtin_new (c);
252 asm_calljavafunction(mid,obj,NULL,NULL,NULL);
254 if (*exceptionptr != NULL) {
255 utf_display((*exceptionptr)->vftbl->class->name);
262 mid = class_resolvemethod(classpc,
264 utf_new_char("(Ljava/security/Permission;)V"));
267 log_text("unable to find add in java.security.PermissionCollection");
271 asm_calljavafunction(mid,pc,obj,NULL,NULL);
272 if (*exceptionptr != NULL) {
273 utf_display((*exceptionptr)->vftbl->class->name);
279 /* create a new java.security.ProtectionDomain object */
280 c = class_new(utf_new_char_classname("java/security/ProtectionDomain"));
282 if (!class_load(c) || !class_link(c)) {
283 log_text("unable to find java.security.ProtectionDomain");
284 throw_main_exception_exit();
287 mid = class_resolvemethod(c,
288 utf_new_char("<init>"),
289 utf_new_char("(Ljava/security/CodeSource;Ljava/security/PermissionCollection;)V"));
292 log_text("unable to find constructor in java.security.ProtectionDomain");
296 obj = builtin_new (c);
297 asm_calljavafunction(mid,obj,cs,pc,NULL);
299 if (*exceptionptr != NULL) {
300 utf_display((*exceptionptr)->vftbl->class->name);
306 cpi->pd = (struct java_security_ProtectionDomain*) obj;
310 /************* use classinfo structure as java.lang.Class object **************/
312 void use_class_as_object(classinfo *c)
314 if (!c->classvftbl) {
315 /* is the class loaded */
318 panic("Class could not be loaded in use_class_as_object");
319 /* is the class linked */
322 panic("Class could not be linked in use_class_as_object");
324 /*if (class_java_lang_Class ==0) panic("java/lang/Class not loaded in use_class_as_object");
325 if (class_java_lang_Class->vftbl ==0) panic ("vftbl == 0 in use_class_as_object");*/
326 c->header.vftbl = class_java_lang_Class->vftbl;
327 c->classvftbl = true;
330 /* set a real, java object ProtectionDomain and CodeSource.
331 Only one ProtectionDomain-object per classpath_info is needed.*/
333 /* only set ProtectionDomain for non primitive type classes*/
334 if (((struct classpath_info*)c->pd)->pd == NULL)
335 create_ProtectionDomain((struct classpath_info *)c->pd);
337 c->pd = ((struct classpath_info*)c->pd)->pd;
344 /************************** tables for methods ********************************/
349 #ifdef STATIC_CLASSPATH
350 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
352 /* table for fast string comparison */
353 static nativecompref nativecomptable[NATIVETABLESIZE];
355 /* string comparsion table initialized */
356 static bool nativecompdone = false;
360 /* XXX don't define this in a header file!!! */
362 static struct nativeCall nativeCalls[] =
364 #include "nativecalls.inc"
367 #define NATIVECALLSSIZE (sizeof(nativeCalls) / sizeof(struct nativeCall))
369 struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE];
371 /******************************************************************************/
373 /**include "natcalls.h" **/
376 /*********************** function: native_loadclasses **************************
378 load classes required for native methods
380 *******************************************************************************/
382 void native_loadclasses()
384 static int classesLoaded = 0; /*temporary hack JoWenn*/
392 #if !defined(STATIC_CLASSPATH)
393 /* We need to access the dummy native table, not only to remove a warning */
394 /* but to be sure that the table is not optimized away (gcc does this */
396 p = &dummynativetable;
399 class_java_lang_Cloneable =
400 class_new(utf_new_char("java/lang/Cloneable"));
401 class_load(class_java_lang_Cloneable);
402 class_link(class_java_lang_Cloneable);
404 class_java_lang_Class =
405 class_new(utf_new_char("java/lang/Class"));
406 class_load(class_java_lang_Class);
407 class_link(class_java_lang_Class);
409 class_java_lang_VMClass =
410 class_new(utf_new_char("java/lang/VMClass"));
411 class_load(class_java_lang_VMClass);
412 class_link(class_java_lang_VMClass);
414 class_java_lang_ClassLoader =
415 class_new(utf_new_char("java/lang/ClassLoader"));
416 class_load(class_java_lang_ClassLoader);
417 class_link(class_java_lang_ClassLoader);
419 /* load classes for wrapping primitive types */
420 class_java_lang_Double = class_new(utf_new_char("java/lang/Double"));
421 class_load(class_java_lang_Double);
422 class_link(class_java_lang_Double);
424 class_java_lang_Float = class_new(utf_new_char("java/lang/Float"));
425 class_load(class_java_lang_Float);
426 class_link(class_java_lang_Float);
428 class_java_lang_Character = class_new(utf_new_char("java/lang/Character"));
429 class_load(class_java_lang_Character);
430 class_link(class_java_lang_Character);
432 class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer"));
433 class_load(class_java_lang_Integer);
434 class_link(class_java_lang_Integer);
436 class_java_lang_Long = class_new(utf_new_char("java/lang/Long"));
437 class_load(class_java_lang_Long);
438 class_link(class_java_lang_Long);
440 class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte"));
441 class_load(class_java_lang_Byte);
442 class_link(class_java_lang_Byte);
444 class_java_lang_Short = class_new(utf_new_char("java/lang/Short"));
445 class_load(class_java_lang_Short);
446 class_link(class_java_lang_Short);
448 class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean"));
449 class_load(class_java_lang_Boolean);
450 class_link(class_java_lang_Boolean);
452 class_java_lang_Void = class_new(utf_new_char("java/lang/Void"));
453 class_load(class_java_lang_Void);
454 class_link(class_java_lang_Void);
458 /*****************************************************************************
460 create systemclassloader object and initialize instance fields
462 ******************************************************************************/
464 void init_systemclassloader()
466 if (!SystemClassLoader) {
467 native_loadclasses();
469 /* create object and call initializer */
470 SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader")));
472 /* systemclassloader has no parent */
473 SystemClassLoader->parent = NULL;
474 SystemClassLoader->initialized = true;
479 /*********************** Function: native_findfunction *************************
481 Looks up a method (must have the same class name, method name, descriptor
482 and 'static'ness) and returns a function pointer to it.
483 Returns: function pointer or NULL (if there is no such method)
485 Remark: For faster operation, the names/descriptors are converted from C
486 strings to Unicode the first time this function is called.
488 *******************************************************************************/
490 functionptr native_findfunction(utf *cname, utf *mname,
491 utf *desc, bool isstatic)
493 #ifdef STATIC_CLASSPATH
495 /* entry of table for fast string comparison */
496 struct nativecompref *n;
497 /* for warning message if no function is found */
501 isstatic = isstatic ? true : false;
503 if (!nativecompdone) {
504 for (i = 0; i < NATIVETABLESIZE; i++) {
505 nativecomptable[i].classname =
506 utf_new_char(nativetable[i].classname);
507 nativecomptable[i].methodname =
508 utf_new_char(nativetable[i].methodname);
509 nativecomptable[i].descriptor =
510 utf_new_char(nativetable[i].descriptor);
511 nativecomptable[i].isstatic =
512 nativetable[i].isstatic;
513 nativecomptable[i].func =
516 nativecompdone = true;
521 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
523 buffer = MNEW(char, buffer_len);
525 strcpy(buffer, "searching matching function in native table:");
526 utf_sprint(buffer+strlen(buffer), mname);
527 strcpy(buffer+strlen(buffer), ": ");
528 utf_sprint(buffer+strlen(buffer), desc);
529 strcpy(buffer+strlen(buffer), " for class ");
530 utf_sprint(buffer+strlen(buffer), cname);
534 MFREE(buffer, char, buffer_len);
537 for (i = 0; i < NATIVETABLESIZE; i++) {
538 n = &(nativecomptable[i]);
540 if (cname == n->classname && mname == n->methodname &&
541 desc == n->descriptor && isstatic == n->isstatic)
545 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
549 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
551 buffer = MNEW(char, buffer_len);
553 strcpy(buffer, "comparing with:");
554 utf_sprint(buffer+strlen(buffer), n->methodname);
555 strcpy (buffer+strlen(buffer), ": ");
556 utf_sprint(buffer+strlen(buffer), n->descriptor);
557 strcpy(buffer+strlen(buffer), " for class ");
558 utf_sprint(buffer+strlen(buffer), n->classname);
562 MFREE(buffer, char, buffer_len);
569 /* no function was found, display warning */
572 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
574 buffer = MNEW(char, buffer_len);
576 strcpy(buffer, "warning: native function ");
577 utf_sprint(buffer + strlen(buffer), mname);
578 strcpy(buffer + strlen(buffer), ": ");
579 utf_sprint(buffer + strlen(buffer), desc);
580 strcpy(buffer + strlen(buffer), " not found in class ");
581 utf_sprint(buffer + strlen(buffer), cname);
585 MFREE(buffer, char, buffer_len);
589 /* keep compiler happy */
592 /* dynamic classpath */
598 /********************** function: javastring_new *******************************
600 creates a new object of type java/lang/String with the text of
601 the specified utf8-string
603 return: pointer to the string or NULL if memory is exhausted.
605 *******************************************************************************/
607 java_lang_String *javastring_new(utf *u)
609 char *utf_ptr; /* current utf character in utf string */
610 u4 utflength; /* length of utf-string if uncompressed */
611 java_lang_String *s; /* result-string */
616 *exceptionptr = new_nullpointerexception();
621 utflength = utf_strlen(u);
623 s = (java_lang_String *) builtin_new(class_java_lang_String);
624 a = builtin_newarray_char(utflength);
626 /* javastring or character-array could not be created */
630 /* decompress utf-string */
631 for (i = 0; i < utflength; i++)
632 a->data[i] = utf_nextu2(&utf_ptr);
634 /* set fields of the javastring-object */
637 s->count = utflength;
643 /********************** function: javastring_new_char **************************
645 creates a new java/lang/String object which contains the convertet
646 C-string passed via text.
648 return: the object pointer or NULL if memory is exhausted.
650 *******************************************************************************/
652 java_lang_String *javastring_new_char(const char *text)
655 s4 len; /* length of the string */
656 java_lang_String *s; /* result-string */
660 *exceptionptr = new_nullpointerexception();
666 s = (java_lang_String *) builtin_new(class_java_lang_String);
667 a = builtin_newarray_char(len);
669 /* javastring or character-array could not be created */
674 for (i = 0; i < len; i++)
675 a->data[i] = text[i];
677 /* set fields of the javastring-object */
686 /************************* function javastring_tochar **************************
688 converts a Java string into a C string.
690 return: pointer to C string
692 Caution: every call of this function overwrites the previous string !!!
694 *******************************************************************************/
696 static char stringbuffer[MAXSTRINGSIZE];
698 char *javastring_tochar(java_objectheader *so)
700 java_lang_String *s = (java_lang_String *) so;
712 if (s->count > MAXSTRINGSIZE)
715 for (i = 0; i < s->count; i++)
716 stringbuffer[i] = a->data[s->offset + i];
718 stringbuffer[i] = '\0';
724 /****************** function class_findfield_approx ****************************
726 searches in 'classinfo'-structure for a field with the
729 *******************************************************************************/
731 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
735 for (i = 0; i < c->fieldscount; i++) {
736 /* compare field names */
737 if ((c->fields[i].name == name))
738 return &(c->fields[i]);
741 /* field was not found, raise exception */
742 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
748 s4 class_findfield_index_approx(classinfo *c, utf *name)
752 for (i = 0; i < c->fieldscount; i++) {
753 /* compare field names */
754 if ((c->fields[i].name == name))
758 /* field was not found, raise exception */
759 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
765 /********************** function: native_new_and_init *************************
767 Creates a new object on the heap and calls the initializer.
768 Returns the object pointer or NULL if memory is exhausted.
770 *******************************************************************************/
772 java_objectheader *native_new_and_init(classinfo *c)
775 java_objectheader *o;
778 return *exceptionptr;
787 /* find initializer */
789 m = class_findmethod(c, utf_new_char("<init>"), utf_new_char("()V"));
791 /* initializer not found */
796 /* call initializer */
798 asm_calljavafunction(m, o, NULL, NULL, NULL);
804 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
807 java_objectheader *o;
810 return *exceptionptr;
819 /* find initializer */
821 m = class_resolveclassmethod(c,
822 utf_new_char("<init>"),
823 utf_new_char("(Ljava/lang/String;)V"),
827 /* initializer not found */
832 /* call initializer */
834 asm_calljavafunction(m, o, s, NULL, NULL);
840 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
843 java_objectheader *o;
846 return *exceptionptr;
855 /* find initializer */
857 m = class_resolveclassmethod(c,
858 utf_new_char("<init>"),
859 utf_new_char("(I)V"),
863 /* initializer not found */
867 /* call initializer */
869 asm_calljavafunction(m, o, (void *) (ptrint) i, NULL, NULL);
875 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
878 java_objectheader *o;
881 return *exceptionptr;
890 /* find initializer */
892 m = class_findmethod(c,
893 utf_new_char("<init>"),
894 utf_new_char("(Ljava/lang/Throwable;)V"));
896 /* initializer not found */
901 /* call initializer */
903 asm_calljavafunction(m, o, t, NULL, NULL);
909 /******************** function: stringtable_update ****************************
911 traverses the javastring hashtable and sets the vftbl-entries of
912 javastrings which were temporarily set to NULL, because
913 java.lang.Object was not yet loaded
915 *******************************************************************************/
917 void stringtable_update ()
919 java_lang_String *js;
921 literalstring *s; /* hashtable entry */
924 for (i = 0; i < string_hash.size; i++) {
925 s = string_hash.ptr[i];
929 js = (java_lang_String *) s->string;
931 if (!js || !js->value)
932 /* error in hashtable found */
933 panic("invalid literalstring in hashtable");
937 if (!js->header.vftbl)
938 /* vftbl of javastring is NULL */
939 js->header.vftbl = class_java_lang_String->vftbl;
941 if (!a->header.objheader.vftbl)
942 /* vftbl of character-array is NULL */
943 a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
945 /* follow link in external hash chain */
953 /************************* function: u2_utflength ***************************
955 returns the utf length in bytes of a u2 array
957 *****************************************************************************/
959 u4 u2_utflength(u2 *text, u4 u2_length)
961 u4 result_len = 0; /* utf length in bytes */
962 u2 ch; /* current unicode character */
965 for (len = 0; len < u2_length; len++) {
966 /* next unicode character */
969 /* determine bytes required to store unicode character as utf */
970 if (ch && (ch < 0x80))
982 /********************* function: utf_new_u2 ***********************************
984 make utf symbol from u2 array,
985 if isclassname is true '.' is replaced by '/'
987 *******************************************************************************/
989 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
991 char *buffer; /* memory buffer for unicode characters */
992 char *pos; /* pointer to current position in buffer */
993 u4 left; /* unicode characters left */
994 u4 buflength; /* utf length in bytes of the u2 array */
995 utf *result; /* resulting utf-string */
998 /* determine utf length in bytes and allocate memory */
999 /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */
1000 buflength = u2_utflength(unicode_pos, unicode_length);
1001 buffer = MNEW(char, buflength);
1006 for (i = 0; i++ < unicode_length; unicode_pos++) {
1007 /* next unicode character */
1008 u2 c = *unicode_pos;
1010 if ((c != 0) && (c < 0x80)) {
1013 if ((int) left < 0) break;
1014 /* convert classname */
1015 if (isclassname && c == '.')
1020 } else if (c < 0x800) {
1022 unsigned char high = c >> 6;
1023 unsigned char low = c & 0x3F;
1025 if ((int) left < 0) break;
1026 *pos++ = high | 0xC0;
1027 *pos++ = low | 0x80;
1031 char low = c & 0x3f;
1032 char mid = (c >> 6) & 0x3F;
1033 char high = c >> 12;
1035 if ((int) left < 0) break;
1036 *pos++ = high | 0xE0;
1037 *pos++ = mid | 0x80;
1038 *pos++ = low | 0x80;
1042 /* insert utf-string into symbol-table */
1043 result = utf_new(buffer,buflength);
1045 MFREE(buffer, char, buflength);
1051 /********************* function: javastring_toutf *****************************
1053 make utf symbol from javastring
1055 *******************************************************************************/
1057 utf *javastring_toutf(java_lang_String *string, bool isclassname)
1059 java_lang_String *str = (java_lang_String *) string;
1061 /* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */
1062 /* fflush(stdout); */
1064 return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
1068 /********************* function: literalstring_u2 *****************************
1070 searches for the javastring with the specified u2-array in
1071 the string hashtable, if there is no such string a new one is
1074 if copymode is true a copy of the u2-array is made
1076 *******************************************************************************/
1078 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
1081 literalstring *s; /* hashtable element */
1082 java_lang_String *js; /* u2-array wrapped in javastring */
1083 java_chararray *stringdata; /* copy of u2-array */
1088 /* #define DEBUG_LITERALSTRING_U2 */
1089 #ifdef DEBUG_LITERALSTRING_U2
1090 printf("literalstring_u2: length=%d, offset=%d\n", length, offset);
1094 /* find location in hashtable */
1095 key = unicode_hashkey(a->data + offset, length);
1096 slot = key & (string_hash.size - 1);
1097 s = string_hash.ptr[slot];
1100 js = (java_lang_String *) s->string;
1102 if (length == js->count) {
1104 for (i = 0; i < length; i++) {
1105 if (a->data[offset + i] != js->value->data[i])
1109 /* string already in hashtable, free memory */
1111 mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
1113 #ifdef DEBUG_LITERALSTRING_U2
1114 printf("literalstring_u2: foundentry at %p\n", js);
1115 utf_display(javastring_toutf(js, 0));
1119 return (java_objectheader *) js;
1123 /* follow link in external hash chain */
1128 /* create copy of u2-array for new javastring */
1129 u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
1130 stringdata = mem_alloc(arraysize);
1131 /* memcpy(stringdata, a, arraysize); */
1132 memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader));
1133 memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
1139 /* location in hashtable found, complete arrayheader */
1140 stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
1141 stringdata->header.size = length;
1143 /* if we use eager loading, we have to check loaded String class */
1145 class_java_lang_String =
1146 class_new_intern(utf_new_char("java/lang/String"));
1148 if (!class_load(class_java_lang_String))
1151 list_addfirst(&unlinkedclasses, class_java_lang_String);
1154 /* create new javastring */
1155 js = NEW(java_lang_String);
1156 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1157 initObjectLock(&js->header);
1159 js->header.vftbl = class_java_lang_String->vftbl;
1160 js->value = stringdata;
1164 #ifdef DEBUG_LITERALSTRING_U2
1165 printf("literalstring_u2: newly created at %p\n", js);
1166 utf_display(javastring_toutf(js, 0));
1171 /* create new literalstring */
1172 s = NEW(literalstring);
1173 s->hashlink = string_hash.ptr[slot];
1174 s->string = (java_objectheader *) js;
1175 string_hash.ptr[slot] = s;
1177 /* update number of hashtable entries */
1178 string_hash.entries++;
1180 /* reorganization of hashtable */
1181 if (string_hash.entries > (string_hash.size * 2)) {
1182 /* reorganization of hashtable, average length of
1183 the external chains is approx. 2 */
1187 hashtable newhash; /* the new hashtable */
1189 /* create new hashtable, double the size */
1190 init_hashtable(&newhash, string_hash.size * 2);
1191 newhash.entries = string_hash.entries;
1193 /* transfer elements to new hashtable */
1194 for (i = 0; i < string_hash.size; i++) {
1195 s = string_hash.ptr[i];
1197 literalstring *nexts = s->hashlink;
1198 js = (java_lang_String *) s->string;
1199 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
1201 s->hashlink = newhash.ptr[slot];
1202 newhash.ptr[slot] = s;
1204 /* follow link in external hash chain */
1209 /* dispose old table */
1210 MFREE(string_hash.ptr, void*, string_hash.size);
1211 string_hash = newhash;
1214 return (java_objectheader *) js;
1218 /******************** Function: literalstring_new *****************************
1220 creates a new javastring with the text of the utf-symbol
1221 and inserts it into the string hashtable
1223 *******************************************************************************/
1225 java_objectheader *literalstring_new(utf *u)
1227 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
1228 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
1229 java_chararray *a; /* u2-array constructed from utf string */
1232 /* allocate memory */
1233 a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1235 /* convert utf-string to u2-array */
1236 for (i = 0; i < utflength; i++)
1237 a->data[i] = utf_nextu2(&utf_ptr);
1239 return literalstring_u2(a, utflength, 0, false);
1243 /********************** function: literalstring_free **************************
1245 removes a javastring from memory
1247 ******************************************************************************/
1249 void literalstring_free(java_objectheader* sobj)
1251 java_lang_String *s = (java_lang_String *) sobj;
1252 java_chararray *a = s->value;
1254 /* dispose memory of java.lang.String object */
1255 FREE(s, java_lang_String);
1257 /* dispose memory of java-characterarray */
1258 FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1262 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
1266 /* XXX this kind of copying does not work (in the general
1267 * case). The interface tables would have to be copied, too. I
1268 * don't see why we should make a copy anyway. -Edwin
1270 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1271 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1272 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1277 /******************************************************************************************
1279 creates method signature (excluding return type) from array of
1280 class-objects representing the parameters of the method
1282 *******************************************************************************************/
1285 utf *create_methodsig(java_objectarray* types, char *retType)
1287 char *buffer; /* buffer for building the desciptor */
1288 char *pos; /* current position in buffer */
1289 utf *result; /* the method signature */
1290 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1293 if (!types) return NULL;
1295 /* determine required buffer-size */
1296 for (i = 0; i < types->header.size; i++) {
1297 classinfo *c = (classinfo *) types->data[i];
1298 buffer_size = buffer_size + c->name->blength + 2;
1301 if (retType) buffer_size += strlen(retType);
1303 /* allocate buffer */
1304 buffer = MNEW(char, buffer_size);
1307 /* method-desciptor starts with parenthesis */
1310 for (i = 0; i < types->header.size; i++) {
1313 /* current argument */
1314 classinfo *c = (classinfo *) types->data[i];
1316 /* current position in utf-text */
1317 char *utf_ptr = c->name->text;
1319 /* determine type of argument */
1320 if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1322 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1323 *pos++ = *utf_ptr; /* copy text */
1327 /* check for primitive types */
1328 for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1329 char *utf_pos = utf_ptr - 1;
1330 char *primitive = primitivetype_table[j].wrapname;
1333 while (utf_pos < utf_end(c->name)) {
1334 if (*utf_pos++ != *primitive++) goto nomatch;
1337 /* primitive type found */
1338 *pos++ = primitivetype_table[j].typesig;
1345 /* no primitive type and no arrayclass, so must be object */
1349 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1363 for (i = 0; i < strlen(retType); i++) {
1364 *pos++ = retType[i];
1368 /* create utf-string */
1369 result = utf_new(buffer, (pos - buffer));
1370 MFREE(buffer, char, buffer_size);
1376 /******************************************************************************************
1378 retrieve the next argument or returntype from a descriptor
1379 and return the corresponding class
1381 *******************************************************************************************/
1383 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1385 classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1386 (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1389 panic("illegal descriptor");
1391 if (skip) return NULL;
1393 use_class_as_object(c);
1398 /* get_parametertypes **********************************************************
1400 use the descriptor of a method to generate a java/lang/Class array
1401 which contains the classes of the parametertypes of the method
1403 *******************************************************************************/
1405 java_objectarray* get_parametertypes(methodinfo *m)
1407 utf *descr = m->descriptor; /* method-descriptor */
1408 char *utf_ptr = descr->text; /* current position in utf-text */
1409 char *desc_end = utf_end(descr); /* points behind utf string */
1410 java_objectarray* result;
1411 int parametercount = 0;
1415 utf_nextu2(&utf_ptr);
1417 /* determine number of parameters */
1418 while (*utf_ptr != ')') {
1419 get_type(&utf_ptr, desc_end, true);
1423 /* create class-array */
1424 result = builtin_anewarray(parametercount, class_java_lang_Class);
1426 utf_ptr = descr->text;
1427 utf_nextu2(&utf_ptr);
1429 /* get returntype classes */
1430 for (i = 0; i < parametercount; i++)
1432 (java_objectheader *) get_type(&utf_ptr, desc_end, false);
1438 /* get_exceptiontypes **********************************************************
1440 get the exceptions which can be thrown by a method
1442 *******************************************************************************/
1444 java_objectarray* get_exceptiontypes(methodinfo *m)
1448 java_objectarray *result;
1450 excount = m->thrownexceptionscount;
1452 /* create class-array */
1453 result = builtin_anewarray(excount, class_java_lang_Class);
1455 for (i = 0; i < excount; i++) {
1456 java_objectheader *o = (java_objectheader *) (m->thrownexceptions[i]);
1457 use_class_as_object((classinfo *) o);
1458 result->data[i] = o;
1468 /******************************************************************************************
1470 get the returntype class of a method
1472 *******************************************************************************************/
1474 classinfo *get_returntype(methodinfo *m)
1476 char *utf_ptr; /* current position in utf-text */
1477 char *desc_end; /* points behind utf string */
1478 utf *desc = m->descriptor; /* method-descriptor */
1480 utf_ptr = desc->text;
1481 desc_end = utf_end(desc);
1483 /* ignore parametertypes */
1484 while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1487 return get_type(&utf_ptr,desc_end, false);
1491 /*****************************************************************************/
1492 /*****************************************************************************/
1495 /*--------------------------------------------------------*/
1496 void printNativeCall(nativeCall nc) {
1499 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1500 for (i=0; i<nc.methCnt; i++) {
1501 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1503 for (j=0; j<nc.callCnt[i]; j++) {
1504 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1505 nc.methods[i].methodCalls[j].classname,
1506 nc.methods[i].methodCalls[j].methodname,
1507 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1510 printf("-+++++--------------------\n");fflush(stdout);
1513 /*--------------------------------------------------------*/
1514 void printCompNativeCall(nativeCompCall nc) {
1516 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1517 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1518 utf_display(nc.classname); fflush(stdout);
1520 for (i=0; i<nc.methCnt; i++) {
1521 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1522 utf_display(nc.methods[i].methodname); fflush(stdout);
1523 utf_display(nc.methods[i].descriptor);fflush(stdout);
1524 printf("\n");fflush(stdout);
1526 for (j=0; j<nc.callCnt[i]; j++) {
1527 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1528 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1529 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1530 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1531 printf("\n");fflush(stdout);
1534 printf("---------------------\n");fflush(stdout);
1538 /*--------------------------------------------------------*/
1539 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1552 /*--------------------------------------------------------*/
1553 nativeCall* findNativeClassCalls(char *aclassname ) {
1556 for (i=0;i<NATIVECALLSSIZE; i++) {
1557 /* convert table to utf later to speed up search */
1558 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1559 return &nativeCalls[i];
1564 /*--------------------------------------------------------*/
1565 /*--------------------------------------------------------*/
1566 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1570 ncc->classname = utf_new_char(nc.classname);
1571 ncc->methCnt = nc.methCnt;
1573 for (i=0; i<nc.methCnt; i++) {
1574 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1575 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1576 ncc->callCnt[i] = nc.callCnt[i];
1578 for (j=0; j<nc.callCnt[i]; j++) {
1580 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1582 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1583 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1584 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1587 ncc->methods[i].methodCalls[j].methodname = NULL;
1588 ncc->methods[i].methodCalls[j].descriptor = NULL;
1596 /*--------------------------------------------------------*/
1598 bool natcall2utf(bool natcallcompdone) {
1601 if (natcallcompdone)
1604 for (i=0;i<NATIVECALLSSIZE; i++) {
1605 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1611 /*--------------------------------------------------------*/
1614 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end, classinfo **start)
1616 #if defined(__GNUC__)
1617 #warning platform dependend
1619 java_objectarray *tmpArray;
1621 classinfo **current;
1625 size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
1627 /*printf("end %p, start %p, size %ld\n",end,start,size);*/
1628 if (!class_java_lang_Class)
1629 class_java_lang_Class = class_new(utf_new_char("java/lang/Class"));
1631 if (!class_java_lang_SecurityManager)
1632 class_java_lang_SecurityManager =
1633 class_new(utf_new_char("java/lang/SecurityManager"));
1636 if (start == class_java_lang_SecurityManager) {
1643 builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1645 for(i = 0, current = start; i < size; i++, current--) {
1647 /* printf("%d\n",i);
1648 utf_display(c->name);*/
1649 use_class_as_object(c);
1650 tmpArray->data[i] = (java_objectheader *) c;
1657 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end, classinfo **start)
1659 #if defined(__GNUC__)
1660 #warning platform dependend
1663 classinfo **current;
1665 classinfo *privilegedAction;
1668 size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
1670 /* log_text("builtin_asm_getclassloader");
1671 printf("end %p, start %p, size %ld\n",end,start,size);*/
1673 if (!class_java_lang_SecurityManager)
1674 class_java_lang_SecurityManager =
1675 class_new(utf_new_char("java/lang/SecurityManager"));
1678 if (start == class_java_lang_SecurityManager) {
1684 privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1686 for(i = 0, current = start; i < size; i++, current--) {
1689 if (c == privilegedAction)
1693 return (java_lang_ClassLoader *) c->classloader;
1699 log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1700 init_systemclassloader();
1702 return SystemClassLoader;*/
1707 * These are local overrides for various environment variables in Emacs.
1708 * Please do not remove this and leave it at the end of the file, where
1709 * Emacs will automagically detect them.
1710 * ---------------------------------------------------------------------
1713 * indent-tabs-mode: t