1 /********************************************************************
3 preverify.c - methods for preverifing class files
5 Niksa Orlic, 2004-05-16
7 ********************************************************************/
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdio.h>
14 //#include "../util/message.h"
26 //#include "../util/message.h"
37 {
42 /* go through the bytecode */
48 /* revisit the offsets in the pending list */
50 {
58 }
63 }
66 /*
67 Sorts the list according to offsets
68 */
70 {
76 /* repeat until the list is empty */
78 {
79 /* find the next smallest number */
84 {
89 }
96 /* extract the smallest number into the output list */
99 {
101 {
105 }
107 }
109 }
112 }
115 /*
116 Preverifies the bytecode starting with the given stackmap
117 */
119 {
124 {
125 /* do nothing */
126 }
127 }
130 /*
131 Reads one bytecode and updates stack map. Returns 0 if
132 'return' bytocode is found, or 1 otherwise.
134 It seems that most of the jumps have nothing on the stack. The few
135 jumps that have something on the stack will only have integers.
136 */
137 int preverify_consume_bytecode(bytecode *code, stack_map *map, int *offset, identifier *block_identifier)
138 {
141 {
270 {
277 }
282 {
292 }
296 {
310 }
314 {
323 }
411 process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
427 process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
433 {
435 process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
437 }
475 {
490 {
493 }
496 }
501 // TODO::
522 {
531 {
534 {
541 }
542 // case '[':
543 // stack_map_push_entry(map, ITEM_Object, t);
544 // break;
551 }
552 }
578 {
592 };
604 {
608 {
615 }
616 i ++;
619 count ++;
622 {
631 }
632 }
637 {
639 count --;
640 }
643 {
647 }
649 {
652 }
653 else
654 {
658 }
661 }
665 /*case invokestatic$:
666 {
667 unsigned short int num;
668 int len, i = 0;
669 int oldstate, state = 0;
670 int count = 0;
671 int isVoid = 0;
672 char *descriptor;
673 int state_machine_table[4][6] =
674 { /* ( ) L ; V else
675 /* 0 { 1, -1, -1, -1, -1, -1 },
676 /* 1 {-1, 2, 3, -1, 1, 1 },
677 /* 2 {-1, -1, -1, -1, -1, -1 },
678 /* 3 { 3, 3, 3, 1, 3, 3 }
679 };
681 (*offset) ++;
682 num = (code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1]);
683 (*offset) += 2;
685 num = constants[num-1].param2;
686 num = constants[num-1].param2;
687 len = constants[num-1].data_len;
688 descriptor = constants[num-1].data;
690 while (i < len)
691 {
692 oldstate = state;
694 switch (descriptor[i])
695 {
696 case '(': state = state_machine_table[state][0]; break;
697 case ')': state = state_machine_table[state][1]; break;
698 case 'L': state = state_machine_table[state][2]; break;
699 case ';': state = state_machine_table[state][3]; break;
700 case 'V': state = state_machine_table[state][4]; break;
701 default : state = state_machine_table[state][5]; break;
702 }
703 i ++;
705 if ((state == 1) && (oldstate != 0))
706 count ++;
708 if (state == 2)
709 {
710 if (descriptor[i] == 'V')
711 isVoid = 1;
713 break;
714 }
715 }
717 while (count > 0)
718 {
719 stack_entry_destroy(stack_map_pop(map));
720 count --;
721 }
723 if (!isVoid)
724 stack_map_push_entry(map, ITEM_Bogus, 0);
725 }
726 break;*/
744 {
755 {
757 i --;
758 }
762 }
768 process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
776 }
779 }
782 /*
783 When a branch instruction is found, adds the target offset into the list.
784 */
786 {
789 /* check if the position is already in the pending or output list */
794 {
798 }
803 {
807 }
809 /* if here, add the offset into the pendign list */
813 }
816 /*
817 Create anew stack_entry object.
818 */
820 {
827 }
830 /*
831 Delete all data used by stack_entry
832 */
834 {
836 }
839 /*
840 Create a copy of the stack entry.
841 */
843 {
853 }
856 /*
857 Create a stackmap object
858 */
860 {
870 }
873 /*
874 Destroy the stack map
875 */
877 {
880 {
882 }
888 }
891 /*
892 Create a copy of the map
893 */
895 {
908 {
909 new_map->stack = (stack_entry**) mem_alloc(sizeof(stack_entry) * old_map->allocated_number_of_items);
913 }
919 }
922 /*
923 Take the top element from the stack
924 */
926 {
934 }
937 /*
938 Add a new element to the top of the stack
939 */
941 {
943 }
946 /*
947 Add a new element to the top of the stack.
948 */
950 {
955 /*
956 Do realloc or malloc if needeed
957 */
959 {
961 {
968 }
969 else
970 {
971 map->stack = (stack_entry**) mem_realloc(map->stack, sizeof(stack_entry*) * (map->allocated_number_of_items + 1));
977 }
978 }
982 }
986 /*
987 Push a local variable, determine its type
988 */
990 {
997 {
998 /* if block is the root block, this should never happen */
1001 }
1005 {
1010 {
1013 }
1014 i ++;
1016 }
1021 {
1024 i ++;
1025 }
1029 {
1034 {
1037 }
1038 i ++;
1040 }
1043 {
1061 }
1065 }
1067 /*
1068 Append data to the end of the list
1069 */
1071 {
1075 {
1083 }
1099 }
1102 /*
1103 Get the first element from the list
1104 */
1106 {
1119 }