1 /* src/vmcore/field.c - field functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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
25 $Id: field.c 8227 2007-07-24 11:55:07Z twisti $
38 #include "vm/exceptions.h"
39 #include "vm/stringlocal.h"
42 #include "vmcore/class.h"
43 #include "vmcore/descriptor.h"
44 #include "vmcore/field.h"
45 #include "vmcore/loader.h"
46 #include "vmcore/options.h"
47 #include "vmcore/primitive.h"
48 #include "vmcore/references.h"
49 #include "vmcore/suck.h"
50 #include "vmcore/utf8.h"
53 /* field_load ******************************************************************
55 Load everything about a class field from the class file and fill a
58 *******************************************************************************/
60 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
62 bool field_load(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
67 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
72 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
75 f->flags = suck_u2(cb);
77 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
82 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
88 if (!descriptor_pool_add(descpool, u, NULL))
91 /* descriptor_pool_add accepts method descriptors, so we have to
92 check against them here before the call of
93 descriptor_to_basic_type below. */
95 if (u->text[0] == '(') {
96 exceptions_throw_classformaterror(c, "Method descriptor used for field");
100 #ifdef ENABLE_VERIFIER
103 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
104 exceptions_throw_classformaterror(c,
105 "Illegal Field name \"%s\"",
110 /* check flag consistency */
111 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
113 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
114 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
115 exceptions_throw_classformaterror(c,
116 "Illegal field modifiers: 0x%X",
121 if (c->flags & ACC_INTERFACE) {
122 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
123 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
124 f->flags & ACC_TRANSIENT) {
125 exceptions_throw_classformaterror(c,
126 "Illegal field modifiers: 0x%X",
132 #endif /* ENABLE_VERIFIER */
136 jtype = descriptor_to_basic_type(f->descriptor);
140 f->offset = 0; /* offset from start of object */
157 if (!(f->flags & ACC_STATIC))
158 c->flags |= ACC_CLASS_HAS_POINTERS;
171 /* read attributes */
172 if (!suck_check_classbuffer_size(cb, 2))
175 attrnum = suck_u2(cb);
176 for (i = 0; i < attrnum; i++) {
177 if (!suck_check_classbuffer_size(cb, 2))
180 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
183 if (u == utf_ConstantValue) {
184 if (!suck_check_classbuffer_size(cb, 4 + 2))
187 /* check attribute length */
189 if (suck_u4(cb) != 2) {
190 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
194 /* constant value attribute */
196 if (pindex != field_load_NOVALUE) {
197 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
201 /* index of value in constantpool */
203 pindex = suck_u2(cb);
205 /* initialize field with value from constantpool */
209 constant_integer *ci;
211 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
214 f->value.i = ci->value;
221 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
224 f->value.l = cl->value;
231 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
234 f->value.f = cf->value;
241 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
244 f->value.d = cd->value;
249 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
252 /* create javastring from compressed utf8-string */
253 f->value.a = literalstring_new(u);
257 vm_abort("field_load: invalid field type %d", jtype);
260 #if defined(ENABLE_JAVASE)
261 else if (u == utf_Signature) {
264 if (!loader_load_attribute_signature(cb, &(f->signature)))
269 /* unknown attribute */
271 if (!loader_skip_attribute_body(cb))
276 /* everything was ok */
282 /* field_get_type **************************************************************
284 Returns the type of the field as class.
286 *******************************************************************************/
288 classinfo *field_get_type(fieldinfo *f)
296 if (td->type == TYPE_ADR) {
297 assert(td->classref);
299 u = td->classref->name;
301 /* load the class of the field-type with the field's
304 c = load_class_from_classloader(u, f->class->classloader);
307 c = primitive_class_get_by_type(td->decltype);
314 /* field_free ******************************************************************
316 Frees a fields' resources.
318 *******************************************************************************/
320 void field_free(fieldinfo *f)
326 /* field_printflags ************************************************************
330 *******************************************************************************/
333 void field_printflags(fieldinfo *f)
340 if (f->flags & ACC_PUBLIC) printf(" PUBLIC");
341 if (f->flags & ACC_PRIVATE) printf(" PRIVATE");
342 if (f->flags & ACC_PROTECTED) printf(" PROTECTED");
343 if (f->flags & ACC_STATIC) printf(" STATIC");
344 if (f->flags & ACC_FINAL) printf(" FINAL");
345 if (f->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
346 if (f->flags & ACC_VOLATILE) printf(" VOLATILE");
347 if (f->flags & ACC_TRANSIENT) printf(" TRANSIENT");
348 if (f->flags & ACC_NATIVE) printf(" NATIVE");
349 if (f->flags & ACC_INTERFACE) printf(" INTERFACE");
350 if (f->flags & ACC_ABSTRACT) printf(" ABSTRACT");
355 /* field_print *****************************************************************
359 *******************************************************************************/
362 void field_print(fieldinfo *f)
365 printf("(fieldinfo*)NULL");
369 utf_display_printable_ascii_classname(f->class->name);
371 utf_display_printable_ascii(f->name);
373 utf_display_printable_ascii(f->descriptor);
380 /* field_println ***************************************************************
384 *******************************************************************************/
387 void field_println(fieldinfo *f)
394 /* field_fieldref_print ********************************************************
398 *******************************************************************************/
401 void field_fieldref_print(constant_FMIref *fr)
404 printf("(constant_FMIref *)NULL");
408 if (IS_FMIREF_RESOLVED(fr)) {
410 field_print(fr->p.field);
413 printf("<fieldref> ");
414 utf_display_printable_ascii_classname(fr->p.classref->name);
416 utf_display_printable_ascii(fr->name);
418 utf_display_printable_ascii(fr->descriptor);
423 /* field_fieldref_println ******************************************************
427 *******************************************************************************/
430 void field_fieldref_println(constant_FMIref *fr)
432 field_fieldref_print(fr);
438 * These are local overrides for various environment variables in Emacs.
439 * Please do not remove this and leave it at the end of the file, where
440 * Emacs will automagically detect them.
441 * ---------------------------------------------------------------------
444 * indent-tabs-mode: t