1 /* src/vmcore/stackmap.c - class attribute StackMapTable
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
25 $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
33 #include "mm/memory.h"
35 #include "vm/exceptions.h"
37 #include "vmcore/class.h"
38 #include "vmcore/method.h"
39 #include "vmcore/options.h"
40 #include "vmcore/stackmap.h"
41 #include "vmcore/statistics.h"
42 #include "vmcore/suck.h"
45 /* stackmap_get_verification_type_info *****************************************
47 union verification_type_info {
49 Integer_variable_info;
54 UninitializedThis_variable_info;
56 Uninitialized_variable_info;
60 u1 tag = ITEM_Top; // 0
63 Integer_variable_info {
64 u1 tag = ITEM_Integer; // 1
68 u1 tag = ITEM_Float; // 2
72 u1 tag = ITEM_Long; // 4
75 Double_variable_info {
76 u1 tag = ITEM_Double; // 3
80 u1 tag = ITEM_Null; // 5
83 UninitializedThis_variable_info {
84 u1 tag = ITEM_UninitializedThis; // 6
87 Object_variable_info {
88 u1 tag = ITEM_Object; // 7
92 Uninitialized_variable_info {
93 u1 tag = ITEM_Uninitialized; // 8
97 *******************************************************************************/
99 static bool stackmap_get_verification_type_info(classbuffer *cb, verification_type_info_t *verification_type_info)
101 /* get verification type */
103 if (!suck_check_classbuffer_size(cb, 1))
106 verification_type_info->tag = suck_u1(cb);
108 /* process the tag */
110 switch (verification_type_info->tag) {
117 case ITEM_UninitializedThis:
121 /* get constant pool index */
123 if (!suck_check_classbuffer_size(cb, 2))
126 verification_type_info->Object_variable_info.cpool_index = suck_u2(cb);
129 case ITEM_Uninitialized:
132 if (!suck_check_classbuffer_size(cb, 2))
135 verification_type_info->Uninitialized_variable_info.offset = suck_u2(cb);
143 /* stackmap_get_same_locals_1_stack_item_frame *********************************
145 same_locals_1_stack_item_frame {
146 u1 frame_type = SAME_LOCALS_1_STACK_ITEM; // 64-127
147 verification_type_info stack[1];
150 *******************************************************************************/
152 static bool stackmap_get_same_locals_1_stack_item_frame(classbuffer *cb, stack_map_frame_t *stack_map_frame)
154 same_locals_1_stack_item_frame_t *same_locals_1_stack_item_frame;
156 /* for convenience */
158 same_locals_1_stack_item_frame =
159 &(stack_map_frame->same_locals_1_stack_item_frame);
161 if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame->stack[0])))
168 /* stackmap_get_same_locals_1_stack_item_frame_extended ************************
170 same_locals_1_stack_item_frame_extended {
171 u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED; // 247
173 verification_type_info stack[1];
176 *******************************************************************************/
178 static bool stackmap_get_same_locals_1_stack_item_frame_extended(classbuffer *cb, stack_map_frame_t *stack_map_frame)
180 same_locals_1_stack_item_frame_extended_t *same_locals_1_stack_item_frame_extended;
182 /* for convenience */
184 same_locals_1_stack_item_frame_extended =
185 &(stack_map_frame->same_locals_1_stack_item_frame_extended);
187 /* check buffer size */
189 if (!suck_check_classbuffer_size(cb, 2))
192 /* get offset delta */
194 same_locals_1_stack_item_frame_extended->offset_delta = suck_u2(cb);
198 if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame_extended->stack[0])))
205 /* stackmap_get_chop_frame *****************************************************
208 u1 frame_type = CHOP_FRAME; // 248-250
212 *******************************************************************************/
214 static bool stackmap_get_chop_frame(classbuffer *cb,
215 stack_map_frame_t *stack_map_frame)
217 chop_frame_t *chop_frame;
219 /* for convenience */
221 chop_frame = &(stack_map_frame->chop_frame);
223 /* check buffer size */
225 if (!suck_check_classbuffer_size(cb, 2))
228 /* get offset delta */
230 chop_frame->offset_delta = suck_u2(cb);
236 /* stackmap_get_same_frame_extended ********************************************
238 same_frame_extended {
239 u1 frame_type = SAME_FRAME_EXTENDED; // 251
243 *******************************************************************************/
245 static bool stackmap_get_same_frame_extended(classbuffer *cb,
246 stack_map_frame_t *stack_map_frame)
248 same_frame_extended_t *same_frame_extended;
250 /* for convenience */
252 same_frame_extended = &(stack_map_frame->same_frame_extended);
254 /* check buffer size */
256 if (!suck_check_classbuffer_size(cb, 2))
259 /* get offset delta */
261 same_frame_extended->offset_delta = suck_u2(cb);
267 /* stackmap_get_append_frame ***************************************************
270 u1 frame_type = APPEND_FRAME; // 252-254
272 verification_type_info locals[frame_Type - 251];
275 *******************************************************************************/
277 static bool stackmap_get_append_frame(classbuffer *cb,
278 stack_map_frame_t *stack_map_frame)
280 append_frame_t *append_frame;
284 /* for convenience */
286 append_frame = &(stack_map_frame->append_frame);
288 /* check buffer size */
290 if (!suck_check_classbuffer_size(cb, 2))
293 /* get offset delta */
295 append_frame->offset_delta = suck_u2(cb);
297 /* allocate locals array */
299 number_of_locals = append_frame->frame_type - 251;
301 append_frame->locals = DMNEW(verification_type_info_t, number_of_locals);
303 /* process all locals */
305 for (i = 0; i < number_of_locals; i++)
306 if (!stackmap_get_verification_type_info(cb, &(append_frame->locals[i])))
313 /* stackmap_get_full_frame *****************************************************
316 u1 frame_type = FULL_FRAME;
319 verification_type_info locals[number_of_locals];
320 u2 number_of_stack_items;
321 verification_type_info stack[number_of_stack_items];
324 *******************************************************************************/
326 static bool stackmap_get_full_frame(classbuffer *cb,
327 stack_map_frame_t *stack_map_frame)
329 full_frame_t *full_frame;
332 /* for convenience */
334 full_frame = &(stack_map_frame->full_frame);
336 /* check buffer size */
338 if (!suck_check_classbuffer_size(cb, 2 + 2))
341 /* get offset delta */
343 stack_map_frame->full_frame.offset_delta = suck_u2(cb);
345 /* get number of locals */
347 full_frame->number_of_locals = suck_u2(cb);
349 /* allocate locals array */
352 DMNEW(verification_type_info_t, full_frame->number_of_locals);
354 /* process all locals */
356 for (i = 0; i < full_frame->number_of_locals; i++)
357 if (!stackmap_get_verification_type_info(cb, &(full_frame->locals[i])))
360 /* get number of stack items */
362 if (!suck_check_classbuffer_size(cb, 2))
365 full_frame->number_of_stack_items = suck_u2(cb);
367 /* allocate stack array */
370 DMNEW(verification_type_info_t, full_frame->number_of_stack_items);
372 /* process all stack items */
374 for (i = 0; i < full_frame->number_of_stack_items; i++)
375 if (!stackmap_get_verification_type_info(cb, &(full_frame->stack[i])))
382 /* stackmap_load_attribute_stackmaptable ***************************************
385 u2 attribute_name_index;
387 u2 number_of_entries;
388 stack_map_frame entries[number_of_entries];
391 union stack_map_frame {
393 same_locals_1_stack_item_frame;
394 same_locals_1_stack_item_frame_extended;
402 u1 frame_type = SAME; // 0-63
405 *******************************************************************************/
407 bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m)
410 stack_map_t *stack_map;
418 /* allocate stack map structure */
420 stack_map = DNEW(stack_map_t);
422 STATISTICS(size_stack_map += sizeof(stack_map_t));
424 /* check buffer size */
426 if (!suck_check_classbuffer_size(cb, 4 + 2))
429 /* attribute_length */
431 stack_map->attribute_length = suck_u4(cb);
433 if (!suck_check_classbuffer_size(cb, stack_map->attribute_length))
436 /* get number of entries */
438 stack_map->number_of_entries = suck_u2(cb);
440 /* process all entries */
442 stack_map->entries = DMNEW(stack_map_frame_t, stack_map->number_of_entries);
444 for (i = 0; i < stack_map->number_of_entries; i++) {
445 /* get the frame type */
447 frame_type = suck_u1(cb);
449 stack_map->entries[i].frame_type = frame_type;
453 if (frame_type <= FRAME_TYPE_SAME) {
456 else if (frame_type <= FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM) {
457 /* same_locals_1_stack_item_frame */
459 if (!stackmap_get_same_locals_1_stack_item_frame(cb, &(stack_map->entries[i])))
462 else if (frame_type <= FRAME_TYPE_RESERVED) {
465 exceptions_throw_classformaterror(c, "reserved frame type");
468 else if (frame_type == FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
469 /* same_locals_1_stack_item_frame_extended */
471 if (!stackmap_get_same_locals_1_stack_item_frame_extended(cb, &(stack_map->entries[i])))
474 else if (frame_type <= FRAME_TYPE_CHOP) {
477 if (!stackmap_get_chop_frame(cb, &(stack_map->entries[i])))
480 else if (frame_type == FRAME_TYPE_SAME_FRAME_EXTENDED) {
481 /* same_frame_extended */
483 if (!stackmap_get_same_frame_extended(cb, &(stack_map->entries[i])))
486 else if (frame_type <= FRAME_TYPE_APPEND) {
489 if (!stackmap_get_append_frame(cb, &(stack_map->entries[i])))
492 else if (frame_type == FRAME_TYPE_FULL_FRAME) {
495 if (!stackmap_get_full_frame(cb, &(stack_map->entries[i])))
500 /* store stack map in method structure */
503 /* currently not used */
505 m->stack_map = stack_map;
513 * These are local overrides for various environment variables in Emacs.
514 * Please do not remove this and leave it at the end of the file, where
515 * Emacs will automagically detect them.
516 * ---------------------------------------------------------------------
519 * indent-tabs-mode: t
523 * vim:noexpandtab:sw=4:ts=4: