diff --git a/BUGS b/BUGS new file mode 100644 index 00000000..b6bdc3f4 --- /dev/null +++ b/BUGS @@ -0,0 +1,4 @@ +Known Bugs +========== + +- Annotation element values are not parsed. diff --git a/Makefile b/Makefile index d85906d8..27e47713 100644 --- a/Makefile +++ b/Makefile @@ -60,6 +60,7 @@ include sys/$(SYS)-$(ARCH)/Makefile OBJS += $(ARCH_OBJS) OBJS += $(SYS_OBJS) +OBJS += cafebabe/annotations_attribute.o OBJS += cafebabe/attribute_array.o OBJS += cafebabe/attribute_info.o OBJS += cafebabe/class.o @@ -138,6 +139,7 @@ OBJS += runtime/reflection.o OBJS += runtime/runtime.o OBJS += runtime/stack-walker.o OBJS += runtime/unsafe.o +OBJS += vm/annotation.o OBJS += vm/boehm-gc.o OBJS += vm/bytecode.o OBJS += vm/call.o diff --git a/cafebabe/annotations_attribute.c b/cafebabe/annotations_attribute.c new file mode 100644 index 00000000..d26286d3 --- /dev/null +++ b/cafebabe/annotations_attribute.c @@ -0,0 +1,229 @@ +/* + * cafebabe - the class loader library in C + * Copyright (C) 2010 Pekka Enberg + * + * This file is released under the GPL version 2 with the following + * clarification and special exception: + * + * Linking this library statically or dynamically with other modules is + * making a combined work based on this library. Thus, the terms and + * conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give you + * permission to link this library with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under terms + * of your choice, provided that you also meet, for each linked independent + * module, the terms and conditions of the license of that module. An + * independent module is a module which is not derived from or based on + * this library. If you modify this library, you may extend this exception + * to your version of the library, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + * Please refer to the file LICENSE for details. + */ + +#include "cafebabe/annotations_attribute.h" + +#include +#include + +#include "cafebabe/attribute_info.h" +#include "cafebabe/stream.h" +#include "cafebabe/class.h" + +#include "vm/die.h" + +#define ELEMENT_TYPE_BYTE 'B' +#define ELEMENT_TYPE_CHAR 'C' +#define ELEMENT_TYPE_DOUBLE 'D' +#define ELEMENT_TYPE_FLOAT 'F' +#define ELEMENT_TYPE_INTEGER 'I' +#define ELEMENT_TYPE_LONG 'J' +#define ELEMENT_TYPE_SHORT 'S' +#define ELEMENT_TYPE_BOOLEAN 'Z' +#define ELEMENT_TYPE_STRING 's' +#define ELEMENT_TYPE_ENUM_CONSTANT 'e' +#define ELEMENT_TYPE_CLASS 'c' +#define ELEMENT_TYPE_ANNOTATION_TYPE '@' +#define ELEMENT_TYPE_ARRAY '[' + +static int cafebabe_annotation_parse(struct cafebabe_annotation *a, struct cafebabe_stream *s); + +static int +cafebabe_element_value_parse(struct cafebabe_element_value *v, struct cafebabe_stream *s) +{ + int err; + + err = cafebabe_stream_read_uint8(s, &v->tag); + if (err) + goto out; + + switch (v->tag) { + case ELEMENT_TYPE_BYTE: + case ELEMENT_TYPE_CHAR: + case ELEMENT_TYPE_DOUBLE: + case ELEMENT_TYPE_FLOAT: + case ELEMENT_TYPE_INTEGER: + case ELEMENT_TYPE_LONG: + case ELEMENT_TYPE_SHORT: + case ELEMENT_TYPE_BOOLEAN: + case ELEMENT_TYPE_STRING: { + err = cafebabe_stream_read_uint16(s, &v->value.const_value); + if (err) + goto out; + break; + } + case ELEMENT_TYPE_ENUM_CONSTANT: { + err = cafebabe_stream_read_uint16(s, &v->value.enum_const_value.type_name_index); + if (err) + goto out; + + err = cafebabe_stream_read_uint16(s, &v->value.enum_const_value.const_name_index); + if (err) + goto out; + break; + } + case ELEMENT_TYPE_CLASS: { + err = cafebabe_stream_read_uint16(s, &v->value.class_info_index); + if (err) + goto out; + break; + } + case ELEMENT_TYPE_ANNOTATION_TYPE: { + struct cafebabe_annotation unused; /* XXX */ + + err = cafebabe_annotation_parse(&unused, s); + if (err) + goto out; + break; + } + case ELEMENT_TYPE_ARRAY: { + err = cafebabe_stream_read_uint16(s, &v->value.array_value.num_values); + if (err) + goto out; + + for (unsigned int i = 0; i < v->value.array_value.num_values; i++) { + struct cafebabe_element_value unused; /* XXX */ + + err = cafebabe_element_value_parse(&unused, s); + if (err) + goto out; + } + break; + } + default: + warn("unknown annotation element type %d", v->tag); + err = -1; + goto out; + }; +out: + return err; +} + +static int +cafebabe_element_value_pair_parse(struct cafebabe_element_value_pair *p, struct cafebabe_stream *s) +{ + int err; + + err = cafebabe_stream_read_uint16(s, &p->element_name_index); + if (err) + goto out; + + err = cafebabe_element_value_parse(&p->value, s); +out: + return err; +} + +static int +cafebabe_annotation_parse(struct cafebabe_annotation *a, struct cafebabe_stream *s) +{ + int err; + + err = cafebabe_stream_read_uint16(s, &a->type_index); + if (err) + goto out; + + err = cafebabe_stream_read_uint16(s, &a->num_element_value_pairs); + if (err) + goto out; + + a->element_value_pairs = calloc(a->num_element_value_pairs, sizeof(struct cafebabe_element_value_pair)); + if (!a->element_value_pairs) { + err = -1; + goto out; + } + for (unsigned int i = 0; i < a->num_element_value_pairs; i++) { + err = cafebabe_element_value_pair_parse(&a->element_value_pairs[i], s); + if (!err) + goto out; + } +out: + return err; +} + +int +cafebabe_annotations_attribute_init(struct cafebabe_annotations_attribute *a, struct cafebabe_stream *s) +{ + int err = 0; + + err = cafebabe_stream_read_uint16(s, &a->num_annotations); + if (err) + goto out; + + a->annotations = calloc(a->num_annotations, sizeof(struct cafebabe_annotation)); + if (!a->annotations) { + err = -1; + goto out; + } + for (unsigned int i = 0; i < a->num_annotations; i++) { + err = cafebabe_annotation_parse(&a->annotations[i], s); + if (err) + goto out; + } +out: + return err; +} + +static void +cafebabe_annotation_free(struct cafebabe_annotation *a) +{ + free(a->element_value_pairs); +} + +void +cafebabe_annotations_attribute_deinit(struct cafebabe_annotations_attribute *a) +{ + for (unsigned int i = 0; i < a->num_annotations; i++) + cafebabe_annotation_free(&a->annotations[i]); + + free(a->annotations); +} + +int +cafebabe_read_annotations_attribute(const struct cafebabe_class *class, + const struct cafebabe_attribute_array *attributes, + struct cafebabe_annotations_attribute *annotations_attrib) +{ + const struct cafebabe_attribute_info *attribute; + unsigned int annotations_index = 0; + struct cafebabe_stream stream; + int err; + + memset(annotations_attrib, 0, sizeof(*annotations_attrib)); + + if (cafebabe_attribute_array_get(attributes, "RuntimeVisibleAnnotations", class, &annotations_index)) + return 0; + + attribute = &class->attributes.array[annotations_index]; + + cafebabe_stream_open_buffer(&stream, attribute->info, attribute->attribute_length); + + err = cafebabe_annotations_attribute_init(annotations_attrib, &stream); + + cafebabe_stream_close_buffer(&stream); + + return err; +} diff --git a/include/cafebabe/annotation.h b/include/cafebabe/annotation.h new file mode 100644 index 00000000..89537f69 --- /dev/null +++ b/include/cafebabe/annotation.h @@ -0,0 +1,66 @@ +/* + * cafebabe - the class loader library in C + * Copyright (C) 2010 Pekka Enberg + * + * This file is released under the GPL version 2 with the following + * clarification and special exception: + * + * Linking this library statically or dynamically with other modules is + * making a combined work based on this library. Thus, the terms and + * conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give you + * permission to link this library with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under terms + * of your choice, provided that you also meet, for each linked independent + * module, the terms and conditions of the license of that module. An + * independent module is a module which is not derived from or based on + * this library. If you modify this library, you may extend this exception + * to your version of the library, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + * Please refer to the file LICENSE for details. + */ + +#ifndef CAFEBABE__ANNOTATION_H +#define CAFEBABE__ANNOTATION_H + +#include + +#include "cafebabe/attribute_array.h" +#include "cafebabe/attribute_info.h" + +struct cafebabe_annotation; + +struct cafebabe_element_value { + uint8_t tag; + union { + uint16_t const_value; + struct { + uint16_t type_name_index; + uint16_t const_name_index; + } enum_const_value; + uint16_t class_info_index; + struct cafebabe_annotation *annotation_value; + struct { + uint16_t num_values; + struct cafebabe_element_value *values; + } array_value; + } value; +}; + +struct cafebabe_element_value_pair { + uint16_t element_name_index; + struct cafebabe_element_value value; +}; + +struct cafebabe_annotation { + uint16_t type_index; + uint16_t num_element_value_pairs; + struct cafebabe_element_value_pair *element_value_pairs; +}; + +#endif diff --git a/include/cafebabe/annotations_attribute.h b/include/cafebabe/annotations_attribute.h new file mode 100644 index 00000000..4f8ba4df --- /dev/null +++ b/include/cafebabe/annotations_attribute.h @@ -0,0 +1,49 @@ +/* + * cafebabe - the class loader library in C + * Copyright (C) 2010 Pekka Enberg + * + * This file is released under the GPL version 2 with the following + * clarification and special exception: + * + * Linking this library statically or dynamically with other modules is + * making a combined work based on this library. Thus, the terms and + * conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give you + * permission to link this library with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under terms + * of your choice, provided that you also meet, for each linked independent + * module, the terms and conditions of the license of that module. An + * independent module is a module which is not derived from or based on + * this library. If you modify this library, you may extend this exception + * to your version of the library, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + * Please refer to the file LICENSE for details. + */ + +#ifndef CAFEBABE__ANNOTATIONS_ATTRIBUTE_H +#define CAFEBABE__ANNOTATIONS_ATTRIBUTE_H + +#include + +#include "cafebabe/annotation.h" + +/* + * The RuntimeVisibleAnnotations and RuntimeInvisibleAnnotations attributes. + * + * See section 4.8.15 and 4.8.16 of The Java Virtual Machine Specification for details. + */ +struct cafebabe_annotations_attribute { + uint16_t num_annotations; + struct cafebabe_annotation *annotations; +}; + +int cafebabe_annotations_attribute_init(struct cafebabe_annotations_attribute *a, struct cafebabe_stream *s); +void cafebabe_annotations_attribute_deinit(struct cafebabe_annotations_attribute *a); +int cafebabe_read_annotations_attribute(const struct cafebabe_class *class, const struct cafebabe_attribute_array *attributes, struct cafebabe_annotations_attribute *annotations_attrib); + +#endif diff --git a/include/cafebabe/class.h b/include/cafebabe/class.h index 046e057a..7ef46d59 100644 --- a/include/cafebabe/class.h +++ b/include/cafebabe/class.h @@ -52,6 +52,7 @@ struct cafebabe_stream; #define CAFEBABE_CLASS_ACC_SUPER 0x0020 #define CAFEBABE_CLASS_ACC_INTERFACE 0x0200 #define CAFEBABE_CLASS_ACC_ABSTRACT 0x0400 +#define CAFEBABE_CLASS_ACC_ANNOTATION 0x4000 /** * A java class file. diff --git a/include/runtime/java_lang_VMClass.h b/include/runtime/java_lang_VMClass.h index 8249ea2d..a6e53563 100644 --- a/include/runtime/java_lang_VMClass.h +++ b/include/runtime/java_lang_VMClass.h @@ -6,6 +6,7 @@ jobject java_lang_VMClass_forName(jobject name, jboolean initialize, jobject loader); jobject java_lang_VMClass_getClassLoader(jobject object); jobject java_lang_VMClass_getComponentType(jobject object); +jobject java_lang_VMClass_getDeclaredAnnotations(jobject klass); jobject java_lang_VMClass_getDeclaredConstructors(jobject class_object, jboolean public_only); jobject java_lang_VMClass_getDeclaredFields(jobject class_object, jboolean public_only); jobject java_lang_VMClass_getDeclaredMethods(jobject class_object, jboolean public_only); diff --git a/include/vm/annotation.h b/include/vm/annotation.h new file mode 100644 index 00000000..40fa32ed --- /dev/null +++ b/include/vm/annotation.h @@ -0,0 +1,21 @@ +#ifndef JATO__VM_ANNOTATION_H +#define JATO__VM_ANNOTATION_H + +struct cafebabe_annotation; +struct cafebabe_class; + +struct vm_element_value_pair { + const char *name; + struct vm_object *value; +}; + +struct vm_annotation { + char *type; + unsigned long nr_elements; + struct vm_element_value_pair elements[]; +}; + +struct vm_annotation *vm_annotation_parse(const struct cafebabe_class *klass, struct cafebabe_annotation *annotation); +void vm_annotation_free(struct vm_annotation *vma); + +#endif /* JATO__VM_ANNOTATION_H */ diff --git a/include/vm/class.h b/include/vm/class.h index bdc932b3..efe0823a 100644 --- a/include/vm/class.h +++ b/include/vm/class.h @@ -18,6 +18,7 @@ struct vm_object; struct vm_thread; +struct vm_annotation; enum vm_class_state { VM_CLASS_LOADED, @@ -51,6 +52,8 @@ struct vm_class { struct vm_field *fields; unsigned int nr_methods; struct vm_method *methods; + unsigned int nr_annotations; + struct vm_annotation **annotations; unsigned int object_size; unsigned int static_size; diff --git a/include/vm/preload.h b/include/vm/preload.h index e60d4fb2..9eef87ac 100644 --- a/include/vm/preload.h +++ b/include/vm/preload.h @@ -6,6 +6,7 @@ extern struct vm_class *vm_array_of_java_lang_Class; extern struct vm_class *vm_array_of_java_lang_StackTraceElement; extern struct vm_class *vm_array_of_java_lang_String; +extern struct vm_class *vm_array_of_java_lang_annotation_Annotation; extern struct vm_class *vm_array_of_java_lang_reflect_Constructor; extern struct vm_class *vm_array_of_java_lang_reflect_Field; extern struct vm_class *vm_array_of_java_lang_reflect_Method; @@ -160,6 +161,7 @@ extern struct vm_method *vm_java_lang_Number_doubleValue; extern struct vm_method *vm_java_lang_ref_Reference_clear; extern struct vm_method *vm_java_lang_ref_Reference_enqueue; extern struct vm_method *vm_java_nio_DirectByteBufferImpl_ReadWrite_init; +extern struct vm_method *vm_sun_reflect_annotation_AnnotationInvocationHandler_create; extern bool preload_finished; diff --git a/regression/java/lang/VMClassTest.java b/regression/java/lang/VMClassTest.java index ab748e13..b7cd73b0 100644 --- a/regression/java/lang/VMClassTest.java +++ b/regression/java/lang/VMClassTest.java @@ -31,6 +31,10 @@ * @author Pekka Enberg */ public class VMClassTest extends TestCase { + public static void testGetDeclaredAnnotations() { + assertEquals(0, VMClass.getDeclaredAnnotations(Object.class).length); + } + public static void testIsAnonymousClass() { assertFalse(VMClass.isAnonymousClass(int.class)); assertFalse(VMClass.isAnonymousClass(int[].class)); @@ -56,6 +60,7 @@ public static void testIsPrimitive() { } public static void main(String[] args) { + testGetDeclaredAnnotations(); testIsAnonymousClass(); testIsArray(); testIsPrimitive(); diff --git a/runtime/java_lang_VMClass.c b/runtime/java_lang_VMClass.c index 80f85825..1c0079c6 100644 --- a/runtime/java_lang_VMClass.c +++ b/runtime/java_lang_VMClass.c @@ -29,11 +29,13 @@ #include "jit/exception.h" #include "vm/classloader.h" +#include "vm/annotation.h" #include "vm/reflection.h" #include "vm/preload.h" #include "vm/errors.h" #include "vm/object.h" #include "vm/class.h" +#include "vm/call.h" #include "vm/utf8.h" #include "vm/vm.h" @@ -95,6 +97,52 @@ struct vm_object *java_lang_VMClass_getComponentType(struct vm_object *object) return vm_class_get_array_element_class(class)->object; } +/* XXX */ +static struct vm_object *get_system_class_loader(void) +{ + if (vm_class_ensure_init(vm_java_lang_ClassLoader)) + return NULL; + + return vm_call_method_object(vm_java_lang_ClassLoader_getSystemClassLoader); +} + +jobject java_lang_VMClass_getDeclaredAnnotations(jobject klass) +{ + struct vm_object *result; + struct vm_class *vmc; + unsigned int i; + + vmc = vm_object_to_vm_class(klass); + if (!vmc) + return rethrow_exception(); + + result = vm_object_alloc_array(vm_array_of_java_lang_annotation_Annotation, vmc->nr_annotations); + if (!result) + return rethrow_exception(); + + for (i = 0; i < vmc->nr_annotations; i++) { + struct vm_annotation *vma = vmc->annotations[i]; + struct vm_object *annotation; + struct vm_type_info type; + struct vm_class *klass; + + if (parse_type(&vma->type, &type)) + return NULL; + + klass = classloader_load(get_system_class_loader(), type.class_name); + if (!klass) + return rethrow_exception(); + + annotation = vm_call_method_object(vm_sun_reflect_annotation_AnnotationInvocationHandler_create, klass->object, NULL); + if (!annotation) + return rethrow_exception(); /* XXX */ + + array_set_field_object(result, i, annotation); + } + + return result; +} + jobject java_lang_VMClass_getDeclaredConstructors(jobject clazz, jboolean public_only) { struct vm_class *vmc; diff --git a/vm/annotation.c b/vm/annotation.c new file mode 100644 index 00000000..cb3bfe20 --- /dev/null +++ b/vm/annotation.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010 Pekka Enberg + * + * This file is released under the GPL version 2 with the following + * clarification and special exception: + * + * Linking this library statically or dynamically with other modules is + * making a combined work based on this library. Thus, the terms and + * conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give you + * permission to link this library with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under terms + * of your choice, provided that you also meet, for each linked independent + * module, the terms and conditions of the license of that module. An + * independent module is a module which is not derived from or based on + * this library. If you modify this library, you may extend this exception + * to your version of the library, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + * Please refer to the file LICENSE for details. + */ + +#include "vm/annotation.h" + +#include +#include + +#include "cafebabe/annotation.h" +#include "cafebabe/class.h" +#include "vm/gc.h" + +struct vm_annotation *vm_annotation_parse(const struct cafebabe_class *klass, struct cafebabe_annotation *annotation) +{ + const struct cafebabe_constant_info_utf8 *type; + struct vm_annotation *vma; + + if (cafebabe_class_constant_get_utf8(klass, annotation->type_index, &type)) + return NULL; + + vma = calloc(1, sizeof *vma); + if (!vma) + return NULL; + + vma->type = strndup((char *) type->bytes, type->length); + if (!vma->type) + goto out_free; + + return vma; +out_free: + free(vma); + + return NULL; +} + +void vm_annotation_free(struct vm_annotation *vma) +{ + free(vma->type); +} diff --git a/vm/class.c b/vm/class.c index 1479de58..80712387 100644 --- a/vm/class.c +++ b/vm/class.c @@ -28,6 +28,7 @@ #include "vm/class.h" #include "cafebabe/inner_classes_attribute.h" +#include "cafebabe/annotations_attribute.h" #include "cafebabe/constant_pool.h" #include "cafebabe/method_info.h" #include "cafebabe/field_info.h" @@ -40,6 +41,7 @@ #include "vm/fault-inject.h" #include "vm/classloader.h" +#include "vm/annotation.h" #include "vm/gc.h" #include "vm/preload.h" #include "vm/errors.h" @@ -495,9 +497,38 @@ int vm_class_link(struct vm_class *vmc, const struct cafebabe_class *class) } } + struct cafebabe_annotations_attribute annotations_attribute; + + if (cafebabe_read_annotations_attribute(class, &class->attributes, &annotations_attribute)) + goto error_free_methods; + + vmc->annotations = vm_alloc(sizeof(struct vm_annotation *) * annotations_attribute.num_annotations); + if (!vmc->annotations) + goto error_free_methods; + + for (unsigned int i = 0; i < annotations_attribute.num_annotations; i++) { + struct cafebabe_annotation *annotation = &annotations_attribute.annotations[i]; + struct vm_annotation *vma; + + vma = vm_annotation_parse(class, annotation); + if (!vma) + goto error_free_annotations; + + vmc->annotations[vmc->nr_annotations++] = vma; + } + + cafebabe_annotations_attribute_deinit(&annotations_attribute); + vmc->state = VM_CLASS_LINKED; return 0; +error_free_annotations: + for (unsigned int i = 0; i < vmc->nr_annotations; i++) { + struct vm_annotation *vma = vmc->annotations[i]; + + vm_annotation_free(vma); + } + free(vmc->annotations); error_free_methods: vm_free(vmc->methods); error_free_static_values: diff --git a/vm/jato.c b/vm/jato.c index 053e297c..f3c0bc18 100644 --- a/vm/jato.c +++ b/vm/jato.c @@ -424,6 +424,7 @@ static struct vm_native natives[] = { DEFINE_NATIVE("java/lang/VMClass", "forName", java_lang_VMClass_forName), DEFINE_NATIVE("java/lang/VMClass", "getClassLoader", java_lang_VMClass_getClassLoader), DEFINE_NATIVE("java/lang/VMClass", "getComponentType", java_lang_VMClass_getComponentType), + DEFINE_NATIVE("java/lang/VMClass", "getDeclaredAnnotations", java_lang_VMClass_getDeclaredAnnotations), DEFINE_NATIVE("java/lang/VMClass", "getDeclaredConstructors", java_lang_VMClass_getDeclaredConstructors), DEFINE_NATIVE("java/lang/VMClass", "getDeclaredFields", java_lang_VMClass_getDeclaredFields), DEFINE_NATIVE("java/lang/VMClass", "getDeclaredMethods", java_lang_VMClass_getDeclaredMethods), @@ -1090,7 +1091,7 @@ main(int argc, char *argv[]) } if (preload_vm_classes()) { - NOT_IMPLEMENTED; + fprintf(stderr, "Unable to preload system classes\n"); exit(EXIT_FAILURE); } diff --git a/vm/preload.c b/vm/preload.c index c2a7661c..6984d3bc 100644 --- a/vm/preload.c +++ b/vm/preload.c @@ -79,6 +79,7 @@ struct vm_class *vm_java_lang_InheritableThreadLocal; struct vm_class *vm_java_lang_VMThread; struct vm_class *vm_java_lang_IllegalMonitorStateException; struct vm_class *vm_java_lang_System; +struct vm_class *vm_array_of_java_lang_annotation_Annotation; struct vm_class *vm_java_lang_reflect_Constructor; struct vm_class *vm_java_lang_reflect_Field; struct vm_class *vm_java_lang_reflect_Method; @@ -110,6 +111,7 @@ struct vm_class *vm_java_lang_ref_PhantomReference; struct vm_class *vm_java_nio_Buffer; struct vm_class *vm_java_nio_DirectByteBufferImpl_ReadWrite; struct vm_class *vm_gnu_classpath_PointerNN; +struct vm_class *vm_sun_reflect_annotation_AnnotationInvocationHandler; struct vm_class *vm_boolean_class; struct vm_class *vm_char_class; struct vm_class *vm_float_class; @@ -154,6 +156,7 @@ static const struct preload_entry preload_entries[] = { { "java/lang/InheritableThreadLocal", &vm_java_lang_InheritableThreadLocal }, { "java/lang/IllegalMonitorStateException", &vm_java_lang_IllegalMonitorStateException }, { "java/lang/System", &vm_java_lang_System }, + { "[Ljava/lang/annotation/Annotation;", &vm_array_of_java_lang_annotation_Annotation }, { "java/lang/reflect/Field", &vm_java_lang_reflect_Field }, { "java/lang/reflect/VMField", &vm_java_lang_reflect_VMField, PRELOAD_OPTIONAL }, /* Classpath 0.98 */ { "java/lang/reflect/Constructor", &vm_java_lang_reflect_Constructor }, @@ -189,6 +192,7 @@ static const struct preload_entry preload_entries[] = { #else { "gnu/classpath/Pointer64", &vm_gnu_classpath_PointerNN }, #endif + { "sun/reflect/annotation/AnnotationInvocationHandler", &vm_sun_reflect_annotation_AnnotationInvocationHandler }, }; static const struct preload_entry primitive_preload_entries[] = { @@ -373,6 +377,7 @@ struct vm_method *vm_java_lang_Number_doubleValue; struct vm_method *vm_java_lang_ref_Reference_clear; struct vm_method *vm_java_lang_ref_Reference_enqueue; struct vm_method *vm_java_nio_DirectByteBufferImpl_ReadWrite_init; +struct vm_method *vm_sun_reflect_annotation_AnnotationInvocationHandler_create; static const struct method_preload_entry method_preload_entries[] = { { @@ -651,6 +656,12 @@ static const struct method_preload_entry method_preload_entries[] = { "(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V", &vm_java_nio_DirectByteBufferImpl_ReadWrite_init, }, + { + &vm_sun_reflect_annotation_AnnotationInvocationHandler, + "create", + "(Ljava/lang/Class;Ljava/util/Map;)Ljava/lang/annotation/Annotation;", + &vm_sun_reflect_annotation_AnnotationInvocationHandler_create, + }, }; /*