32366f0529939e2a353ad7ca92efc32c80c12c28
[cacao.git] / src / native / vm / java_lang_Class.c
1 /* src/native/vm/java_lang_Class.c - java/lang/Class
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
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.
14
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.
19
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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: java_lang_Class.c 8343 2007-08-17 21:39:32Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdint.h>
34 #include <string.h>
35
36 #include "vm/types.h"
37
38 #include "mm/memory.h"
39
40 #include "native/jni.h"
41 #include "native/llni.h"
42 #include "native/native.h"
43
44 /* keep this order of the native includes */
45
46 #include "native/include/java_lang_String.h"
47
48 #if defined(ENABLE_JAVASE)
49 # if defined(WITH_CLASSPATH_SUN)
50 #  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
51 # endif
52 # include "native/include/java_lang_ClassLoader.h"
53 #endif
54
55 #include "native/include/java_lang_Object.h"
56 #include "native/include/java_lang_Class.h"
57
58 #if defined(ENABLE_JAVASE)
59 # include "native/include/java_lang_reflect_Constructor.h"
60 # include "native/include/java_lang_reflect_Field.h"
61 # include "native/include/java_lang_reflect_Method.h"
62 #endif
63
64 #include "native/vm/java_lang_Class.h"
65 #include "native/vm/java_lang_String.h"
66
67 #if defined(ENABLE_JAVASE)
68 # include "native/vm/reflect.h"
69 #endif
70
71 #include "toolbox/logging.h"
72
73 #include "vm/builtin.h"
74 #include "vm/exceptions.h"
75 #include "vm/global.h"
76 #include "vm/initialize.h"
77 #include "vm/primitive.h"
78 #include "vm/resolve.h"
79 #include "vm/stringlocal.h"
80
81 #include "vmcore/class.h"
82 #include "vmcore/loader.h"
83
84 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
85 #include "vm/vm.h"
86 #include "vmcore/annotation.h"
87 #include "native/include/sun_reflect_ConstantPool.h"
88 #endif
89
90 /*
91  * Class:     java/lang/Class
92  * Method:    getName
93  * Signature: ()Ljava/lang/String;
94  */
95 java_lang_String *_Jv_java_lang_Class_getName(java_lang_Class *klass)
96 {
97         classinfo               *c;
98         java_lang_String        *s;
99         java_handle_chararray_t *ca;
100         u4                       i;
101
102         c = LLNI_classinfo_unwrap(klass);
103
104         /* create a java string */
105
106         s = (java_lang_String *) javastring_new(c->name);
107
108         if (s == NULL)
109                 return NULL;
110
111         /* return string where '/' is replaced by '.' */
112
113         LLNI_field_get_ref(s, value, ca);
114
115         for (i = 0; i < LLNI_array_size(ca); i++) {
116                 if (LLNI_array_direct(ca, i) == '/')
117                         LLNI_array_direct(ca, i) = '.';
118         }
119
120         return s;
121 }
122
123
124 /*
125  * Class:     java/lang/Class
126  * Method:    forName
127  * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
128  */
129 #if defined(ENABLE_JAVASE)
130 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader)
131 #elif defined(ENABLE_JAVAME_CLDC1_1)
132 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
133 #endif
134 {
135 #if defined(ENABLE_JAVASE)
136         classloader *cl;
137 #endif
138         utf         *ufile;
139         utf         *uname;
140         classinfo   *c;
141         u2          *pos;
142         s4           i;
143
144 #if defined(ENABLE_JAVASE)
145         cl = loader_hashtable_classloader_add((java_handle_t *) loader);
146 #endif
147
148         /* illegal argument */
149
150         if (name == NULL) {
151                 exceptions_throw_nullpointerexception();
152                 return NULL;
153         }
154
155         /* create utf string in which '.' is replaced by '/' */
156
157         ufile = javastring_toutf((java_handle_t *) name, true);
158         uname = javastring_toutf((java_handle_t *) name, false);
159
160         /* name must not contain '/' (mauve test) */
161
162         for (i = 0, pos = LLNI_field_direct(name, value)->data + LLNI_field_direct(name, offset); i < LLNI_field_direct(name, count); i++, pos++) {
163                 if (*pos == '/') {
164                         exceptions_throw_classnotfoundexception(uname);
165                         return NULL;
166                 }
167         }
168
169         /* try to load, ... */
170
171 #if defined(ENABLE_JAVASE)
172         c = load_class_from_classloader(ufile, cl);
173 #elif defined(ENABLE_JAVAME_CLDC1_1)
174         c = load_class_bootstrap(ufile);
175 #endif
176
177         if (c == NULL)
178             return NULL;
179
180         /* link, ... */
181
182         if (!link_class(c))
183                 return NULL;
184         
185         /* ...and initialize it, if required */
186
187 #if defined(ENABLE_JAVASE)
188         if (initialize)
189 #endif
190                 if (!initialize_class(c))
191                         return NULL;
192
193         return LLNI_classinfo_wrap(c);
194 }
195
196
197 /*
198  * Class:     java/lang/Class
199  * Method:    isInstance
200  * Signature: (Ljava/lang/Object;)Z
201  */
202 s4 _Jv_java_lang_Class_isInstance(java_lang_Class *klass, java_lang_Object *o)
203 {
204         classinfo     *c;
205         java_handle_t *ob;
206
207         c = LLNI_classinfo_unwrap(klass);
208         ob = (java_handle_t *) o;
209
210         if (!(c->state & CLASS_LINKED))
211                 if (!link_class(c))
212                         return 0;
213
214         return builtin_instanceof(ob, c);
215 }
216
217
218 /*
219  * Class:     java/lang/Class
220  * Method:    isAssignableFrom
221  * Signature: (Ljava/lang/Class;)Z
222  */
223 s4 _Jv_java_lang_Class_isAssignableFrom(java_lang_Class *klass, java_lang_Class *c)
224 {
225         classinfo *kc;
226         classinfo *cc;
227
228         kc = LLNI_classinfo_unwrap(klass);
229         cc = LLNI_classinfo_unwrap(c);
230
231         if (cc == NULL) {
232                 exceptions_throw_nullpointerexception();
233                 return 0;
234         }
235
236         if (!(kc->state & CLASS_LINKED))
237                 if (!link_class(kc))
238                         return 0;
239
240         if (!(cc->state & CLASS_LINKED))
241                 if (!link_class(cc))
242                         return 0;
243
244         return class_isanysubclass(cc, kc);
245 }
246
247
248 /*
249  * Class:     java/lang/Class
250  * Method:    isInterface
251  * Signature: ()Z
252  */
253 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isInterface(JNIEnv *env, java_lang_Class *this)
254 {
255         classinfo *c;
256
257         c = LLNI_classinfo_unwrap(this);
258
259         return class_is_interface(c);
260 }
261
262
263 #if defined(ENABLE_JAVASE)
264
265 /*
266  * Class:     java/lang/Class
267  * Method:    isPrimitive
268  * Signature: ()Z
269  */
270 s4 _Jv_java_lang_Class_isPrimitive(java_lang_Class *klass)
271 {
272         classinfo *c;
273
274         c = LLNI_classinfo_unwrap(klass);
275
276         return class_is_primitive(c);
277 }
278
279
280 /*
281  * Class:     java/lang/Class
282  * Method:    getSuperclass
283  * Signature: ()Ljava/lang/Class;
284  */
285 java_lang_Class *_Jv_java_lang_Class_getSuperclass(java_lang_Class *klass)
286 {
287         classinfo *c;
288         classinfo *super;
289
290         c = LLNI_classinfo_unwrap(klass);
291
292         super = class_get_superclass(c);
293
294         return LLNI_classinfo_wrap(super);
295 }
296
297
298 /*
299  * Class:     java/lang/Class
300  * Method:    getInterfaces
301  * Signature: ()[Ljava/lang/Class;
302  */
303 java_handle_objectarray_t *_Jv_java_lang_Class_getInterfaces(java_lang_Class *klass)
304 {
305         classinfo                 *c;
306         java_handle_objectarray_t *oa;
307
308         c = LLNI_classinfo_unwrap(klass);
309
310         oa = class_get_interfaces(c);
311
312         return oa;
313 }
314
315
316 /*
317  * Class:     java/lang/Class
318  * Method:    getModifiers
319  * Signature: (Z)I
320  */
321 s4 _Jv_java_lang_Class_getModifiers(java_lang_Class *klass, s4 ignoreInnerClassesAttrib)
322 {
323         classinfo             *c;
324         classref_or_classinfo  inner;
325         classref_or_classinfo  outer;
326         utf                   *innername;
327         s4                     i;
328
329         c = LLNI_classinfo_unwrap(klass);
330
331         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
332                 /* search for passed class as inner class */
333
334                 for (i = 0; i < c->innerclasscount; i++) {
335                         inner = c->innerclass[i].inner_class;
336                         outer = c->innerclass[i].outer_class;
337
338                         /* Check if inner is a classref or a real class and get
339                the name of the structure */
340
341                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
342
343                         /* innerclass is this class */
344
345                         if (innername == c->name) {
346                                 /* has the class actually an outer class? */
347
348                                 if (outer.any)
349                                         /* return flags got from the outer class file */
350                                         return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
351                                 else
352                                         return c->flags & ACC_CLASS_REFLECT_MASK;
353                         }
354                 }
355         }
356
357         /* passed class is no inner class or it was not requested */
358
359         return c->flags & ACC_CLASS_REFLECT_MASK;
360 }
361
362
363 /*
364  * Class:     java/lang/Class
365  * Method:    getDeclaringClass
366  * Signature: ()Ljava/lang/Class;
367  */
368 java_lang_Class *_Jv_java_lang_Class_getDeclaringClass(java_lang_Class *klass)
369 {
370         classinfo *c;
371         classinfo *dc;
372
373         c = LLNI_classinfo_unwrap(klass);
374
375         dc = class_get_declaringclass(c);
376
377         return LLNI_classinfo_wrap(dc);
378 }
379
380
381 /*
382  * Class:     java/lang/Class
383  * Method:    getDeclaredClasses
384  * Signature: (Z)[Ljava/lang/Class;
385  */
386 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredClasses(java_lang_Class *klass, s4 publicOnly)
387 {
388         classinfo                 *c;
389         java_handle_objectarray_t *oa;
390
391         c = LLNI_classinfo_unwrap(klass);
392
393         oa = class_get_declaredclasses(c, publicOnly);
394
395         return oa;
396 }
397
398
399 /*
400  * Class:     java/lang/Class
401  * Method:    getDeclaredFields
402  * Signature: (Z)[Ljava/lang/reflect/Field;
403  */
404 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, s4 publicOnly)
405 {
406         classinfo                 *c;
407         java_handle_objectarray_t *oa;          /* result: array of field-objects */
408         fieldinfo                 *f;
409         java_lang_reflect_Field   *rf;
410         s4 public_fields;                    /* number of elements in field-array */
411         s4 pos;
412         s4 i;
413
414         c = LLNI_classinfo_unwrap(klass);
415
416         /* determine number of fields */
417
418         for (i = 0, public_fields = 0; i < c->fieldscount; i++)
419                 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
420                         public_fields++;
421
422         /* create array of fields */
423
424         oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
425
426         if (oa == NULL)
427                 return NULL;
428
429         /* get the fields and store in the array */
430
431         for (i = 0, pos = 0; i < c->fieldscount; i++) {
432                 f = &(c->fields[i]);
433
434                 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
435                         /* create Field object */
436
437                         rf = reflect_field_new(f);
438
439                         /* store object into array */
440
441                         LLNI_objectarray_element_set(oa, pos, rf);
442                         pos++;
443                 }
444         }
445
446         return oa;
447 }
448
449
450 /*
451  * Class:     java/lang/Class
452  * Method:    getDeclaredMethods
453  * Signature: (Z)[Ljava/lang/reflect/Method;
454  */
455 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, s4 publicOnly)
456 {
457         classinfo                 *c;
458         java_lang_reflect_Method  *rm;
459         java_handle_objectarray_t *oa;         /* result: array of Method-objects */
460         methodinfo                *m;     /* the current method to be represented */
461         s4 public_methods;               /* number of public methods of the class */
462         s4 pos;
463         s4 i;
464
465         c = LLNI_classinfo_unwrap(klass);
466
467         public_methods = 0;
468
469         /* JOWENN: array classes do not declare methods according to mauve
470            test.  It should be considered, if we should return to my old
471            clone method overriding instead of declaring it as a member
472            function. */
473
474         if (class_is_array(c))
475                 return builtin_anewarray(0, class_java_lang_reflect_Method);
476
477         /* determine number of methods */
478
479         for (i = 0; i < c->methodscount; i++) {
480                 m = &c->methods[i];
481
482                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
483                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
484                         !(m->flags & ACC_MIRANDA))
485                         public_methods++;
486         }
487
488         oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
489
490         if (oa == NULL)
491                 return NULL;
492
493         for (i = 0, pos = 0; i < c->methodscount; i++) {
494                 m = &c->methods[i];
495
496                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
497                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
498                         !(m->flags & ACC_MIRANDA)) {
499                         /* create Method object */
500
501                         rm = reflect_method_new(m);
502
503                         /* store object into array */
504
505                         LLNI_objectarray_element_set(oa, pos, rm);
506                         pos++;
507                 }
508         }
509
510         return oa;
511 }
512
513
514 /*
515  * Class:     java/lang/Class
516  * Method:    getDeclaredConstructors
517  * Signature: (Z)[Ljava/lang/reflect/Constructor;
518  */
519 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *klass, s4 publicOnly)
520 {
521         classinfo                     *c;
522         methodinfo                    *m; /* the current method to be represented */
523         java_handle_objectarray_t     *oa;     /* result: array of Method-objects */
524         java_lang_reflect_Constructor *rc;
525         s4 public_methods;               /* number of public methods of the class */
526         s4 pos;
527         s4 i;
528
529         c = LLNI_classinfo_unwrap(klass);
530
531         /* determine number of constructors */
532
533         for (i = 0, public_methods = 0; i < c->methodscount; i++) {
534                 m = &c->methods[i];
535
536                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
537                         (m->name == utf_init))
538                         public_methods++;
539         }
540
541         oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
542
543         if (oa == NULL)
544                 return NULL;
545
546         for (i = 0, pos = 0; i < c->methodscount; i++) {
547                 m = &c->methods[i];
548
549                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
550                         (m->name == utf_init)) {
551                         /* create Constructor object */
552
553                         rc = reflect_constructor_new(m);
554
555                         /* store object into array */
556
557                         LLNI_objectarray_element_set(oa, pos, rc);
558                         pos++;
559                 }
560         }
561
562         return oa;
563 }
564
565
566 /*
567  * Class:     java/lang/Class
568  * Method:    getClassLoader
569  * Signature: ()Ljava/lang/ClassLoader;
570  */
571 java_lang_ClassLoader *_Jv_java_lang_Class_getClassLoader(java_lang_Class *klass)
572 {
573         classinfo *c;
574
575         c = LLNI_classinfo_unwrap(klass);
576
577         if (c->classloader == NULL)
578                 return NULL;
579         else
580                 return (java_lang_ClassLoader *) c->classloader->object;
581 }
582
583 #endif /* defined(ENABLE_JAVASE) */
584
585
586 /*
587  * Class:     java/lang/Class
588  * Method:    isArray
589  * Signature: ()Z
590  */
591 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isArray(JNIEnv *env, java_lang_Class *this)
592 {
593         classinfo *c;
594
595         c = LLNI_classinfo_unwrap(this);
596
597         return class_is_array(c);
598 }
599
600
601 #if defined(ENABLE_JAVASE)
602
603 /*
604  * Class:     java/lang/Class
605  * Method:    throwException
606  * Signature: (Ljava/lang/Throwable;)V
607  */
608 void _Jv_java_lang_Class_throwException(java_lang_Throwable *t)
609 {
610         java_handle_t *o;
611
612         o = (java_handle_t *) t;
613
614         exceptions_set_exception(o);
615 }
616
617
618 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
619 /*
620  * Class:     java/lang/Class
621  * Method:    getDeclaredAnnotations
622  * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
623  */
624 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
625 {
626         classinfo                *c               = LLNI_classinfo_unwrap(klass);
627         static methodinfo        *m_parseAnnotationsIntoArray   = NULL;
628         utf                      *utf_parseAnnotationsIntoArray = NULL;
629         utf                      *utf_desc        = NULL;
630         java_handle_bytearray_t  *annotations     = NULL;
631         sun_reflect_ConstantPool *constantPool    = NULL;
632         uint32_t                  size            = 0;
633         java_lang_Object         *constantPoolOop = (java_lang_Object*)klass;
634
635         if (c == NULL) {
636                 exceptions_throw_nullpointerexception();
637                 return NULL;
638         }
639         
640         /* Return null for arrays and primitives: */
641         if (class_is_primitive(c) || class_is_array(c)) {
642                 return NULL;
643         }
644
645         if (c->annotations != NULL) {
646                 size        = c->annotations->size;
647                 annotations = builtin_newarray_byte(size);
648
649                 if(annotations != NULL) {
650                         MCOPY(annotations->data, c->annotations->data, uint8_t, size);
651                 }
652         }
653
654         constantPool = 
655                 (sun_reflect_ConstantPool*)native_new_and_init(
656                         class_sun_reflect_ConstantPool);
657         
658         if(constantPool == NULL) {
659                 /* out of memory */
660                 return NULL;
661         }
662
663         LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
664
665         /* only resolve the method the first time */
666         if (m_parseAnnotationsIntoArray == NULL) {
667                 utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
668                 utf_desc = utf_new_char(
669                         "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
670                         "[Ljava/lang/annotation/Annotation;");
671
672                 if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
673                         /* out of memory */
674                         return NULL;
675                 }
676
677                 m_parseAnnotationsIntoArray = class_resolveclassmethod(
678                         class_sun_reflect_annotation_AnnotationParser,
679                         utf_parseAnnotationsIntoArray,
680                         utf_desc,
681                         class_java_lang_Class,
682                         true);
683
684                 if (m_parseAnnotationsIntoArray == NULL) {
685                         /* method not found */
686                         return NULL;
687                 }
688         }
689
690         return (java_handle_objectarray_t*)vm_call_method(
691                 m_parseAnnotationsIntoArray, NULL,
692                 annotations, constantPool, klass);
693 }
694 #endif
695
696
697 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
698
699    Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
700    _Jv_java_lang_Class_getEnclosingMethod.
701
702 *******************************************************************************/
703
704 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
705 {
706         constant_nameandtype *cn;
707         classinfo            *ec;
708         methodinfo           *m;
709
710         /* get enclosing class and method */
711
712         ec = class_get_enclosingclass(c);
713         cn = c->enclosingmethod;
714
715         /* check for enclosing class and method */
716
717         if (ec == NULL)
718                 return NULL;
719
720         if (cn == NULL)
721                 return NULL;
722
723         /* find method in enclosing class */
724
725         m = class_findmethod(ec, cn->name, cn->descriptor);
726
727         if (m == NULL) {
728                 exceptions_throw_internalerror("Enclosing method doesn't exist");
729                 return NULL;
730         }
731
732         return m;
733 }
734
735
736 /*
737  * Class:     java/lang/Class
738  * Method:    getEnclosingConstructor
739  * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
740  */
741 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
742 {
743         classinfo                     *c;
744         methodinfo                    *m;
745         java_lang_reflect_Constructor *rc;
746
747         c = LLNI_classinfo_unwrap(klass);
748
749         /* get enclosing method */
750
751         m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
752
753         if (m == NULL)
754                 return NULL;
755
756         /* check for <init> */
757
758         if (m->name != utf_init)
759                 return NULL;
760
761         /* create Constructor object */
762
763         rc = reflect_constructor_new(m);
764
765         return rc;
766 }
767
768
769 /*
770  * Class:     java/lang/Class
771  * Method:    getEnclosingMethod
772  * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
773  */
774 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
775 {
776         classinfo                *c;
777         methodinfo               *m;
778         java_lang_reflect_Method *rm;
779
780         c = LLNI_classinfo_unwrap(klass);
781
782         /* get enclosing method */
783
784         m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
785
786         if (m == NULL)
787                 return NULL;
788
789         /* check for <init> */
790
791         if (m->name == utf_init)
792                 return NULL;
793
794         /* create java.lang.reflect.Method object */
795
796         rm = reflect_method_new(m);
797
798         return rm;
799 }
800
801
802 /*
803  * Class:     java/lang/Class
804  * Method:    getClassSignature
805  * Signature: (Ljava/lang/Class;)Ljava/lang/String;
806  */
807 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
808 {
809         classinfo     *c;
810         java_handle_t *o;
811
812         c = LLNI_classinfo_unwrap(klass);
813
814         if (c->signature == NULL)
815                 return NULL;
816
817         o = javastring_new(c->signature);
818
819         /* in error case o is NULL */
820
821         return (java_lang_String *) o;
822 }
823
824 #endif /* ENABLE_JAVASE */
825
826
827 /*
828  * These are local overrides for various environment variables in Emacs.
829  * Please do not remove this and leave it at the end of the file, where
830  * Emacs will automagically detect them.
831  * ---------------------------------------------------------------------
832  * Local variables:
833  * mode: c
834  * indent-tabs-mode: t
835  * c-basic-offset: 4
836  * tab-width: 4
837  * End:
838  * vim:noexpandtab:sw=4:ts=4:
839  */