1 /* src/vm/stackmap.c - class attribute StackMapTable
3 Copyright (C) 2006 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
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
29 $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
37 #include "mm/memory.h"
39 #include "vm/exceptions.h"
40 #include "vm/method.h"
41 #include "vm/options.h"
42 #include "vm/stackmap.h"
44 #if defined(ENABLE_STATISTICS)
45 # include "vm/statistics.h"
51 /* stackmap_get_verification_type_info *****************************************
53 union verification_type_info {
55 Integer_variable_info;
60 UninitializedThis_variable_info;
62 Uninitialized_variable_info;
66 u1 tag = ITEM_Top; // 0
69 Integer_variable_info {
70 u1 tag = ITEM_Integer; // 1
74 u1 tag = ITEM_Float; // 2
78 u1 tag = ITEM_Long; // 4
81 Double_variable_info {
82 u1 tag = ITEM_Double; // 3
86 u1 tag = ITEM_Null; // 5
89 UninitializedThis_variable_info {
90 u1 tag = ITEM_UninitializedThis; // 6
93 Object_variable_info {
94 u1 tag = ITEM_Object; // 7
98 Uninitialized_variable_info {
99 u1 tag = ITEM_Uninitialized; // 8
103 *******************************************************************************/
105 static bool stackmap_get_verification_type_info(classbuffer *cb, verification_type_info_t *verification_type_info)
107 /* get verification type */
109 if (!suck_check_classbuffer_size(cb, 1))
112 verification_type_info->tag = suck_u1(cb);
114 /* process the tag */
116 switch (verification_type_info->tag) {
123 case ITEM_UninitializedThis:
127 /* get constant pool index */
129 if (!suck_check_classbuffer_size(cb, 2))
132 verification_type_info->Object_variable_info.cpool_index = suck_u2(cb);
135 case ITEM_Uninitialized:
138 if (!suck_check_classbuffer_size(cb, 2))
141 verification_type_info->Uninitialized_variable_info.offset = suck_u2(cb);
149 /* stackmap_get_same_locals_1_stack_item_frame *********************************
151 same_locals_1_stack_item_frame {
152 u1 frame_type = SAME_LOCALS_1_STACK_ITEM; // 64-127
153 verification_type_info stack[1];
156 *******************************************************************************/
158 static bool stackmap_get_same_locals_1_stack_item_frame(classbuffer *cb, stack_map_frame_t *stack_map_frame)
160 same_locals_1_stack_item_frame_t *same_locals_1_stack_item_frame;
162 /* for convenience */
164 same_locals_1_stack_item_frame =
165 &(stack_map_frame->same_locals_1_stack_item_frame);
167 if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame->stack[0])))
174 /* stackmap_get_same_locals_1_stack_item_frame_extended ************************
176 same_locals_1_stack_item_frame_extended {
177 u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED; // 247
179 verification_type_info stack[1];
182 *******************************************************************************/
184 static bool stackmap_get_same_locals_1_stack_item_frame_extended(classbuffer *cb, stack_map_frame_t *stack_map_frame)
186 same_locals_1_stack_item_frame_extended_t *same_locals_1_stack_item_frame_extended;
188 /* for convenience */
190 same_locals_1_stack_item_frame_extended =
191 &(stack_map_frame->same_locals_1_stack_item_frame_extended);
193 /* check buffer size */
195 if (!suck_check_classbuffer_size(cb, 2))
198 /* get offset delta */
200 same_locals_1_stack_item_frame_extended->offset_delta = suck_u2(cb);
204 if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame_extended->stack[0])))
211 /* stackmap_get_chop_frame *****************************************************
214 u1 frame_type = CHOP_FRAME; // 248-250
218 *******************************************************************************/
220 static bool stackmap_get_chop_frame(classbuffer *cb,
221 stack_map_frame_t *stack_map_frame)
223 chop_frame_t *chop_frame;
225 /* for convenience */
227 chop_frame = &(stack_map_frame->chop_frame);
229 /* check buffer size */
231 if (!suck_check_classbuffer_size(cb, 2))
234 /* get offset delta */
236 chop_frame->offset_delta = suck_u2(cb);
242 /* stackmap_get_same_frame_extended ********************************************
244 same_frame_extended {
245 u1 frame_type = SAME_FRAME_EXTENDED; // 251
249 *******************************************************************************/
251 static bool stackmap_get_same_frame_extended(classbuffer *cb,
252 stack_map_frame_t *stack_map_frame)
254 same_frame_extended_t *same_frame_extended;
256 /* for convenience */
258 same_frame_extended = &(stack_map_frame->same_frame_extended);
260 /* check buffer size */
262 if (!suck_check_classbuffer_size(cb, 2))
265 /* get offset delta */
267 same_frame_extended->offset_delta = suck_u2(cb);
273 /* stackmap_get_append_frame ***************************************************
276 u1 frame_type = APPEND_FRAME; // 252-254
278 verification_type_info locals[frame_Type - 251];
281 *******************************************************************************/
283 static bool stackmap_get_append_frame(classbuffer *cb,
284 stack_map_frame_t *stack_map_frame)
286 append_frame_t *append_frame;
290 /* for convenience */
292 append_frame = &(stack_map_frame->append_frame);
294 /* check buffer size */
296 if (!suck_check_classbuffer_size(cb, 2))
299 /* get offset delta */
301 append_frame->offset_delta = suck_u2(cb);
303 /* allocate locals array */
305 number_of_locals = append_frame->frame_type - 251;
307 append_frame->locals = DMNEW(verification_type_info_t, number_of_locals);
309 /* process all locals */
311 for (i = 0; i < number_of_locals; i++)
312 if (!stackmap_get_verification_type_info(cb, &(append_frame->locals[i])))
319 /* stackmap_get_full_frame *****************************************************
322 u1 frame_type = FULL_FRAME;
325 verification_type_info locals[number_of_locals];
326 u2 number_of_stack_items;
327 verification_type_info stack[number_of_stack_items];
330 *******************************************************************************/
332 static bool stackmap_get_full_frame(classbuffer *cb,
333 stack_map_frame_t *stack_map_frame)
335 full_frame_t *full_frame;
338 /* for convenience */
340 full_frame = &(stack_map_frame->full_frame);
342 /* check buffer size */
344 if (!suck_check_classbuffer_size(cb, 2 + 2))
347 /* get offset delta */
349 stack_map_frame->full_frame.offset_delta = suck_u2(cb);
351 /* get number of locals */
353 full_frame->number_of_locals = suck_u2(cb);
355 /* allocate locals array */
358 DMNEW(verification_type_info_t, full_frame->number_of_locals);
360 /* process all locals */
362 for (i = 0; i < full_frame->number_of_locals; i++)
363 if (!stackmap_get_verification_type_info(cb, &(full_frame->locals[i])))
366 /* get number of stack items */
368 if (!suck_check_classbuffer_size(cb, 2))
371 full_frame->number_of_stack_items = suck_u2(cb);
373 /* allocate stack array */
376 DMNEW(verification_type_info_t, full_frame->number_of_stack_items);
378 /* process all stack items */
380 for (i = 0; i < full_frame->number_of_stack_items; i++)
381 if (!stackmap_get_verification_type_info(cb, &(full_frame->stack[i])))
388 /* stackmap_load_attribute_stackmaptable ***************************************
391 u2 attribute_name_index;
393 u2 number_of_entries;
394 stack_map_frame entries[number_of_entries];
397 union stack_map_frame {
399 same_locals_1_stack_item_frame;
400 same_locals_1_stack_item_frame_extended;
408 u1 frame_type = SAME; // 0-63
411 *******************************************************************************/
413 bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m)
416 stack_map_t *stack_map;
424 /* allocate stack map structure */
426 stack_map = DNEW(stack_map_t);
428 STATISTICS(size_stack_map += sizeof(stack_map_t));
430 /* check buffer size */
432 if (!suck_check_classbuffer_size(cb, 4 + 2))
435 /* attribute_length */
437 stack_map->attribute_length = suck_u4(cb);
439 if (!suck_check_classbuffer_size(cb, stack_map->attribute_length))
442 /* get number of entries */
444 stack_map->number_of_entries = suck_u2(cb);
446 /* process all entries */
448 stack_map->entries = DMNEW(stack_map_frame_t, stack_map->number_of_entries);
450 for (i = 0; i < stack_map->number_of_entries; i++) {
451 /* get the frame type */
453 frame_type = suck_u1(cb);
455 stack_map->entries[i].frame_type = frame_type;
459 if (frame_type <= FRAME_TYPE_SAME) {
462 else if (frame_type <= FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM) {
463 /* same_locals_1_stack_item_frame */
465 if (!stackmap_get_same_locals_1_stack_item_frame(cb, &(stack_map->entries[i])))
468 else if (frame_type <= FRAME_TYPE_RESERVED) {
471 exceptions_throw_classformaterror(c, "reserved frame type");
474 else if (frame_type == FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
475 /* same_locals_1_stack_item_frame_extended */
477 if (!stackmap_get_same_locals_1_stack_item_frame_extended(cb, &(stack_map->entries[i])))
480 else if (frame_type <= FRAME_TYPE_CHOP) {
483 if (!stackmap_get_chop_frame(cb, &(stack_map->entries[i])))
486 else if (frame_type == FRAME_TYPE_SAME_FRAME_EXTENDED) {
487 /* same_frame_extended */
489 if (!stackmap_get_same_frame_extended(cb, &(stack_map->entries[i])))
492 else if (frame_type <= FRAME_TYPE_APPEND) {
495 if (!stackmap_get_append_frame(cb, &(stack_map->entries[i])))
498 else if (frame_type == FRAME_TYPE_FULL_FRAME) {
501 if (!stackmap_get_full_frame(cb, &(stack_map->entries[i])))
506 /* store stack map in method structure */
509 /* currently not used */
511 m->stack_map = stack_map;
519 * These are local overrides for various environment variables in Emacs.
520 * Please do not remove this and leave it at the end of the file, where
521 * Emacs will automagically detect them.
522 * ---------------------------------------------------------------------
525 * indent-tabs-mode: t
529 * vim:noexpandtab:sw=4:ts=4: