1 /* src/native/vm/VMClass.c - java/lang/VMClass
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: Roman Obermaiser
29 Changes: Joseph Wenninger
32 $Id: VMClass.c 2174 2005-04-01 08:42:57Z twisti $
40 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/native.h"
43 #include "native/include/java_lang_Class.h"
44 #include "native/include/java_lang_ClassLoader.h"
45 #include "native/include/java_lang_Object.h"
46 #include "native/include/java_lang_VMClass.h"
47 #include "native/include/java_lang_reflect_Constructor.h"
48 #include "native/include/java_lang_reflect_Field.h"
49 #include "native/include/java_lang_reflect_Method.h"
50 #include "native/include/java_security_ProtectionDomain.h"
51 #include "toolbox/logging.h"
52 #include "vm/builtin.h"
53 #include "vm/exceptions.h"
54 #include "vm/global.h"
55 #include "vm/loader.h"
56 #include "vm/stringlocal.h"
57 #include "vm/tables.h"
60 /* for selecting public members */
61 #define MEMBER_PUBLIC 0
65 * Class: java/lang/VMClass
67 * Signature: (Ljava/lang/String;)Ljava/lang/Class;
69 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, java_lang_String *s)
73 /* XXX TWISTI: we currently use the classpath default implementation, maybe
74 we change this someday to a faster native version */
79 /* illegal argument */
84 /* create utf string in which '.' is replaced by '/' */
86 u = javastring_toutf(s, true);
88 /* create a new class, ... */
92 /* try to load, ... */
94 if (!load_class_bootstrap(c)) {
97 xclass = (*exceptionptr)->vftbl->class;
99 /* if the exception is a NoClassDefFoundError, we replace it with a
100 ClassNotFoundException, otherwise return the exception */
102 if (xclass == class_java_lang_NoClassDefFoundError) {
103 /* clear exceptionptr, because builtin_new checks for
104 ExceptionInInitializerError */
105 *exceptionptr = NULL;
108 new_exception_javastring(string_java_lang_ClassNotFoundException, s);
119 /* ...and initialize it */
124 use_class_as_object(c);
126 return (java_lang_Class *) c;
132 * Class: java/lang/VMClass
133 * Method: getClassLoader
134 * Signature: ()Ljava/lang/ClassLoader;
136 JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, java_lang_Class *that)
138 return (java_lang_ClassLoader *) ((classinfo *) that)->classloader;
143 * Class: java_lang_VMClass
144 * Method: getComponentType
145 * Signature: ()Ljava/lang/Class;
147 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz, java_lang_Class *that)
149 classinfo *thisclass = (classinfo *) that;
151 arraydescriptor *desc;
153 if ((desc = thisclass->vftbl->arraydesc) != NULL) {
154 if (desc->arraytype == ARRAYTYPE_OBJECT)
155 c = desc->componentvftbl->class;
157 c = primitivetype_table[desc->arraytype].class_primitive;
160 use_class_as_object(c);
163 return (java_lang_Class *) c;
168 * Class: java/lang/VMClass
169 * Method: getDeclaredConstructors
170 * Signature: (Z)[Ljava/lang/reflect/Constructor;
172 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
175 classinfo *c = (classinfo *) that;
176 java_objectheader *o;
177 classinfo *class_constructor;
178 java_objectarray *array_constructor; /* result: array of Method-objects */
179 java_objectarray *exceptiontypes; /* the exceptions thrown by the method */
180 methodinfo *m; /* the current method to be represented */
181 int public_methods = 0; /* number of public methods of the class */
185 /* determine number of constructors */
186 for (i = 0; i < c->methodscount; i++)
187 if (((c->methods[i].flags & ACC_PUBLIC) || !public_only) &&
188 (c->methods[i].name == utf_init))
191 class_constructor = class_new(utf_new_char("java/lang/reflect/Constructor"));
193 if (!class_constructor->loaded)
194 load_class_bootstrap(class_constructor);
196 if (!class_constructor->linked)
197 link_class(class_constructor);
199 array_constructor = builtin_anewarray(public_methods, class_constructor);
201 if (!array_constructor)
204 for (i = 0; i < c->methodscount; i++)
205 if ((c->methods[i].flags & ACC_PUBLIC) || !public_only){
207 if (m->name != utf_init)
210 o = native_new_and_init(class_constructor);
211 array_constructor->data[pos++] = o;
213 /* array of exceptions declared to be thrown, information not available !! */
214 exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
216 /* class_showconstantpool(class_constructor);*/
217 /* initialize instance fields */
218 /* ((java_lang_reflect_Constructor*)o)->flag=(m->flags & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED));*/
219 setfield_critical(class_constructor,o,"clazz", "Ljava/lang/Class;", jobject, (jobject) c /*this*/);
220 setfield_critical(class_constructor,o,"slot", "I", jint, i);
221 /* setfield_critical(class_constructor,o,"flag", "I", jint, (m->flags & (ACC_PRIVATE |
222 ACC_PUBLIC | ACC_PROTECTED))); */
223 setfield_critical(class_constructor,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
224 setfield_critical(class_constructor,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) get_parametertypes(m));
227 return array_constructor;
232 * Class: java_lang_VMClass
233 * Method: getDeclaredClasses
234 * Signature: (Z)[Ljava/lang/Class;
236 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 publicOnly)
238 #if defined(__GNUC__)
239 #warning fix the public only case
241 classinfo *c = (classinfo *) that;
242 int pos = 0; /* current declared class */
243 int declaredclasscount = 0; /* number of declared classes */
244 java_objectarray *result; /* array of declared classes */
245 int notPublicOnly = !publicOnly;
251 /*printf("PublicOnly: %d\n",publicOnly);*/
252 if (!Java_java_lang_VMClass_isPrimitive(env, clazz, (java_lang_Class *) c) && (c->name->text[0] != '[')) {
253 /* determine number of declared classes */
254 for (i = 0; i < c->innerclasscount; i++) {
255 if ( (c->innerclass[i].outer_class == c) && (notPublicOnly || (c->innerclass[i].flags & ACC_PUBLIC)))
256 /* outer class is this class */
257 declaredclasscount++;
261 /*class_showmethods(c); */
263 result = builtin_anewarray(declaredclasscount, class_java_lang_Class);
265 for (i = 0; i < c->innerclasscount; i++) {
266 classinfo *inner = c->innerclass[i].inner_class;
267 classinfo *outer = c->innerclass[i].outer_class;
269 if ((outer == c) && (notPublicOnly || (inner->flags & ACC_PUBLIC))) {
270 /* outer class is this class, store innerclass in array */
271 use_class_as_object(inner);
272 result->data[pos++] = (java_objectheader *) inner;
281 * Class: java/lang/Class
282 * Method: getDeclaringClass
283 * Signature: ()Ljava/lang/Class;
285 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIEnv *env, jclass clazz, struct java_lang_Class *that)
287 #if defined(__GNUC__)
290 classinfo *c = (classinfo *) that;
292 if (that && !Java_java_lang_VMClass_isPrimitive(env, clazz,that) && (c->name->text[0] != '[')) {
295 if (c->innerclasscount == 0) /* no innerclasses exist */
298 for (i = 0; i < c->innerclasscount; i++) {
299 classinfo *inner = c->innerclass[i].inner_class;
300 classinfo *outer = c->innerclass[i].outer_class;
303 /* innerclass is this class */
304 use_class_as_object(outer);
305 return (java_lang_Class *) outer;
310 /* return NULL for arrayclasses and primitive classes */
315 java_lang_reflect_Field* cacao_getField0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, s4 public_only)
318 classinfo *fieldtype;
319 fieldinfo *f; /* the field to be represented */
320 java_lang_reflect_Field *o; /* result: field-object */
321 utf *desc; /* the fielddescriptor */
324 /* create Field object */
325 /* c = (classinfo *) loader_load(utf_new_char("java/lang/reflect/Field")); */
326 c = class_new(utf_new_char("java/lang/reflect/Field"));
327 o = (java_lang_reflect_Field *) native_new_and_init(c);
329 /* get fieldinfo entry */
330 idx = class_findfield_index_approx((classinfo *) that, javastring_toutf(name, false));
333 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
337 f = &(((classinfo *) that)->fields[idx]);
339 if (public_only && !(f->flags & ACC_PUBLIC)) {
340 /* field is not public and public only had been requested*/
341 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
345 desc = f->descriptor;
346 fieldtype = class_from_descriptor(desc->text, utf_end(desc), NULL, CLASSLOAD_LOAD);
350 /* initialize instance fields */
351 setfield_critical(c,o,"declaringClass", "Ljava/lang/Class;", jobject, (jobject) that /*this*/);
352 /* ((java_lang_reflect_Field*)(o))->flag=f->flags;*/
353 /* save type in slot-field for faster processing */
354 /* setfield_critical(c,o,"flag", "I", jint, (jint) f->flags); */
355 /*o->flag = f->flags;*/
356 setfield_critical(c,o,"slot", "I", jint, (jint) idx);
357 setfield_critical(c,o,"name", "Ljava/lang/String;", jstring, (jstring) name);
358 /*setfield_critical(c,o,"type", "Ljava/lang/Class;", jclass, fieldtype);*/
368 * Class: java_lang_VMClass
369 * Method: getDeclaredFields
370 * Signature: (Z)[Ljava/lang/reflect/Field;
372 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredFields(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
374 classinfo *c = (classinfo *) that;
375 classinfo *class_field;
376 java_objectarray *array_field; /* result: array of field-objects */
377 int public_fields = 0; /* number of elements in field-array */
381 /* determine number of fields */
382 for (i = 0; i < c->fieldscount; i++)
383 if ((c->fields[i].flags & ACC_PUBLIC) || (!public_only))
386 /* class_field = loader_load(utf_new_char("java/lang/reflect/Field")); */
387 class_field = class_new(utf_new_char("java/lang/reflect/Field"));
392 /* create array of fields */
393 array_field = builtin_anewarray(public_fields, class_field);
395 /* creation of array failed */
399 /* get the fields and store in the array */
400 for (i = 0; i < c->fieldscount; i++)
401 if ( (c->fields[i].flags & ACC_PUBLIC) || (!public_only))
402 array_field->data[pos++] =
403 (java_objectheader *) cacao_getField0(env,
404 that, (java_lang_String *) javastring_new(c->fields[i].name),public_only);
410 * Class: java/lang/Class
411 * Method: getInterfaces
412 * Signature: ()[Ljava/lang/Class;
414 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv *env, jclass clazz, java_lang_Class *that)
416 classinfo *c = (classinfo *) that;
420 a = builtin_anewarray(c->interfacescount, class_java_lang_Class);
425 for (i = 0; i < c->interfacescount; i++) {
426 use_class_as_object(c->interfaces[i]);
428 a->data[i] = (java_objectheader *) c->interfaces[i];
435 java_lang_reflect_Method* cacao_getMethod0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, java_objectarray *types, s4 which)
438 classinfo *clazz = (classinfo *) that;
439 java_lang_reflect_Method* o; /* result: Method-object */
440 java_objectarray *exceptiontypes; /* the exceptions thrown by the method */
441 methodinfo *m; /* the method to be represented */
443 /* c = (classinfo *) loader_load(utf_new_char("java/lang/reflect/Method")); */
444 c = class_new(utf_new_char("java/lang/reflect/Method"));
445 o = (java_lang_reflect_Method *) native_new_and_init(c);
447 /* find the method */
448 m = class_resolvemethod_approx(clazz,
449 javastring_toutf(name, false),
450 create_methodsig(types,0)
453 if (!m || (which == MEMBER_PUBLIC && !(m->flags & ACC_PUBLIC))) {
454 /* no apropriate method was found */
455 *exceptionptr = new_exception(string_java_lang_NoSuchMethodException);
459 /* array of exceptions declared to be thrown, information not available! */
460 exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
462 /* initialize instance fields */
464 setfield_critical(c, o, "clazz", "Ljava/lang/Class;", jobject,
465 (jobject) clazz /*this*/);
467 setfield_critical(c, o, "parameterTypes", "[Ljava/lang/Class;", jobject,
470 setfield_critical(c, o, "exceptionTypes", "[Ljava/lang/Class;", jobject,
471 (jobject) exceptiontypes);
473 setfield_critical(c, o, "name", "Ljava/lang/String;", jstring,
474 (jobject) javastring_new(m->name));
476 setfield_critical(c, o, "modifiers", "I", jint,
479 setfield_critical(c, o, "slot", "I", jint,
482 setfield_critical(c, o, "returnType", "Ljava/lang/Class;", jclass,
490 * Class: java_lang_VMClass
491 * Method: getDeclaredMethods
492 * Signature: (Z)[Ljava/lang/reflect/Method;
494 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
496 classinfo *c = (classinfo *) that;
497 java_objectheader *o;
498 classinfo *class_method;
499 java_objectarray *array_method; /* result: array of Method-objects */
500 java_objectarray *exceptiontypes; /* the exceptions thrown by the method */
501 methodinfo *m; /* the current method to be represented */
502 int public_methods = 0; /* number of public methods of the class */
506 /* class_method = (classinfo*) loader_load(utf_new_char ("java/lang/reflect/Method")); */
507 class_method = class_new(utf_new_char("java/lang/reflect/Method"));
512 /* JOWENN: array classes do not declare methods according to mauve test. It should be considered, if
513 we should return to my old clone method overriding instead of declaring it as a member function */
514 if (Java_java_lang_VMClass_isArray(env, clazz,that)) {
515 return builtin_anewarray(0, class_method);
519 /* determine number of methods */
520 for (i = 0; i < c->methodscount; i++)
521 if ((((c->methods[i].flags & ACC_PUBLIC)) || (!public_only)) &&
523 ((c->methods[i].name == utf_init) ||
524 (c->methods[i].name == utf_clinit) )
528 class_showmethods(class_method);
533 array_method = builtin_anewarray(public_methods, class_method);
538 for (i = 0; i < c->methodscount; i++)
539 if (((c->methods[i].flags & ACC_PUBLIC) || (!public_only)) &&
541 ((c->methods[i].name == utf_init) ||
542 (c->methods[i].name == utf_clinit) )
546 o = native_new_and_init(class_method);
547 array_method->data[pos++] = o;
549 /* array of exceptions declared to be thrown, information not available !! */
550 exceptiontypes = builtin_anewarray (0, class_java_lang_Class);
553 /* initialize instance fields */
554 /* ((java_lang_reflect_Method*)o)->flag=(m->flags &
555 (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
556 ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)
558 setfield_critical(class_method,o,"declaringClass", "Ljava/lang/Class;", jobject, (jobject) c /*this*/);
559 setfield_critical(class_method,o,"name", "Ljava/lang/String;", jstring, (jobject) javastring_new(m->name));
560 /* setfield_critical(class_method,o,"flag", "I", jint, (m->flags &
561 (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
562 ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)));*/
563 setfield_critical(class_method,o,"slot", "I", jint, i);
564 /* setfield_critical(class_method,o,"returnType", "Ljava/lang/Class;", jclass, get_returntype(m));
565 setfield_critical(class_method,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
566 setfield_critical(class_method,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) get_parametertypes(m));*/
574 * Class: java/lang/Class
575 * Method: getModifiers
578 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_getModifiers(JNIEnv *env, jclass clazz, java_lang_Class *that)
580 classinfo *c = (classinfo *) that;
586 * Class: java/lang/Class
588 * Signature: ()Ljava/lang/String;
590 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getName(JNIEnv *env, jclass clazz, java_lang_Class* that)
593 classinfo *c = (classinfo *) that;
594 java_lang_String *s = (java_lang_String *) javastring_new(c->name);
599 /* return string where '/' is replaced by '.' */
600 for (i = 0; i < s->value->header.size; i++) {
601 if (s->value->data[i] == '/')
602 s->value->data[i] = '.';
611 * Class: java/lang/VMClass
612 * Method: getBeautifiedName
613 * Signature: (Ljava/lang/Class;)Ljava/lang/String;
615 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getBeautifiedName(JNIEnv *env, jclass clazz, java_lang_Class *par1)
618 classinfo *c = (classinfo *) (par1);
620 char *utf__ptr = c->name->text; /* current position in utf-text */
621 char **utf_ptr = &utf__ptr;
622 char *desc_end = utf_end(c->name); /* points behind utf string */
629 log_text("Java_java_lang_VMClass_getBeautifiedName");
630 utf_display(c->name);
631 log_text("beautifying");
634 while ( *utf_ptr != desc_end ) {
635 if (utf_nextu2(utf_ptr)=='[') dimCnt++;
638 utf__ptr = (*utf_ptr) - 1;
644 utf_display(c->name);
648 if (((*utf_ptr) + 1) == desc_end) {
649 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
650 if (primitivetype_table[i].typesig == (*utf__ptr)) {
651 len = dimCnt * 2 + strlen(primitivetype_table[i].name);
652 str = MNEW(char, len + 1);
653 strcpy(str, primitivetype_table[i].name);
661 len = dimCnt + strlen(c->name->text) - 2;
662 str = MNEW(char, len + 1);
663 strncpy(str, ++utf__ptr, len - 2 * dimCnt);
665 len = strlen(c->name->text);
666 str = MNEW(char, len + 1);
667 strncpy(str, utf__ptr, len);
672 dimCnt = len - 2 * dimCnt;
674 for (i = len - 1; i >= dimCnt; i = i - 2) {
679 s = javastring_new(utf_new_char(str));
680 MFREE(str, char, len + 1);
684 /* return string where '/' is replaced by '.' */
685 for (i = 0; i < s->value->header.size; i++) {
686 if (s->value->data[i] == '/') s->value->data[i] = '.';
695 * Class: java/lang/Class
696 * Method: getSuperclass
697 * Signature: ()Ljava/lang/Class;
699 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, java_lang_Class *that)
701 classinfo *cl = (classinfo *) that;
702 classinfo *c = cl->super;
707 use_class_as_object(c);
709 return (java_lang_Class *) c;
714 * Class: java/lang/Class
718 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, java_lang_Class *that)
720 classinfo *c = (classinfo *) that;
722 return c->vftbl->arraydesc != NULL;
727 * Class: java/lang/Class
728 * Method: isAssignableFrom
729 * Signature: (Ljava/lang/Class;)Z
731 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Class *sup)
734 *exceptionptr = new_nullpointerexception();
738 return builtin_isanysubclass(sup, that);
744 * Class: java/lang/Class
746 * Signature: (Ljava/lang/Object;)Z
748 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Object *obj)
750 return builtin_instanceof(obj, that);
755 * Class: java/lang/Class
756 * Method: isInterface
759 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *that)
761 classinfo *c = (classinfo *) that;
763 if (c->flags & ACC_INTERFACE)
771 * Class: java/lang/Class
772 * Method: isPrimitive
775 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass clazz, java_lang_Class *that)
778 classinfo *c = (classinfo *) that;
780 /* search table of primitive classes */
781 for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
782 if (primitivetype_table[i].class_primitive == c)
790 * Class: java/lang/VMClass
794 JNIEXPORT void JNICALL Java_java_lang_VMClass_initialize(JNIEnv *env, jclass clazz, java_lang_Class *c)
798 ci = (classinfo *) c;
800 /* initialize class */
801 if (!ci->initialized)
802 /* No need to check return value, because class_init already sets the */
803 /* exception pointer. */
804 (void) class_init(ci);
809 * Class: java/lang/VMClass
810 * Method: loadArrayClass
811 * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;
813 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_loadArrayClass(JNIEnv *env, jclass clazz, java_lang_String *name, java_lang_ClassLoader *classloader)
818 /* create utf string with `.' replaced by `/' */
820 u = javastring_toutf(name, true);
822 /* class_new "loads" the array class */
826 /* set the classloader */
828 c->classloader = classloader;
830 use_class_as_object(c);
832 return (java_lang_Class *) c;
837 * Class: java/lang/VMClass
838 * Method: throwException
839 * Signature: (Ljava/lang/Throwable;)V
841 JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
843 *exceptionptr = (java_objectheader *) t;
848 * These are local overrides for various environment variables in Emacs.
849 * Please do not remove this and leave it at the end of the file, where
850 * Emacs will automagically detect them.
851 * ---------------------------------------------------------------------
854 * indent-tabs-mode: t