LCOV - code coverage report
Current view: top level - vm - stackmap.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 80 104 76.9 %
Date: 2015-06-10 18:10:59 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /* src/vm/stackmap.c - class attribute StackMapTable
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       8             :    This program is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU General Public License as
      10             :    published by the Free Software Foundation; either version 2, or (at
      11             :    your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful, but
      14             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program; if not, write to the Free Software
      20             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : 
      26             : #include "config.h"
      27             : #include "vm/types.hpp"
      28             : 
      29             : #include "mm/dumpmemory.hpp"
      30             : 
      31             : #include "vm/exceptions.hpp"
      32             : #include "vm/stackmap.hpp"
      33             : #include "vm/statistics.hpp"
      34             : #include "vm/options.hpp"
      35             : #include "vm/suck.hpp"
      36             : 
      37             : STAT_DECLARE_VAR(int,size_stack_map,0)
      38             : 
      39             : struct classinfo;
      40             : 
      41             : using namespace cacao;
      42             : 
      43             : 
      44             : /* stackmap_get_verification_type_info *****************************************
      45             : 
      46             :    union verification_type_info {
      47             :        Top_variable_info;
      48             :            Integer_variable_info;
      49             :            Float_variable_info;
      50             :            Long_variable_info;
      51             :            Double_variable_info;
      52             :            Null_variable_info;
      53             :            UninitializedThis_variable_info;
      54             :            Object_variable_info;
      55             :            Uninitialized_variable_info;
      56             :    }
      57             : 
      58             :    Top_variable_info {
      59             :        u1 tag = ITEM_Top;  // 0
      60             :    }
      61             : 
      62             :    Integer_variable_info {
      63             :        u1 tag = ITEM_Integer;  // 1
      64             :    }
      65             : 
      66             :    Float_variable_info {
      67             :        u1 tag = ITEM_Float;  // 2
      68             :    }
      69             : 
      70             :    Long_variable_info {
      71             :        u1 tag = ITEM_Long;  // 4
      72             :    }
      73             : 
      74             :    Double_variable_info {
      75             :        u1 tag = ITEM_Double;  // 3
      76             :    }
      77             : 
      78             :    Null_variable_info {
      79             :        u1 tag = ITEM_Null;  // 5
      80             :    }
      81             : 
      82             :    UninitializedThis_variable_info {
      83             :        u1 tag = ITEM_UninitializedThis;  // 6
      84             :    }
      85             : 
      86             :    Object_variable_info {
      87             :        u1 tag = ITEM_Object;  // 7
      88             :            u2 cpool_index;
      89             :    }
      90             : 
      91             :    Uninitialized_variable_info {
      92             :        u1 tag = ITEM_Uninitialized;  // 8
      93             :            u2 offset;
      94             :    }
      95             : 
      96             : *******************************************************************************/
      97             : 
      98      449857 : static bool stackmap_get_verification_type_info(ClassBuffer& cb, verification_type_info_t *verification_type_info)
      99             : {
     100             :         /* get verification type */
     101             : 
     102      449857 :         if (!cb.check_size(1))
     103           0 :                 return false;
     104             : 
     105      449857 :         verification_type_info->tag = cb.read_u1();
     106             : 
     107             :         /* process the tag */
     108             : 
     109      449857 :         switch (verification_type_info->tag) {
     110             :         case ITEM_Top:
     111             :         case ITEM_Integer:
     112             :         case ITEM_Float:
     113             :         case ITEM_Long:
     114             :         case ITEM_Double:
     115             :         case ITEM_Null:
     116             :         case ITEM_UninitializedThis:
     117      171430 :                 break;
     118             : 
     119             :         case ITEM_Object:
     120             :                 /* get constant pool index */
     121             : 
     122      274723 :                 if (!cb.check_size(2))
     123           0 :                         return false;
     124             : 
     125      274723 :                 verification_type_info->Object_variable_info.cpool_index = cb.read_u2();
     126      274723 :                 break;
     127             : 
     128             :         case ITEM_Uninitialized:
     129             :                 /* get offset */
     130             : 
     131        3704 :                 if (!cb.check_size(2))
     132           0 :                         return false;
     133             : 
     134        3704 :                 verification_type_info->Uninitialized_variable_info.offset = cb.read_u2();
     135             :                 break;
     136             :         }
     137             : 
     138      449857 :         return true;
     139             : }
     140             : 
     141             : 
     142             : /* stackmap_get_same_locals_1_stack_item_frame *********************************
     143             : 
     144             :    same_locals_1_stack_item_frame {
     145             :        u1 frame_type = SAME_LOCALS_1_STACK_ITEM;  // 64-127
     146             :            verification_type_info stack[1];
     147             :    }
     148             : 
     149             : *******************************************************************************/
     150             : 
     151       34593 : static bool stackmap_get_same_locals_1_stack_item_frame(ClassBuffer& cb, stack_map_frame_t *stack_map_frame)
     152             : {
     153             :         same_locals_1_stack_item_frame_t *same_locals_1_stack_item_frame;
     154             : 
     155             :         /* for convenience */
     156             : 
     157             :         same_locals_1_stack_item_frame =
     158       34593 :                 &(stack_map_frame->same_locals_1_stack_item_frame);
     159             : 
     160       34593 :         if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame->stack[0])))
     161           0 :                 return false;
     162             : 
     163       34593 :         return true;
     164             : }
     165             : 
     166             : 
     167             : /* stackmap_get_same_locals_1_stack_item_frame_extended ************************
     168             : 
     169             :    same_locals_1_stack_item_frame_extended {
     170             :        u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED;  // 247
     171             :            u2 offset_delta;
     172             :            verification_type_info stack[1];
     173             :    }
     174             : 
     175             : *******************************************************************************/
     176             : 
     177         148 : static bool stackmap_get_same_locals_1_stack_item_frame_extended(ClassBuffer& cb, stack_map_frame_t *stack_map_frame)
     178             : {
     179             :         same_locals_1_stack_item_frame_extended_t *same_locals_1_stack_item_frame_extended;
     180             : 
     181             :         /* for convenience */
     182             : 
     183             :         same_locals_1_stack_item_frame_extended =
     184         148 :                 &(stack_map_frame->same_locals_1_stack_item_frame_extended);
     185             : 
     186             :         /* check buffer size */
     187             : 
     188         148 :         if (!cb.check_size(2))
     189           0 :                 return false;
     190             : 
     191             :         /* get offset delta */
     192             : 
     193         148 :         same_locals_1_stack_item_frame_extended->offset_delta = cb.read_u2();
     194             : 
     195             :         /* process stack */
     196             : 
     197         148 :         if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame_extended->stack[0])))
     198           0 :                 return false;
     199             : 
     200         148 :         return true;
     201             : }
     202             : 
     203             : 
     204             : /* stackmap_get_chop_frame *****************************************************
     205             : 
     206             :    chop_frame {
     207             :        u1 frame_type = CHOP_FRAME;  // 248-250
     208             :            u2 offset_delta;
     209             :    }
     210             : 
     211             : *******************************************************************************/
     212             : 
     213       25393 : static bool stackmap_get_chop_frame(ClassBuffer& cb, stack_map_frame_t *stack_map_frame)
     214             : {
     215             :         chop_frame_t *chop_frame;
     216             : 
     217             :         /* for convenience */
     218             : 
     219       25393 :         chop_frame = &(stack_map_frame->chop_frame);
     220             : 
     221             :         /* check buffer size */
     222             : 
     223       25393 :         if (!cb.check_size(2))
     224           0 :                 return false;
     225             : 
     226             :         /* get offset delta */
     227             : 
     228       25393 :         chop_frame->offset_delta = cb.read_u2();
     229             : 
     230       25393 :         return true;
     231             : }
     232             : 
     233             : 
     234             : /* stackmap_get_same_frame_extended ********************************************
     235             : 
     236             :    same_frame_extended {
     237             :        u1 frame_type = SAME_FRAME_EXTENDED;  // 251
     238             :            u2 offset_delta;
     239             :    }
     240             : 
     241             : *******************************************************************************/
     242             : 
     243        1454 : static bool stackmap_get_same_frame_extended(ClassBuffer& cb,
     244             :                                                                                          stack_map_frame_t *stack_map_frame)
     245             : {
     246             :         same_frame_extended_t *same_frame_extended;
     247             : 
     248             :         /* for convenience */
     249             : 
     250        1454 :         same_frame_extended = &(stack_map_frame->same_frame_extended);
     251             : 
     252             :         /* check buffer size */
     253             : 
     254        1454 :         if (!cb.check_size(2))
     255           0 :                 return false;
     256             : 
     257             :         /* get offset delta */
     258             : 
     259        1454 :         same_frame_extended->offset_delta = cb.read_u2();
     260             : 
     261        1454 :         return true;
     262             : }
     263             : 
     264             : 
     265             : /* stackmap_get_append_frame ***************************************************
     266             : 
     267             :    append_frame {
     268             :        u1 frame_type = APPEND_FRAME;  // 252-254
     269             :            u2 offset_delta;
     270             :            verification_type_info locals[frame_Type - 251];
     271             :    }
     272             : 
     273             : *******************************************************************************/
     274             : 
     275      102850 : static bool stackmap_get_append_frame(ClassBuffer& cb,
     276             :                                                                           stack_map_frame_t *stack_map_frame)
     277             : {
     278             :         append_frame_t *append_frame;
     279             :         s4              number_of_locals;
     280             :         s4              i;
     281             : 
     282             :         /* for convenience */
     283             : 
     284      102850 :         append_frame = &(stack_map_frame->append_frame);
     285             : 
     286             :         /* check buffer size */
     287             : 
     288      102850 :         if (!cb.check_size(2))
     289           0 :                 return false;
     290             : 
     291             :         /* get offset delta */
     292             : 
     293      102850 :         append_frame->offset_delta = cb.read_u2();
     294             : 
     295             :         /* allocate locals array */
     296             : 
     297      102850 :         number_of_locals = append_frame->frame_type - 251;
     298             : 
     299      102850 :         append_frame->locals = DMNEW(verification_type_info_t, number_of_locals);
     300             : 
     301             :         /* process all locals */
     302             : 
     303      249775 :         for (i = 0; i < number_of_locals; i++)
     304      146925 :                 if (!stackmap_get_verification_type_info(cb, &(append_frame->locals[i])))
     305           0 :                         return false;
     306             : 
     307      102850 :         return true;
     308             : }
     309             : 
     310             : 
     311             : /* stackmap_get_full_frame *****************************************************
     312             : 
     313             :    full_frame {
     314             :        u1 frame_type = FULL_FRAME;
     315             :            u2 offset_delta;
     316             :            u2 number_of_locals;
     317             :            verification_type_info locals[number_of_locals];
     318             :            u2 number_of_stack_items;
     319             :            verification_type_info stack[number_of_stack_items];
     320             :    }
     321             : 
     322             : *******************************************************************************/
     323             : 
     324       47063 : static bool stackmap_get_full_frame(ClassBuffer& cb,
     325             :                                                                         stack_map_frame_t *stack_map_frame)
     326             : {
     327             :         full_frame_t *full_frame;
     328             :         s4 i;
     329             : 
     330             :         /* for convenience */
     331             : 
     332       47063 :         full_frame = &(stack_map_frame->full_frame);
     333             : 
     334             :         /* check buffer size */
     335             : 
     336       47063 :         if (!cb.check_size(2 + 2))
     337           0 :                 return false;
     338             : 
     339             :         /*  get offset delta */
     340             : 
     341       47063 :         stack_map_frame->full_frame.offset_delta = cb.read_u2();
     342             : 
     343             :         /* get number of locals */
     344             : 
     345       47063 :         full_frame->number_of_locals = cb.read_u2();
     346             : 
     347             :         /* allocate locals array */
     348             : 
     349             :         full_frame->locals =
     350       47063 :                 DMNEW(verification_type_info_t, full_frame->number_of_locals);
     351             : 
     352             :         /* process all locals */
     353             : 
     354      278039 :         for (i = 0; i < full_frame->number_of_locals; i++)
     355      230976 :                 if (!stackmap_get_verification_type_info(cb, &(full_frame->locals[i])))
     356           0 :                         return false;
     357             : 
     358             :         /* get number of stack items */
     359             : 
     360       47063 :         if (!cb.check_size(2))
     361           0 :                 return false;
     362             : 
     363       47063 :         full_frame->number_of_stack_items = cb.read_u2();
     364             : 
     365             :         /* allocate stack array */
     366             : 
     367             :         full_frame->stack =
     368       47063 :                 DMNEW(verification_type_info_t, full_frame->number_of_stack_items);
     369             : 
     370             :         /* process all stack items */
     371             : 
     372       84278 :         for (i = 0; i < full_frame->number_of_stack_items; i++)
     373       37215 :                 if (!stackmap_get_verification_type_info(cb, &(full_frame->stack[i])))
     374           0 :                         return false;
     375             : 
     376       47063 :         return true;
     377             : }
     378             : 
     379             : 
     380             : /* stackmap_load_attribute_stackmaptable ***************************************
     381             : 
     382             :    stack_map {
     383             :            u2 attribute_name_index;
     384             :            u4 attribute_length;
     385             :            u2 number_of_entries;
     386             :            stack_map_frame entries[number_of_entries];
     387             :    }
     388             : 
     389             :    union stack_map_frame {
     390             :        same_frame;
     391             :            same_locals_1_stack_item_frame;
     392             :            same_locals_1_stack_item_frame_extended;
     393             :            chop_frame;
     394             :            same_frame_extended;
     395             :            append_frame;
     396             :            full_frame;
     397             :    }
     398             : 
     399             :    same_frame {
     400             :        u1 frame_type = SAME;  // 0-63
     401             :    }
     402             : 
     403             : *******************************************************************************/
     404             : 
     405      148188 : bool stackmap_load_attribute_stackmaptable(ClassBuffer& cb, methodinfo *m)
     406             : {
     407             :         classinfo       *c;
     408             :         stack_map_t     *stack_map;
     409             :         s4               i;
     410             :         u1               frame_type;
     411             : 
     412             :         /* get classinfo */
     413             : 
     414      148188 :         c = cb.get_class();
     415             : 
     416             :         /* allocate stack map structure */
     417             : 
     418      148188 :         stack_map = DNEW(stack_map_t);
     419             : 
     420             :         STATISTICS(size_stack_map += sizeof(stack_map_t));
     421             : 
     422             :         /* check buffer size */
     423             : 
     424      148188 :         if (!cb.check_size(4 + 2))
     425           0 :                 return false;
     426             : 
     427             :         /* attribute_length */
     428             : 
     429      148188 :         stack_map->attribute_length = cb.read_u4();
     430             : 
     431      148188 :         if (!cb.check_size(stack_map->attribute_length))
     432           0 :                 return false;
     433             : 
     434             :         /* get number of entries */
     435             : 
     436      148188 :         stack_map->number_of_entries = cb.read_u2();
     437             : 
     438             :         /* process all entries */
     439             : 
     440      148188 :         stack_map->entries = DMNEW(stack_map_frame_t, stack_map->number_of_entries);
     441             : 
     442      621797 :         for (i = 0; i < stack_map->number_of_entries; i++) {
     443             :                 /* get the frame type */
     444             : 
     445      473609 :                 frame_type = cb.read_u1();
     446             : 
     447      473609 :                 stack_map->entries[i].frame_type = frame_type;
     448             : 
     449             :                 /* process frame */
     450             : 
     451      473609 :                 if (frame_type <= FRAME_TYPE_SAME) {
     452             :                         /* same_frame */
     453             :                 }
     454      211501 :                 else if (frame_type <= FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM) {
     455             :                         /* same_locals_1_stack_item_frame */
     456             : 
     457       34593 :                         if (!stackmap_get_same_locals_1_stack_item_frame(cb, &(stack_map->entries[i])))
     458           0 :                                 return false;
     459             :                 }
     460      176908 :                 else if (frame_type <= FRAME_TYPE_RESERVED) {
     461             :                         /* reserved */
     462             : 
     463           0 :                         exceptions_throw_classformaterror(c, "reserved frame type");
     464           0 :                         return false;
     465             :                 }
     466      176908 :                 else if (frame_type == FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
     467             :                         /* same_locals_1_stack_item_frame_extended */
     468             : 
     469         148 :                         if (!stackmap_get_same_locals_1_stack_item_frame_extended(cb, &(stack_map->entries[i])))
     470           0 :                                 return false;
     471             :                 }
     472      176760 :                 else if (frame_type <= FRAME_TYPE_CHOP) {
     473             :                         /* chop_frame */
     474             : 
     475       25393 :                         if (!stackmap_get_chop_frame(cb, &(stack_map->entries[i])))
     476           0 :                                 return false;
     477             :                 }
     478      151367 :                 else if (frame_type == FRAME_TYPE_SAME_FRAME_EXTENDED) {
     479             :                         /* same_frame_extended */
     480             : 
     481        1454 :                         if (!stackmap_get_same_frame_extended(cb, &(stack_map->entries[i])))
     482           0 :                                 return false;
     483             :                 }
     484      149913 :                 else if (frame_type <= FRAME_TYPE_APPEND) {
     485             :                         /* append_frame */
     486             : 
     487      102850 :                         if (!stackmap_get_append_frame(cb, &(stack_map->entries[i])))
     488           0 :                                 return false;
     489             :                 }
     490       47063 :                 else if (frame_type == FRAME_TYPE_FULL_FRAME) {
     491             :                         /* full_frame */
     492             : 
     493       47063 :                         if (!stackmap_get_full_frame(cb, &(stack_map->entries[i])))
     494           0 :                                 return false;
     495             :                 }
     496             :         }
     497             : 
     498             :         /* store stack map in method structure */
     499             : 
     500             : #if 0
     501             :         /* currently not used */
     502             : 
     503             :         m->stack_map = stack_map;
     504             : #endif
     505             : 
     506      148188 :         return true;
     507             : }
     508             : 
     509             : 
     510             : /*
     511             :  * These are local overrides for various environment variables in Emacs.
     512             :  * Please do not remove this and leave it at the end of the file, where
     513             :  * Emacs will automagically detect them.
     514             :  * ---------------------------------------------------------------------
     515             :  * Local variables:
     516             :  * mode: c++
     517             :  * indent-tabs-mode: t
     518             :  * c-basic-offset: 4
     519             :  * tab-width: 4
     520             :  * End:
     521             :  * vim:noexpandtab:sw=4:ts=4:
     522             :  */

Generated by: LCOV version 1.11