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