1 /* src/vmcore/annotation.c - class annotations
3 Copyright (C) 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "mm/memory.h"
37 #include "toolbox/logging.h"
39 #include "vmcore/annotation.h"
40 #include "vmcore/class.h"
41 #include "vmcore/suck.h"
43 #if !defined(ENABLE_ANNOTATIONS)
44 # error annotation support has to be enabled when compling this file!
47 /* annotation_bytearray_new ***************************************************
49 Allocate a new bytearray.
51 *******************************************************************************/
53 annotation_bytearray_t *annotation_bytearray_new(uint32_t size)
55 annotation_bytearray_t *ba =
56 mem_alloc(sizeof(uint32_t) + sizeof(uint8_t) * size);
66 /* annotation_bytearray_free **************************************************
70 *******************************************************************************/
72 void annotation_bytearray_free(annotation_bytearray_t *ba)
75 mem_free(ba, sizeof(uint32_t) + sizeof(uint8_t) * ba->size);
80 /* annotation_bytearrays_new **************************************************
82 Allocate a new array of bytearrays.
84 *******************************************************************************/
86 annotation_bytearrays_t *annotation_bytearrays_new(uint32_t size)
88 annotation_bytearrays_t *bas =
89 mem_alloc(sizeof(uint32_t) + sizeof(annotation_bytearray_t*) * size);
99 /* annotation_bytearrays_resize ***********************************************
101 Resize an array of bytearrays.
103 *******************************************************************************/
105 bool annotation_bytearrays_resize(annotation_bytearrays_t **bas,
108 annotation_bytearrays_t *newbas = NULL;
114 newbas = annotation_bytearrays_new(size);
116 if (newbas == NULL) {
121 minsize = size < (*bas)->size ? size : (*bas)->size;
123 for (i = size; i < (*bas)->size; ++ i) {
124 annotation_bytearray_free((*bas)->data[i]);
127 for (i = 0; i < minsize; ++i) {
128 newbas->data[i] = (*bas)->data[i];
138 /* annotation_bytearrays_insert ***********************************************
140 Insert a bytearray into an array of bytearrays.
142 *******************************************************************************/
144 bool annotation_bytearrays_insert(annotation_bytearrays_t **bas,
145 uint32_t index, annotation_bytearray_t *ba)
150 if (*bas == NULL || (*bas)->size <= index) {
151 if (!annotation_bytearrays_resize(bas, index + 1)) {
156 /* free old bytearray (if any) */
157 annotation_bytearray_free((*bas)->data[index]);
160 /* insert new bytearray */
161 (*bas)->data[index] = ba;
163 else if (*bas != NULL && (*bas)->size > index) {
164 /* do not resize when just inserting NULL,
165 * but free old bytearray if there is any */
166 annotation_bytearray_free((*bas)->data[index]);
173 /* annotation_bytearrays_free *************************************************
175 Free an array of bytearrays.
177 *******************************************************************************/
179 void annotation_bytearrays_free(annotation_bytearrays_t *bas)
184 for (i = 0; i < bas->size; ++ i) {
185 annotation_bytearray_free(bas->data[i]);
188 mem_free(bas, sizeof(uint32_t) +
189 sizeof(annotation_bytearray_t*) * bas->size);
194 /* annotation_load_attribute_body *********************************************
196 This function loads the body of a generic attribute.
198 XXX: Maybe this function should be called loader_load_attribute_body and
199 located in vmcore/loader.c?
202 u2 attribute_name_index;
204 u1 info[attribute_length];
208 cb.................classbuffer from which to read the data.
209 errormsg_prefix....prefix for error messages (if any).
212 attribute..........bytearray-pointer which will be set to the read data.
215 true if all went good. false otherwhise.
217 *******************************************************************************/
219 static bool annotation_load_attribute_body(classbuffer *cb,
220 annotation_bytearray_t **attribute, const char *errormsg_prefix)
223 annotation_bytearray_t *ba = NULL;
226 assert(attribute != NULL);
228 if (!suck_check_classbuffer_size(cb, 4)) {
229 log_println("%s: size missing", errormsg_prefix);
233 /* load attribute_length */
236 if (!suck_check_classbuffer_size(cb, size)) {
237 log_println("%s: invalid size", errormsg_prefix);
241 /* if attribute_length == 0 then NULL is
242 * the right value for this attribute */
244 ba = annotation_bytearray_new(size);
252 suck_nbytes(ba->data, cb, size);
262 /* annotation_load_method_attribute_annotationdefault *************************
264 Load annotation default value.
266 AnnotationDefault_attribute {
267 u2 attribute_name_index;
269 element_value default_value;
273 cb.................classbuffer from which to read the data.
274 m..................methodinfo for the method of which the annotation
275 default value is read and into which the value is
279 true if all went good. false otherwhise.
281 *******************************************************************************/
283 bool annotation_load_method_attribute_annotationdefault(
284 classbuffer *cb, methodinfo *m)
287 annotation_bytearray_t *annotationdefault = NULL;
288 annotation_bytearrays_t **annotationdefaults = NULL;
293 annotationdefaults = &(m->class->method_annotationdefaults);
295 if (!annotation_load_attribute_body(
296 cb, &annotationdefault,
297 "invalid annotation default method attribute")) {
301 if (annotationdefault != NULL) {
302 slot = m - m->class->methods;
304 if (!annotation_bytearrays_insert(
305 annotationdefaults, slot, annotationdefault)) {
306 annotation_bytearray_free(annotationdefault);
315 /* annotation_load_method_attribute_runtimevisibleparameterannotations ********
317 Load runtime visible parameter annotations.
319 RuntimeVisibleParameterAnnotations_attribute {
320 u2 attribute_name_index;
325 annotation annotations[num_annotations];
326 } parameter_annotations[num_parameters];
330 cb.................classbuffer from which to read the data.
331 m..................methodinfo for the method of which the parameter
332 annotations are read and into which the parameter
333 annotations are stored into.
336 true if all went good. false otherwhise.
338 *******************************************************************************/
340 bool annotation_load_method_attribute_runtimevisibleparameterannotations(
341 classbuffer *cb, methodinfo *m)
344 annotation_bytearray_t *annotations = NULL;
345 annotation_bytearrays_t **parameterannotations = NULL;
350 parameterannotations = &(m->class->method_parameterannotations);
352 if (!annotation_load_attribute_body(
354 "invalid runtime visible parameter annotations method attribute")) {
358 if (annotations != NULL) {
359 slot = m - m->class->methods;
361 if (!annotation_bytearrays_insert(
362 parameterannotations, slot, annotations)) {
363 annotation_bytearray_free(annotations);
372 /* annotation_load_method_attribute_runtimeinvisibleparameterannotations ******
374 Load runtime invisible parameter annotations.
376 <quote cite="http://jcp.org/en/jsr/detail?id=202">
377 The RuntimeInvisibleParameterAnnotations attribute is similar to the
378 RuntimeVisibleParameterAnnotations attribute, except that the annotations
379 represented by a RuntimeInvisibleParameterAnnotations attribute must not be
380 made available for return by reflective APIs, unless the the JVM has
381 specifically been instructed to retain these annotations via some
382 implementation-specific mechanism such as a command line flag. In the
383 absence of such instructions, the JVM ignores this attribute.
386 Hotspot loads them into the same bytearray as the runtime visible parameter
387 annotations (after the runtime visible parameter annotations). But in J2SE
388 the bytearray will only be parsed as if ther is only one annotation
389 structure in it, so the runtime invisible parameter annotatios will be
392 Therefore I do not even bother to read them.
394 RuntimeInvisibleParameterAnnotations_attribute {
395 u2 attribute_name_index;
400 annotation annotations[num_annotations];
401 } parameter_annotations[num_parameters];
405 cb.................classbuffer from which to read the data.
406 m..................methodinfo for the method of which the parameter
407 annotations are read and into which the parameter
408 annotations are stored into.
411 true if all went good. false otherwhise.
413 *******************************************************************************/
415 bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
416 classbuffer *cb, methodinfo *m)
418 return loader_skip_attribute_body(cb);
422 /* annotation_load_class_attribute_runtimevisibleannotations ******************
424 Load runtime visible annotations of a class.
426 *******************************************************************************/
428 bool annotation_load_class_attribute_runtimevisibleannotations(
431 return annotation_load_attribute_body(
432 cb, &(cb->class->annotations),
433 "invalid runtime visible annotations class attribute");
437 /* annotation_load_class_attribute_runtimeinvisibleannotations ****************
439 Load runtime invisible annotations of a class (just skip them).
441 *******************************************************************************/
443 bool annotation_load_class_attribute_runtimeinvisibleannotations(
446 return loader_skip_attribute_body(cb);
450 /* annotation_load_method_attribute_runtimevisibleannotations *****************
452 Load runtime visible annotations of a method.
454 *******************************************************************************/
456 bool annotation_load_method_attribute_runtimevisibleannotations(
457 classbuffer *cb, methodinfo *m)
460 annotation_bytearray_t *annotations = NULL;
461 annotation_bytearrays_t **method_annotations = NULL;
466 method_annotations = &(m->class->method_annotations);
468 if (!annotation_load_attribute_body(
470 "invalid runtime visible annotations method attribute")) {
474 if (annotations != NULL) {
475 slot = m - m->class->methods;
477 if (!annotation_bytearrays_insert(
478 method_annotations, slot, annotations)) {
479 annotation_bytearray_free(annotations);
488 /* annotation_load_method_attribute_runtimeinvisibleannotations ****************
490 Load runtime invisible annotations of a method (just skip them).
492 *******************************************************************************/
494 bool annotation_load_method_attribute_runtimeinvisibleannotations(
495 classbuffer *cb, methodinfo *m)
497 return loader_skip_attribute_body(cb);
501 /* annotation_load_field_attribute_runtimevisibleannotations ******************
503 Load runtime visible annotations of a field.
505 *******************************************************************************/
507 bool annotation_load_field_attribute_runtimevisibleannotations(
508 classbuffer *cb, fieldinfo *f)
511 annotation_bytearray_t *annotations = NULL;
512 annotation_bytearrays_t **field_annotations = NULL;
517 field_annotations = &(f->class->field_annotations);
519 if (!annotation_load_attribute_body(
521 "invalid runtime visible annotations field attribute")) {
525 if (annotations != NULL) {
526 slot = f - f->class->fields;
528 if (!annotation_bytearrays_insert(
529 field_annotations, slot, annotations)) {
530 annotation_bytearray_free(annotations);
539 /* annotation_load_field_attribute_runtimeinvisibleannotations ****************
541 Load runtime invisible annotations of a field (just skip them).
543 *******************************************************************************/
545 bool annotation_load_field_attribute_runtimeinvisibleannotations(
546 classbuffer *cb, fieldinfo *f)
548 return loader_skip_attribute_body(cb);
553 * These are local overrides for various environment variables in Emacs.
554 * Please do not remove this and leave it at the end of the file, where
555 * Emacs will automagically detect them.
556 * ---------------------------------------------------------------------
559 * indent-tabs-mode: t
563 * vim:noexpandtab:sw=4:ts=4: