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
31 #include "native/llni.h"
35 #include "vm/builtin.h"
36 #include "vm/primitive.h"
38 #include "mm/memory.h"
40 #include "toolbox/logging.h"
42 #include "vmcore/annotation.h"
43 #include "vmcore/class.h"
44 #include "vmcore/suck.h"
46 #if !defined(ENABLE_ANNOTATIONS)
47 # error annotation support has to be enabled when compling this file!
51 /* annotation_bytearrays_resize ***********************************************
53 Resize an array of bytearrays.
55 *******************************************************************************/
57 static bool annotation_bytearrays_resize(java_handle_objectarray_t **bas,
60 java_handle_objectarray_t *newbas = NULL;
68 /* if the size already fits do nothing */
70 oldsize = array_length_get((java_handle_t*)*bas);
72 if (size == oldsize) {
77 newbas = builtin_anewarray(size,
78 primitive_arrayclass_get_by_type(PRIMITIVETYPE_BYTE));
85 /* is there a old byte array array? */
87 minsize = size < oldsize ? size : oldsize;
89 MCOPY(LLNI_array_data(newbas), LLNI_array_data(*bas), java_object_t*, minsize);
98 /* annotation_bytearrays_insert ***********************************************
100 Insert a bytearray into an array of bytearrays.
102 *******************************************************************************/
104 static bool annotation_bytearrays_insert(java_handle_objectarray_t **bas,
105 uint32_t index, java_handle_bytearray_t *ba)
111 /* do nothing if NULL is inserted but no array exists */
112 if (ba == NULL && *bas == NULL) {
116 /* get lengths if array exists */
118 size = array_length_get((java_handle_t*)*bas);
122 /* insert NULL only if array is big enough */
124 array_objectarray_element_set(*bas, index, NULL);
128 /* resize array if it's not enough for inserted value */
130 if (!annotation_bytearrays_resize(bas, index + 1)) {
136 array_objectarray_element_set(*bas, index, (java_handle_t*)ba);
143 /* annotation_load_attribute_body *********************************************
145 This function loads the body of a generic attribute.
147 XXX: Maybe this function should be called loader_load_attribute_body and
148 located in vmcore/loader.c?
151 u2 attribute_name_index;
153 u1 info[attribute_length];
157 cb.................classbuffer from which to read the data.
158 errormsg_prefix....prefix for error messages (if any).
161 attribute..........bytearray-pointer which will be set to the read data.
164 true if all went good. false otherwhise.
166 *******************************************************************************/
168 static bool annotation_load_attribute_body(classbuffer *cb,
169 java_handle_bytearray_t **attribute, const char *errormsg_prefix)
172 java_handle_bytearray_t *ba = NULL;
175 assert(attribute != NULL);
177 if (!suck_check_classbuffer_size(cb, 4)) {
178 log_println("%s: size missing", errormsg_prefix);
182 /* load attribute_length */
185 if (!suck_check_classbuffer_size(cb, size)) {
186 log_println("%s: invalid size", errormsg_prefix);
190 /* if attribute_length == 0 then NULL is
191 * the right value for this attribute */
193 ba = builtin_newarray_byte(size);
201 suck_nbytes((uint8_t*)LLNI_array_data(ba), cb, size);
211 /* annotation_load_method_attribute_annotationdefault *************************
213 Load annotation default value.
215 AnnotationDefault_attribute {
216 u2 attribute_name_index;
218 element_value default_value;
222 cb.................classbuffer from which to read the data.
223 m..................methodinfo for the method of which the annotation
224 default value is read and into which the value is
228 true if all went good. false otherwhise.
230 *******************************************************************************/
232 bool annotation_load_method_attribute_annotationdefault(
233 classbuffer *cb, methodinfo *m)
236 java_handle_bytearray_t *annotationdefault = NULL;
237 java_handle_objectarray_t **annotationdefaults = NULL;
242 annotationdefaults = &(m->class->method_annotationdefaults);
244 if (!annotation_load_attribute_body(
245 cb, &annotationdefault,
246 "invalid annotation default method attribute")) {
250 if (annotationdefault != NULL) {
251 slot = m - m->class->methods;
253 if (!annotation_bytearrays_insert(
254 annotationdefaults, slot, annotationdefault)) {
263 /* annotation_load_method_attribute_runtimevisibleparameterannotations ********
265 Load runtime visible parameter annotations.
267 RuntimeVisibleParameterAnnotations_attribute {
268 u2 attribute_name_index;
273 annotation annotations[num_annotations];
274 } parameter_annotations[num_parameters];
278 cb.................classbuffer from which to read the data.
279 m..................methodinfo for the method of which the parameter
280 annotations are read and into which the parameter
281 annotations are stored into.
284 true if all went good. false otherwhise.
286 *******************************************************************************/
288 bool annotation_load_method_attribute_runtimevisibleparameterannotations(
289 classbuffer *cb, methodinfo *m)
292 java_handle_bytearray_t *annotations = NULL;
293 java_handle_objectarray_t **parameterannotations = NULL;
298 parameterannotations = &(m->class->method_parameterannotations);
300 if (!annotation_load_attribute_body(
302 "invalid runtime visible parameter annotations method attribute")) {
306 if (annotations != NULL) {
307 slot = m - m->class->methods;
309 if (!annotation_bytearrays_insert(
310 parameterannotations, slot, annotations)) {
319 /* annotation_load_method_attribute_runtimeinvisibleparameterannotations ******
321 Load runtime invisible parameter annotations.
323 <quote cite="http://jcp.org/en/jsr/detail?id=202">
324 The RuntimeInvisibleParameterAnnotations attribute is similar to the
325 RuntimeVisibleParameterAnnotations attribute, except that the annotations
326 represented by a RuntimeInvisibleParameterAnnotations attribute must not be
327 made available for return by reflective APIs, unless the the JVM has
328 specifically been instructed to retain these annotations via some
329 implementation-specific mechanism such as a command line flag. In the
330 absence of such instructions, the JVM ignores this attribute.
333 Hotspot loads them into the same bytearray as the runtime visible parameter
334 annotations (after the runtime visible parameter annotations). But in J2SE
335 the bytearray will only be parsed as if ther is only one annotation
336 structure in it, so the runtime invisible parameter annotatios will be
339 Therefore I do not even bother to read them.
341 RuntimeInvisibleParameterAnnotations_attribute {
342 u2 attribute_name_index;
347 annotation annotations[num_annotations];
348 } parameter_annotations[num_parameters];
352 cb.................classbuffer from which to read the data.
353 m..................methodinfo for the method of which the parameter
354 annotations are read and into which the parameter
355 annotations are stored into.
358 true if all went good. false otherwhise.
360 *******************************************************************************/
362 bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
363 classbuffer *cb, methodinfo *m)
365 return loader_skip_attribute_body(cb);
369 /* annotation_load_class_attribute_runtimevisibleannotations ******************
371 Load runtime visible annotations of a class.
373 *******************************************************************************/
375 bool annotation_load_class_attribute_runtimevisibleannotations(
378 return annotation_load_attribute_body(
379 cb, &(cb->class->annotations),
380 "invalid runtime visible annotations class attribute");
384 /* annotation_load_class_attribute_runtimeinvisibleannotations ****************
386 Load runtime invisible annotations of a class (just skip them).
388 *******************************************************************************/
390 bool annotation_load_class_attribute_runtimeinvisibleannotations(
393 return loader_skip_attribute_body(cb);
397 /* annotation_load_method_attribute_runtimevisibleannotations *****************
399 Load runtime visible annotations of a method.
401 *******************************************************************************/
403 bool annotation_load_method_attribute_runtimevisibleannotations(
404 classbuffer *cb, methodinfo *m)
407 java_handle_bytearray_t *annotations = NULL;
408 java_handle_objectarray_t **method_annotations = NULL;
413 method_annotations = &(m->class->method_annotations);
415 if (!annotation_load_attribute_body(
417 "invalid runtime visible annotations method attribute")) {
421 if (annotations != NULL) {
422 slot = m - m->class->methods;
424 if (!annotation_bytearrays_insert(
425 method_annotations, slot, annotations)) {
434 /* annotation_load_method_attribute_runtimeinvisibleannotations ****************
436 Load runtime invisible annotations of a method (just skip them).
438 *******************************************************************************/
440 bool annotation_load_method_attribute_runtimeinvisibleannotations(
441 classbuffer *cb, methodinfo *m)
443 return loader_skip_attribute_body(cb);
447 /* annotation_load_field_attribute_runtimevisibleannotations ******************
449 Load runtime visible annotations of a field.
451 *******************************************************************************/
453 bool annotation_load_field_attribute_runtimevisibleannotations(
454 classbuffer *cb, fieldinfo *f)
457 java_handle_bytearray_t *annotations = NULL;
458 java_handle_objectarray_t **field_annotations = NULL;
463 field_annotations = &(f->class->field_annotations);
465 if (!annotation_load_attribute_body(
467 "invalid runtime visible annotations field attribute")) {
471 if (annotations != NULL) {
472 slot = f - f->class->fields;
474 if (!annotation_bytearrays_insert(
475 field_annotations, slot, annotations)) {
484 /* annotation_load_field_attribute_runtimeinvisibleannotations ****************
486 Load runtime invisible annotations of a field (just skip them).
488 *******************************************************************************/
490 bool annotation_load_field_attribute_runtimeinvisibleannotations(
491 classbuffer *cb, fieldinfo *f)
493 return loader_skip_attribute_body(cb);
498 * These are local overrides for various environment variables in Emacs.
499 * Please do not remove this and leave it at the end of the file, where
500 * Emacs will automagically detect them.
501 * ---------------------------------------------------------------------
504 * indent-tabs-mode: t
508 * vim:noexpandtab:sw=4:ts=4: