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;
66 /* if the size already fits do nothing */
68 oldsize = array_length_get((java_handle_t*)*bas);
70 if (size == oldsize) {
75 newbas = builtin_anewarray(size,
76 primitive_arrayclass_get_by_type(PRIMITIVETYPE_BYTE));
83 /* is there a old byte array array? */
85 minsize = size < oldsize ? size : oldsize;
87 MCOPY(LLNI_array_data(newbas), LLNI_array_data(*bas), java_object_t*, minsize);
96 /* annotation_bytearrays_insert ***********************************************
98 Insert a bytearray into an array of bytearrays.
100 *******************************************************************************/
102 static bool annotation_bytearrays_insert(java_handle_objectarray_t **bas,
103 uint32_t index, java_handle_bytearray_t *ba)
109 /* do nothing if NULL is inserted but no array exists */
110 if (ba == NULL && *bas == NULL) {
114 /* get lengths if array exists */
116 size = array_length_get((java_handle_t*)*bas);
120 /* insert NULL only if array is big enough */
122 array_objectarray_element_set(*bas, index, NULL);
126 /* resize array if it's not enough for inserted value */
128 if (!annotation_bytearrays_resize(bas, index + 1)) {
134 array_objectarray_element_set(*bas, index, (java_handle_t*)ba);
141 /* annotation_load_attribute_body *********************************************
143 This function loads the body of a generic attribute.
145 XXX: Maybe this function should be called loader_load_attribute_body and
146 located in vmcore/loader.c?
149 u2 attribute_name_index;
151 u1 info[attribute_length];
155 cb.................classbuffer from which to read the data.
156 errormsg_prefix....prefix for error messages (if any).
159 attribute..........bytearray-pointer which will be set to the read data.
162 true if all went good. false otherwhise.
164 *******************************************************************************/
166 static bool annotation_load_attribute_body(classbuffer *cb,
167 java_handle_bytearray_t **attribute, const char *errormsg_prefix)
170 java_handle_bytearray_t *ba = NULL;
173 assert(attribute != NULL);
175 if (!suck_check_classbuffer_size(cb, 4)) {
176 log_println("%s: size missing", errormsg_prefix);
180 /* load attribute_length */
183 if (!suck_check_classbuffer_size(cb, size)) {
184 log_println("%s: invalid size", errormsg_prefix);
188 /* if attribute_length == 0 then NULL is
189 * the right value for this attribute */
191 ba = builtin_newarray_byte(size);
199 suck_nbytes((uint8_t*)LLNI_array_data(ba), cb, size);
209 /* annotation_load_method_attribute_annotationdefault *************************
211 Load annotation default value.
213 AnnotationDefault_attribute {
214 u2 attribute_name_index;
216 element_value default_value;
220 cb.................classbuffer from which to read the data.
221 m..................methodinfo for the method of which the annotation
222 default value is read and into which the value is
226 true if all went good. false otherwhise.
228 *******************************************************************************/
230 bool annotation_load_method_attribute_annotationdefault(
231 classbuffer *cb, methodinfo *m)
234 java_handle_bytearray_t *annotationdefault = NULL;
235 java_handle_objectarray_t **annotationdefaults = NULL;
240 annotationdefaults = &(m->class->method_annotationdefaults);
242 if (!annotation_load_attribute_body(
243 cb, &annotationdefault,
244 "invalid annotation default method attribute")) {
248 if (annotationdefault != NULL) {
249 slot = m - m->class->methods;
251 if (!annotation_bytearrays_insert(
252 annotationdefaults, slot, annotationdefault)) {
261 /* annotation_load_method_attribute_runtimevisibleparameterannotations ********
263 Load runtime visible parameter annotations.
265 RuntimeVisibleParameterAnnotations_attribute {
266 u2 attribute_name_index;
271 annotation annotations[num_annotations];
272 } parameter_annotations[num_parameters];
276 cb.................classbuffer from which to read the data.
277 m..................methodinfo for the method of which the parameter
278 annotations are read and into which the parameter
279 annotations are stored into.
282 true if all went good. false otherwhise.
284 *******************************************************************************/
286 bool annotation_load_method_attribute_runtimevisibleparameterannotations(
287 classbuffer *cb, methodinfo *m)
290 java_handle_bytearray_t *annotations = NULL;
291 java_handle_objectarray_t **parameterannotations = NULL;
296 parameterannotations = &(m->class->method_parameterannotations);
298 if (!annotation_load_attribute_body(
300 "invalid runtime visible parameter annotations method attribute")) {
304 if (annotations != NULL) {
305 slot = m - m->class->methods;
307 if (!annotation_bytearrays_insert(
308 parameterannotations, slot, annotations)) {
317 /* annotation_load_method_attribute_runtimeinvisibleparameterannotations ******
319 Load runtime invisible parameter annotations.
321 <quote cite="http://jcp.org/en/jsr/detail?id=202">
322 The RuntimeInvisibleParameterAnnotations attribute is similar to the
323 RuntimeVisibleParameterAnnotations attribute, except that the annotations
324 represented by a RuntimeInvisibleParameterAnnotations attribute must not be
325 made available for return by reflective APIs, unless the the JVM has
326 specifically been instructed to retain these annotations via some
327 implementation-specific mechanism such as a command line flag. In the
328 absence of such instructions, the JVM ignores this attribute.
331 Hotspot loads them into the same bytearray as the runtime visible parameter
332 annotations (after the runtime visible parameter annotations). But in J2SE
333 the bytearray will only be parsed as if ther is only one annotation
334 structure in it, so the runtime invisible parameter annotatios will be
337 Therefore I do not even bother to read them.
339 RuntimeInvisibleParameterAnnotations_attribute {
340 u2 attribute_name_index;
345 annotation annotations[num_annotations];
346 } parameter_annotations[num_parameters];
350 cb.................classbuffer from which to read the data.
351 m..................methodinfo for the method of which the parameter
352 annotations are read and into which the parameter
353 annotations are stored into.
356 true if all went good. false otherwhise.
358 *******************************************************************************/
360 bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
361 classbuffer *cb, methodinfo *m)
363 return loader_skip_attribute_body(cb);
367 /* annotation_load_class_attribute_runtimevisibleannotations ******************
369 Load runtime visible annotations of a class.
371 *******************************************************************************/
373 bool annotation_load_class_attribute_runtimevisibleannotations(
376 return annotation_load_attribute_body(
377 cb, &(cb->class->annotations),
378 "invalid runtime visible annotations class attribute");
382 /* annotation_load_class_attribute_runtimeinvisibleannotations ****************
384 Load runtime invisible annotations of a class (just skip them).
386 *******************************************************************************/
388 bool annotation_load_class_attribute_runtimeinvisibleannotations(
391 return loader_skip_attribute_body(cb);
395 /* annotation_load_method_attribute_runtimevisibleannotations *****************
397 Load runtime visible annotations of a method.
399 *******************************************************************************/
401 bool annotation_load_method_attribute_runtimevisibleannotations(
402 classbuffer *cb, methodinfo *m)
405 java_handle_bytearray_t *annotations = NULL;
406 java_handle_objectarray_t **method_annotations = NULL;
411 method_annotations = &(m->class->method_annotations);
413 if (!annotation_load_attribute_body(
415 "invalid runtime visible annotations method attribute")) {
419 if (annotations != NULL) {
420 slot = m - m->class->methods;
422 if (!annotation_bytearrays_insert(
423 method_annotations, slot, annotations)) {
432 /* annotation_load_method_attribute_runtimeinvisibleannotations ****************
434 Load runtime invisible annotations of a method (just skip them).
436 *******************************************************************************/
438 bool annotation_load_method_attribute_runtimeinvisibleannotations(
439 classbuffer *cb, methodinfo *m)
441 return loader_skip_attribute_body(cb);
445 /* annotation_load_field_attribute_runtimevisibleannotations ******************
447 Load runtime visible annotations of a field.
449 *******************************************************************************/
451 bool annotation_load_field_attribute_runtimevisibleannotations(
452 classbuffer *cb, fieldinfo *f)
455 java_handle_bytearray_t *annotations = NULL;
456 java_handle_objectarray_t **field_annotations = NULL;
461 field_annotations = &(f->class->field_annotations);
463 if (!annotation_load_attribute_body(
465 "invalid runtime visible annotations field attribute")) {
469 if (annotations != NULL) {
470 slot = f - f->class->fields;
472 if (!annotation_bytearrays_insert(
473 field_annotations, slot, annotations)) {
482 /* annotation_load_field_attribute_runtimeinvisibleannotations ****************
484 Load runtime invisible annotations of a field (just skip them).
486 *******************************************************************************/
488 bool annotation_load_field_attribute_runtimeinvisibleannotations(
489 classbuffer *cb, fieldinfo *f)
491 return loader_skip_attribute_body(cb);
496 * These are local overrides for various environment variables in Emacs.
497 * Please do not remove this and leave it at the end of the file, where
498 * Emacs will automagically detect them.
499 * ---------------------------------------------------------------------
502 * indent-tabs-mode: t
506 * vim:noexpandtab:sw=4:ts=4: