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
33 #include "mm/memory.h"
35 #include "toolbox/logging.h"
37 #include "vmcore/annotation.h"
38 #include "vmcore/class.h"
39 #include "vmcore/suck.h"
41 #if !defined(ENABLE_ANNOTATIONS)
42 # error annotation support has to be enabled when compling this file!
45 /* annotation_bytearray_new ***************************************************
47 Allocate a new bytearray.
49 *******************************************************************************/
51 annotation_bytearray_t *annotation_bytearray_new(uint32_t size)
53 annotation_bytearray_t *ba =
54 mem_alloc(sizeof(uint32_t) + sizeof(uint8_t) * size);
64 /* annotation_bytearray_free **************************************************
68 *******************************************************************************/
70 void annotation_bytearray_free(annotation_bytearray_t *ba)
73 mem_free(ba, sizeof(uint32_t) + sizeof(uint8_t) * ba->size);
78 /* annotation_bytearrays_new **************************************************
80 Allocate a new array of bytearrays.
82 *******************************************************************************/
84 annotation_bytearrays_t *annotation_bytearrays_new(uint32_t size)
86 annotation_bytearrays_t *bas =
87 mem_alloc(sizeof(uint32_t) + sizeof(annotation_bytearray_t*) * size);
97 /* annotation_bytearrays_resize ***********************************************
99 Resize an array of bytearrays.
101 *******************************************************************************/
103 bool annotation_bytearrays_resize(annotation_bytearrays_t **bas,
106 annotation_bytearrays_t *newbas = NULL;
112 newbas = annotation_bytearrays_new(size);
114 if (newbas == NULL) {
119 minsize = size < (*bas)->size ? size : (*bas)->size;
121 for (i = size; i < (*bas)->size; ++ i) {
122 annotation_bytearray_free((*bas)->data[i]);
125 for (i = 0; i < minsize; ++i) {
126 newbas->data[i] = (*bas)->data[i];
136 /* annotation_bytearrays_insert ***********************************************
138 Insert a bytearray into an array of bytearrays.
140 *******************************************************************************/
142 bool annotation_bytearrays_insert(annotation_bytearrays_t **bas,
143 uint32_t index, annotation_bytearray_t *ba)
148 if (*bas == NULL || (*bas)->size <= index) {
149 if (!annotation_bytearrays_resize(bas, index + 1)) {
154 /* free old bytearray (if any) */
155 annotation_bytearray_free((*bas)->data[index]);
158 /* insert new bytearray */
159 (*bas)->data[index] = ba;
161 else if (*bas != NULL && (*bas)->size > index) {
162 /* do not resize when just inserting NULL,
163 * but free old bytearray if there is any */
164 annotation_bytearray_free((*bas)->data[index]);
171 /* annotation_bytearrays_free *************************************************
173 Free an array of bytearrays.
175 *******************************************************************************/
177 void annotation_bytearrays_free(annotation_bytearrays_t *bas)
182 for (i = 0; i < bas->size; ++ i) {
183 annotation_bytearray_free(bas->data[i]);
186 mem_free(bas, sizeof(uint32_t) +
187 sizeof(annotation_bytearray_t*) * bas->size);
192 /* annotation_load_attribute_body *********************************************
194 This function loads the body of a generic attribute.
196 XXX: Maybe this function should be called loader_load_attribute_body and
197 located in vmcore/loader.c?
200 u2 attribute_name_index;
202 u1 info[attribute_length];
206 cb.................classbuffer from which to read the data.
207 errormsg_prefix....prefix for error messages (if any).
210 attribute..........bytearray-pointer which will be set to the read data.
213 true if all went good. false otherwhise.
215 *******************************************************************************/
217 static bool annotation_load_attribute_body(classbuffer *cb,
218 annotation_bytearray_t **attribute, const char *errormsg_prefix)
221 annotation_bytearray_t *ba = NULL;
224 assert(attribute != NULL);
226 if (!suck_check_classbuffer_size(cb, 4)) {
227 log_println("%s: size missing", errormsg_prefix);
231 /* load attribute_length */
234 if (!suck_check_classbuffer_size(cb, size)) {
235 log_println("%s: invalid size", errormsg_prefix);
239 /* if attribute_length == 0 then NULL is
240 * the right value for this attribute */
242 ba = annotation_bytearray_new(size);
250 suck_nbytes(ba->data, cb, size);
260 /* annotation_load_method_attribute_annotationdefault *************************
262 Load annotation default value.
264 AnnotationDefault_attribute {
265 u2 attribute_name_index;
267 element_value default_value;
271 cb.................classbuffer from which to read the data.
272 m..................methodinfo for the method of which the annotation
273 default value is read and into which the value is
277 true if all went good. false otherwhise.
279 *******************************************************************************/
281 bool annotation_load_method_attribute_annotationdefault(
282 classbuffer *cb, methodinfo *m)
285 annotation_bytearray_t *annotationdefault = NULL;
286 annotation_bytearrays_t **annotationdefaults = NULL;
291 annotationdefaults = &(m->class->method_annotationdefaults);
293 if (!annotation_load_attribute_body(
294 cb, &annotationdefault,
295 "invalid annotation default method attribute")) {
299 if (annotationdefault != NULL) {
300 slot = m - m->class->methods;
302 if (!annotation_bytearrays_insert(
303 annotationdefaults, slot, annotationdefault)) {
304 annotation_bytearray_free(annotationdefault);
313 /* annotation_load_method_attribute_runtimevisibleparameterannotations ********
315 Load runtime visible parameter annotations.
317 RuntimeVisibleParameterAnnotations_attribute {
318 u2 attribute_name_index;
323 annotation annotations[num_annotations];
324 } parameter_annotations[num_parameters];
328 cb.................classbuffer from which to read the data.
329 m..................methodinfo for the method of which the parameter
330 annotations are read and into which the parameter
331 annotations are stored into.
334 true if all went good. false otherwhise.
336 *******************************************************************************/
338 bool annotation_load_method_attribute_runtimevisibleparameterannotations(
339 classbuffer *cb, methodinfo *m)
342 annotation_bytearray_t *annotations = NULL;
343 annotation_bytearrays_t **parameterannotations = NULL;
348 parameterannotations = &(m->class->method_parameterannotations);
350 if (!annotation_load_attribute_body(
352 "invalid runtime visible parameter annotations method attribute")) {
356 if (annotations != NULL) {
357 slot = m - m->class->methods;
359 if (!annotation_bytearrays_insert(
360 parameterannotations, slot, annotations)) {
361 annotation_bytearray_free(annotations);
370 /* annotation_load_method_attribute_runtimeinvisibleparameterannotations ******
372 Load runtime invisible parameter annotations.
374 <quote cite="http://jcp.org/en/jsr/detail?id=202">
375 The RuntimeInvisibleParameterAnnotations attribute is similar to the
376 RuntimeVisibleParameterAnnotations attribute, except that the annotations
377 represented by a RuntimeInvisibleParameterAnnotations attribute must not be
378 made available for return by reflective APIs, unless the the JVM has
379 specifically been instructed to retain these annotations via some
380 implementation-specific mechanism such as a command line flag. In the
381 absence of such instructions, the JVM ignores this attribute.
384 Hotspot loads them into the same bytearray as the runtime visible parameter
385 annotations (after the runtime visible parameter annotations). But in J2SE
386 the bytearray will only be parsed as if ther is only one annotation
387 structure in it, so the runtime invisible parameter annotatios will be
390 Therefore I do not even bother to read them.
392 RuntimeInvisibleParameterAnnotations_attribute {
393 u2 attribute_name_index;
398 annotation annotations[num_annotations];
399 } parameter_annotations[num_parameters];
403 cb.................classbuffer from which to read the data.
404 m..................methodinfo for the method of which the parameter
405 annotations are read and into which the parameter
406 annotations are stored into.
409 true if all went good. false otherwhise.
411 *******************************************************************************/
413 bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
414 classbuffer *cb, methodinfo *m)
416 return loader_skip_attribute_body(cb);
420 /* annotation_load_class_attribute_runtimevisibleannotations ******************
422 Load runtime visible annotations of a class.
424 *******************************************************************************/
426 bool annotation_load_class_attribute_runtimevisibleannotations(
429 return annotation_load_attribute_body(
430 cb, &(cb->class->annotations),
431 "invalid runtime visible annotations class attribute");
435 /* annotation_load_class_attribute_runtimeinvisibleannotations ****************
437 Load runtime invisible annotations of a class (just skip them).
439 *******************************************************************************/
441 bool annotation_load_class_attribute_runtimeinvisibleannotations(
444 return loader_skip_attribute_body(cb);
448 /* annotation_load_method_attribute_runtimevisibleannotations *****************
450 Load runtime visible annotations of a method.
452 *******************************************************************************/
454 bool annotation_load_method_attribute_runtimevisibleannotations(
455 classbuffer *cb, methodinfo *m)
458 annotation_bytearray_t *annotations = NULL;
459 annotation_bytearrays_t **method_annotations = NULL;
464 method_annotations = &(m->class->method_annotations);
466 if (!annotation_load_attribute_body(
468 "invalid runtime visible annotations method attribute")) {
472 if (annotations != NULL) {
473 slot = m - m->class->methods;
475 if (!annotation_bytearrays_insert(
476 method_annotations, slot, annotations)) {
477 annotation_bytearray_free(annotations);
486 /* annotation_load_method_attribute_runtimeinvisibleannotations ****************
488 Load runtime invisible annotations of a method (just skip them).
490 *******************************************************************************/
492 bool annotation_load_method_attribute_runtimeinvisibleannotations(
493 classbuffer *cb, methodinfo *m)
495 return loader_skip_attribute_body(cb);
499 /* annotation_load_field_attribute_runtimevisibleannotations ******************
501 Load runtime visible annotations of a field.
503 *******************************************************************************/
505 bool annotation_load_field_attribute_runtimevisibleannotations(
506 classbuffer *cb, fieldinfo *f)
509 annotation_bytearray_t *annotations = NULL;
510 annotation_bytearrays_t **field_annotations = NULL;
515 field_annotations = &(f->class->field_annotations);
517 if (!annotation_load_attribute_body(
519 "invalid runtime visible annotations field attribute")) {
523 if (annotations != NULL) {
524 slot = f - f->class->fields;
526 if (!annotation_bytearrays_insert(
527 field_annotations, slot, annotations)) {
528 annotation_bytearray_free(annotations);
537 /* annotation_load_field_attribute_runtimeinvisibleannotations ****************
539 Load runtime invisible annotations of a field (just skip them).
541 *******************************************************************************/
543 bool annotation_load_field_attribute_runtimeinvisibleannotations(
544 classbuffer *cb, fieldinfo *f)
546 return loader_skip_attribute_body(cb);
551 * These are local overrides for various environment variables in Emacs.
552 * Please do not remove this and leave it at the end of the file, where
553 * Emacs will automagically detect them.
554 * ---------------------------------------------------------------------
557 * indent-tabs-mode: t
561 * vim:noexpandtab:sw=4:ts=4: