1 /* src/vmcore/annotation.c - class annotations
3 Copyright (C) 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 #include "native/llni.h"
35 #include "vm/builtin.h"
36 #include "vm/primitive.hpp"
38 #include "mm/memory.h"
40 #include "toolbox/logging.h"
42 #include "vmcore/annotation.h"
43 #include "vmcore/class.h"
44 #include "vmcore/loader.h"
45 #include "vmcore/suck.h"
47 #if !defined(ENABLE_ANNOTATIONS)
48 # error annotation support has to be enabled when compling this file!
52 /* annotation_bytearrays_resize ***********************************************
54 Resize an array of bytearrays.
57 bytearrays.....array of bytearrays
58 size...........new size of the refered array
61 The new array if a resize was neccessarry, the old if the given size
62 equals the current size or NULL if an error occured.
64 *******************************************************************************/
66 static java_handle_objectarray_t *annotation_bytearrays_resize(
67 java_handle_objectarray_t *bytearrays, uint32_t size)
69 java_handle_objectarray_t *newbas = NULL; /* new array */
70 uint32_t minsize = 0; /* count of object refs to copy */
71 uint32_t oldsize = 0; /* size of old array */
73 if (bytearrays != NULL) {
74 oldsize = array_length_get((java_handle_t*)bytearrays);
76 /* if the size already fits do nothing */
77 if (size == oldsize) {
82 newbas = builtin_anewarray(size,
83 Primitive_get_arrayclass_by_type(PRIMITIVETYPE_BYTE));
85 /* is there a old byte array array? */
86 if (newbas != NULL && bytearrays != NULL) {
87 minsize = size < oldsize ? size : oldsize;
91 LLNI_array_data(newbas), LLNI_array_data(bytearrays),
92 java_object_t*, minsize);
100 /* annotation_bytearrays_insert ***********************************************
102 Insert a bytearray into an array of bytearrays.
105 bytearrays........array of bytearrays where 'bytearray' has to be
106 inserted at position 'index'.
107 index.............position where 'ba' has to be inserted into
109 bytearray.........byte array which has to be inserted into
113 The new array if a resize was neccessarry, the old if the given size
114 equals the current size or NULL if an error occured.
116 *******************************************************************************/
118 static java_handle_t *annotation_bytearrays_insert(
119 java_handle_t *bytearrays, uint32_t index,
120 java_handle_bytearray_t *bytearray)
122 java_handle_objectarray_t *bas; /* bytearrays */
123 uint32_t size = 0; /* current size of the array */
125 /* do nothing if NULL is inserted but no array exists */
126 if (bytearray == NULL && bytearrays == NULL) {
130 /* get lengths if array exists */
131 if (bytearrays != NULL) {
132 size = array_length_get(bytearrays);
135 bas = (java_handle_objectarray_t*)bytearrays;
137 if (bytearray == NULL) {
138 /* insert NULL only if array is big enough */
140 array_objectarray_element_set(bas, index, NULL);
144 /* resize array if it's not enough for inserted value */
146 bas = annotation_bytearrays_resize(bas, index + 1);
154 array_objectarray_element_set(bas, index, (java_handle_t*)bytearray);
157 return (java_handle_t*)bas;
161 /* annotation_load_attribute_body *********************************************
163 This function loads the body of a generic attribute.
165 XXX: Maybe this function should be called loader_load_attribute_body and
166 located in vmcore/loader.c?
169 u2 attribute_name_index;
171 u1 info[attribute_length];
175 cb.................classbuffer from which to read the data.
176 errormsg_prefix....prefix for error messages (if any).
179 attribute..........bytearray-pointer which will be set to the read data.
182 true if all went good. false otherwhise.
184 *******************************************************************************/
186 static bool annotation_load_attribute_body(classbuffer *cb,
187 java_handle_bytearray_t **attribute, const char *errormsg_prefix)
189 uint32_t size = 0; /* size of the attribute */
190 java_handle_bytearray_t *ba = NULL; /* the raw attributes' bytes */
193 assert(attribute != NULL);
195 if (!suck_check_classbuffer_size(cb, 4)) {
196 log_println("%s: size missing", errormsg_prefix);
200 /* load attribute_length */
203 if (!suck_check_classbuffer_size(cb, size)) {
204 log_println("%s: invalid size", errormsg_prefix);
208 /* if attribute_length == 0 then NULL is
209 * the right value for this attribute */
211 ba = builtin_newarray_byte(size);
221 suck_nbytes((uint8_t*)LLNI_array_data(ba), cb, size);
233 /* annotation_load_method_attribute_annotationdefault *************************
235 Load annotation default value.
237 AnnotationDefault_attribute {
238 u2 attribute_name_index;
240 element_value default_value;
244 cb.................classbuffer from which to read the data.
245 m..................methodinfo for the method of which the annotation
246 default value is read and into which the value is
250 true if all went good. false otherwhise.
252 *******************************************************************************/
254 bool annotation_load_method_attribute_annotationdefault(
255 classbuffer *cb, methodinfo *m)
258 /* the slot of the method */
259 java_handle_bytearray_t *annotationdefault = NULL;
260 /* unparsed annotation defalut value */
261 java_handle_t *annotationdefaults = NULL;
262 /* array of unparsed annotation default values */
267 LLNI_classinfo_field_get(
268 m->clazz, method_annotationdefaults, annotationdefaults);
270 if (!annotation_load_attribute_body(
271 cb, &annotationdefault,
272 "invalid annotation default method attribute")) {
276 if (annotationdefault != NULL) {
277 slot = m - m->clazz->methods;
278 annotationdefaults = annotation_bytearrays_insert(
279 annotationdefaults, slot, annotationdefault);
281 if (annotationdefaults == NULL) {
285 LLNI_classinfo_field_set(
286 m->clazz, method_annotationdefaults, annotationdefaults);
293 /* annotation_load_method_attribute_runtimevisibleparameterannotations ********
295 Load runtime visible parameter annotations.
297 RuntimeVisibleParameterAnnotations_attribute {
298 u2 attribute_name_index;
303 annotation annotations[num_annotations];
304 } parameter_annotations[num_parameters];
308 cb.................classbuffer from which to read the data.
309 m..................methodinfo for the method of which the parameter
310 annotations are read and into which the parameter
311 annotations are stored into.
314 true if all went good. false otherwhise.
316 *******************************************************************************/
318 bool annotation_load_method_attribute_runtimevisibleparameterannotations(
319 classbuffer *cb, methodinfo *m)
322 /* the slot of the method */
323 java_handle_bytearray_t *annotations = NULL;
324 /* unparsed parameter annotations */
325 java_handle_t *parameterannotations = NULL;
326 /* array of unparsed parameter annotations */
331 LLNI_classinfo_field_get(
332 m->clazz, method_parameterannotations, parameterannotations);
334 if (!annotation_load_attribute_body(
336 "invalid runtime visible parameter annotations method attribute")) {
340 if (annotations != NULL) {
341 slot = m - m->clazz->methods;
342 parameterannotations = annotation_bytearrays_insert(
343 parameterannotations, slot, annotations);
345 if (parameterannotations == NULL) {
349 LLNI_classinfo_field_set(
350 m->clazz, method_parameterannotations, parameterannotations);
357 /* annotation_load_method_attribute_runtimeinvisibleparameterannotations ******
359 Load runtime invisible parameter annotations.
361 <quote cite="http://jcp.org/en/jsr/detail?id=202">
362 The RuntimeInvisibleParameterAnnotations attribute is similar to the
363 RuntimeVisibleParameterAnnotations attribute, except that the annotations
364 represented by a RuntimeInvisibleParameterAnnotations attribute must not be
365 made available for return by reflective APIs, unless the the JVM has
366 specifically been instructed to retain these annotations via some
367 implementation-specific mechanism such as a command line flag. In the
368 absence of such instructions, the JVM ignores this attribute.
371 Hotspot loads them into the same bytearray as the runtime visible parameter
372 annotations (after the runtime visible parameter annotations). But in J2SE
373 the bytearray will only be parsed as if there is only one annotation
374 structure in it, so the runtime invisible parameter annotatios will be
377 Therefore I do not even bother to read them.
379 RuntimeInvisibleParameterAnnotations_attribute {
380 u2 attribute_name_index;
385 annotation annotations[num_annotations];
386 } parameter_annotations[num_parameters];
390 cb.................classbuffer from which to read the data.
391 m..................methodinfo for the method of which the parameter
392 annotations are read and into which the parameter
393 annotations are stored into.
396 true if all went good. false otherwhise.
398 *******************************************************************************/
400 bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
401 classbuffer *cb, methodinfo *m)
403 return loader_skip_attribute_body(cb);
407 /* annotation_load_class_attribute_runtimevisibleannotations ******************
409 Load runtime visible annotations of a class.
412 cb........the classbuffer from which the attribute has to be loaded.
415 true if all went good. false otherwhise.
417 *******************************************************************************/
419 bool annotation_load_class_attribute_runtimevisibleannotations(
422 java_handle_bytearray_t *annotations = NULL; /* unparsed annotations */
424 if (!annotation_load_attribute_body(
426 "invalid runtime visible annotations class attribute")) {
430 LLNI_classinfo_field_set(cb->clazz, annotations, (java_handle_t*)annotations);
436 /* annotation_load_class_attribute_runtimeinvisibleannotations ****************
438 Load runtime invisible annotations of a class (just skip them).
441 cb........the classbuffer from which the attribute has to be loaded.
444 true if all went good. false otherwhise.
446 *******************************************************************************/
448 bool annotation_load_class_attribute_runtimeinvisibleannotations(
451 return loader_skip_attribute_body(cb);
455 /* annotation_load_method_attribute_runtimevisibleannotations *****************
457 Load runtime visible annotations of a method.
460 cb........the classbuffer from which the attribute has to be loaded.
461 m.........the method of which the runtime visible annotations have
465 true if all went good. false otherwhise.
467 *******************************************************************************/
469 bool annotation_load_method_attribute_runtimevisibleannotations(
470 classbuffer *cb, methodinfo *m)
473 /* slot of the method */
474 java_handle_bytearray_t *annotations = NULL;
475 /* unparsed annotations */
476 java_handle_t *method_annotations = NULL;
477 /* array of unparsed method annotations */
482 LLNI_classinfo_field_get(
483 m->clazz, method_annotations, method_annotations);
485 if (!annotation_load_attribute_body(
487 "invalid runtime visible annotations method attribute")) {
491 if (annotations != NULL) {
492 slot = m - m->clazz->methods;
493 method_annotations = annotation_bytearrays_insert(
494 method_annotations, slot, annotations);
496 if (method_annotations == NULL) {
500 LLNI_classinfo_field_set(
501 m->clazz, method_annotations, method_annotations);
508 /* annotation_load_method_attribute_runtimeinvisibleannotations ****************
510 Load runtime invisible annotations of a method (just skip them).
513 cb........the classbuffer from which the attribute has to be loaded.
514 m.........the method of which the runtime invisible annotations have
518 true if all went good. false otherwhise.
520 *******************************************************************************/
522 bool annotation_load_method_attribute_runtimeinvisibleannotations(
523 classbuffer *cb, methodinfo *m)
525 return loader_skip_attribute_body(cb);
529 /* annotation_load_field_attribute_runtimevisibleannotations ******************
531 Load runtime visible annotations of a field.
534 cb........the classbuffer from which the attribute has to be loaded.
535 f.........the field of which the runtime visible annotations have
539 true if all went good. false otherwhise.
541 *******************************************************************************/
543 bool annotation_load_field_attribute_runtimevisibleannotations(
544 classbuffer *cb, fieldinfo *f)
547 /* slot of the field */
548 java_handle_bytearray_t *annotations = NULL;
549 /* unparsed annotations */
550 java_handle_t *field_annotations = NULL;
551 /* array of unparsed field annotations */
556 LLNI_classinfo_field_get(
557 f->clazz, field_annotations, field_annotations);
559 if (!annotation_load_attribute_body(
561 "invalid runtime visible annotations field attribute")) {
565 if (annotations != NULL) {
566 slot = f - f->clazz->fields;
567 field_annotations = annotation_bytearrays_insert(
568 field_annotations, slot, annotations);
570 if (field_annotations == NULL) {
574 LLNI_classinfo_field_set(
575 f->clazz, field_annotations, field_annotations);
582 /* annotation_load_field_attribute_runtimeinvisibleannotations ****************
584 Load runtime invisible annotations of a field (just skip them).
587 cb........the classbuffer from which the attribute has to be loaded.
588 f.........the field of which the runtime invisible annotations have
592 true if all went good. false otherwhise.
594 *******************************************************************************/
596 bool annotation_load_field_attribute_runtimeinvisibleannotations(
597 classbuffer *cb, fieldinfo *f)
599 return loader_skip_attribute_body(cb);
604 * These are local overrides for various environment variables in Emacs.
605 * Please do not remove this and leave it at the end of the file, where
606 * Emacs will automagically detect them.
607 * ---------------------------------------------------------------------
610 * indent-tabs-mode: t
614 * vim:noexpandtab:sw=4:ts=4: