DEADSOFTWARE

Patched for Linux
[mp3cc.git] / MPC.3.5.LINUX / classgen / preverify.c
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"
15 #include "../util/error.h"
16 #include "../util/strings.h"
17 #include "../structures/type_list.h"
18 #include "../structures/string_list.h"
19 #include "../structures/type.h"
20 #include "../structures/identifier.h"
21 #include "../structures/name_table.h"
22 #include "constant_pool.h"
23 #include "bytecode.h"
24 #include "preverify.h"
25 #include "../util/error.h"
26 //#include "../util/message.h"
27 #include "../util/memory.h"
29 extern constant_pool *constants;
30 extern int constant_pool_size;
32 stack_map_list *pending_list;
33 stack_map_list *output_list;
36 stack_map_list *preverify_bytecode(bytecode *code, identifier *block_identifier)
37 {
38 stack_map *map;
39 pending_list = NULL;
40 output_list = NULL;
42 /* go through the bytecode */
43 map = stack_map_create();
44 map->bytecode_offset = 0;
45 preverify_bytecode_from(map, code, block_identifier);
46 stack_map_destroy(map);
48 /* revisit the offsets in the pending list */
49 while (pending_list != NULL)
50 {
51 map = stack_map_list_get(&pending_list);
52 if (map == NULL)
53 break;
55 stack_map_list_append(&output_list, stack_map_duplicate(map));
56 preverify_bytecode_from(map, code, block_identifier);
57 stack_map_destroy(map);
58 }
60 output_list = sort_map_list(output_list);
62 return output_list;
63 }
66 /*
67 Sorts the list according to offsets
68 */
69 stack_map_list* sort_map_list(stack_map_list *list)
70 {
71 int range = 0;
73 stack_map_list *it;
74 stack_map_list *sorted_list = NULL;
76 /* repeat until the list is empty */
77 while (list != NULL)
78 {
79 /* find the next smallest number */
80 int smallest = 0x0fffffff;
82 it = list;
83 while (it != NULL)
84 {
85 if ((it->data->bytecode_offset < smallest)
86 && (it->data->bytecode_offset >= range))
87 smallest = it->data->bytecode_offset;
88 it = it->next;
89 }
91 if (smallest == 0x0fffffff)
92 break;
94 range = smallest + 1;
96 /* extract the smallest number into the output list */
97 it = list;
98 while (it != NULL)
99 {
100 if (it->data->bytecode_offset == smallest)
102 stack_map_list_append(&sorted_list, it->data);
104 break;
105 }
106 it = it->next;
111 return sorted_list;
115 /*
116 Preverifies the bytecode starting with the given stackmap
117 */
118 void preverify_bytecode_from(stack_map *map, bytecode *code, identifier *block_identifier)
120 int offset;
121 offset = map->bytecode_offset;
123 while (preverify_consume_bytecode(code, map, &offset, block_identifier))
125 /* do nothing */
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)
139 unsigned char opcode = code->bytecode[*offset];
140 switch ((unsigned char)(code->bytecode[*offset]))
142 case nop$:
143 (*offset) ++;
144 break;
146 case aconst_null$:
147 (*offset) ++;
148 stack_map_push_entry(map, ITEM_Null, 0);
149 break;
151 case iconst_m1$:
152 case iconst_0$:
153 case iconst_1$:
154 case iconst_2$:
155 case iconst_3$:
156 case iconst_4$:
157 case iconst_5$:
158 (*offset) ++;
159 stack_map_push_entry(map, ITEM_Integer, 0);
160 break;
162 case lconst_0$:
163 case lconst_1$:
164 (*offset) ++;
165 stack_map_push_entry(map, ITEM_Long, 0);
166 break;
168 case bipush$:
169 (*offset) += 2;
170 stack_map_push_entry(map, ITEM_Integer, 0);
171 break;
173 case sipush$:
174 (*offset) += 3;
175 stack_map_push_entry(map, ITEM_Integer, 0);
176 break;
178 case iload$:
179 (*offset) += 2;
180 stack_map_push_entry(map, ITEM_Integer, 0);
181 break;
183 case lload$:
184 (*offset) += 2;
185 stack_map_push_entry(map, ITEM_Long, 0);
186 break;
188 case iload_0$:
189 case iload_1$:
190 case iload_2$:
191 case iload_3$:
192 (*offset) ++;
193 stack_map_push_entry(map, ITEM_Integer, 0);
194 break;
196 case lload_0$:
197 case lload_1$:
198 case lload_2$:
199 case lload_3$:
200 (*offset) ++;
201 stack_map_push_entry(map, ITEM_Long, 0);
202 break;
204 case iaload$:
205 case baload$:
206 case caload$:
207 case saload$:
208 (*offset) ++;
209 stack_entry_destroy(stack_map_pop(map));
210 stack_entry_destroy(stack_map_pop(map));
211 stack_map_push_entry(map, ITEM_Integer, 0);
212 break;
214 case laload$:
215 (*offset) ++;
216 stack_entry_destroy(stack_map_pop(map));
217 stack_entry_destroy(stack_map_pop(map));
218 stack_map_push_entry(map, ITEM_Long, 0);
219 break;
221 case istore$:
222 case lstore$:
223 case astore$:
224 (*offset) += 2;
225 stack_entry_destroy(stack_map_pop(map));
226 break;
228 case istore_0$:
229 case istore_1$:
230 case istore_2$:
231 case istore_3$:
232 case lstore_0$:
233 case lstore_1$:
234 case lstore_2$:
235 case lstore_3$:
236 case astore_0$:
237 case astore_1$:
238 case astore_2$:
239 case astore_3$:
240 (*offset) ++;
241 stack_entry_destroy(stack_map_pop(map));
242 break;
244 case iastore$:
245 case lastore$:
246 case fastore$:
247 case dastore$:
248 case aastore$:
249 case bastore$:
250 case castore$:
251 case sastore$:
252 (*offset) ++;
253 stack_entry_destroy(stack_map_pop(map));
254 stack_entry_destroy(stack_map_pop(map));
255 stack_entry_destroy(stack_map_pop(map));
256 break;
258 case pop$:
259 (*offset) ++;
260 stack_entry_destroy(stack_map_pop(map));
261 break;
263 case pop2$:
264 (*offset) ++;
265 stack_entry_destroy(stack_map_pop(map));
266 stack_entry_destroy(stack_map_pop(map));
267 break;
269 case dup$:
271 stack_entry *entry;
272 (*offset) ++;
273 entry = stack_map_pop(map);
274 stack_map_push(map, entry);
275 stack_map_push(map, entry);
276 stack_entry_destroy(entry);
278 break;
280 case dup_x1$:
281 case dup_x2$:
283 stack_entry *e1, *e2;
284 (*offset) ++;
285 e1 = stack_map_pop(map);
286 e2 = stack_map_pop(map);
287 stack_map_push(map, e1);
288 stack_map_push(map, e2);
289 stack_map_push(map, e1);
290 stack_entry_destroy(e1);
291 stack_entry_destroy(e2);
293 break;
295 case dup2_x1$:
297 stack_entry *e1, *e2, *e3;
298 (*offset) ++;
299 e1 = stack_map_pop(map);
300 e2 = stack_map_pop(map);
301 e3 = stack_map_pop(map);
302 stack_map_push(map, e2);
303 stack_map_push(map, e1);
304 stack_map_push(map, e3);
305 stack_map_push(map, e2);
306 stack_map_push(map, e1);
307 stack_entry_destroy(e1);
308 stack_entry_destroy(e2);
309 stack_entry_destroy(e3);
311 break;
313 case swap$:
315 stack_entry *e1, *e2;
316 (*offset) ++;
317 e1 = stack_map_pop(map);
318 e2 = stack_map_pop(map);
319 stack_map_push(map, e1);
320 stack_map_push(map, e2);
321 stack_entry_destroy(e1);
322 stack_entry_destroy(e2);
324 break;
326 case iadd$:
327 case ladd$:
328 case fadd$:
329 case dadd$:
330 case isub$:
331 case lsub$:
332 case fsub$:
333 case dsub$:
334 case imul$:
335 case lmul$:
336 case fmul$:
337 case dmul$:
338 case idiv$:
339 case ldiv$:
340 case fdiv$:
341 case ddiv$:
342 case irem$:
343 case lrem$:
344 case frem$:
345 case drem$:
346 case iand$:
347 case land$:
348 case ior$:
349 case lor$:
350 case ixor$:
351 case lxor$:
352 (*offset) ++;
353 stack_entry_destroy(stack_map_pop(map));
354 break;
356 case ineg$:
357 case lneg$:
358 case fneg$:
359 case dneg$:
360 case i2b$:
361 case i2c$:
362 case i2s$:
363 (*offset) ++;
364 break;
366 case ishl$:
367 case lshl$:
368 case ishr$:
369 case lshr$:
370 case iushr$:
371 case lushr$:
372 (*offset) ++;
373 stack_entry_destroy(stack_map_pop(map));
374 break;
376 case iinc$:
377 (*offset) += 3;
378 break;
380 case i2l$:
381 (*offset) ++;
382 stack_entry_destroy(stack_map_pop(map));
383 stack_map_push_entry(map, ITEM_Long, 0);
384 break;
386 case l2i$:
387 (*offset) ++;
388 stack_entry_destroy(stack_map_pop(map));
389 stack_map_push_entry(map, ITEM_Integer, 0);
390 break;
392 case lcmp$:
393 case fcmpl$:
394 case fcmpg$:
395 case dcmpl$:
396 case dcmpg$:
397 (*offset) ++;
398 stack_entry_destroy(stack_map_pop(map));
399 stack_entry_destroy(stack_map_pop(map));
400 stack_map_push_entry(map, ITEM_Integer, 0);
401 break;
403 case ifeq$:
404 case ifne$:
405 case iflt$:
406 case ifge$:
407 case ifgt$:
408 case ifle$:
409 (*offset) ++;
410 stack_entry_destroy(stack_map_pop(map));
411 process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
412 (*offset) ++;
413 (*offset) ++;
414 break;
416 case if_icmpeq$:
417 case if_icmpne$:
418 case if_icmplt$:
419 case if_icmpge$:
420 case if_icmpgt$:
421 case if_icmple$:
422 case if_acmpeq$:
423 case if_acmpne$:
424 (*offset) ++;
425 stack_entry_destroy(stack_map_pop(map));
426 stack_entry_destroy(stack_map_pop(map));
427 process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
428 (*offset) ++;
429 (*offset) ++;
430 break;
432 case goto$:
434 (*offset) ++;
435 process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
436 return 0;
438 break;
440 case ireturn$:
441 case lreturn$:
442 case freturn$:
443 case dreturn$:
444 case areturn$:
445 stack_entry_destroy(stack_map_pop(map));
446 case return$:
447 return 0;
449 case aload$:
450 (*offset) += 2;
451 stack_map_push_local(map, block_identifier, (unsigned char) code->bytecode[*offset-1]);
452 break;
454 case aload_0$:
455 (*offset) ++;
456 stack_map_push_local(map, block_identifier, 0);
457 break;
459 case aload_1$:
460 (*offset) ++;
461 stack_map_push_local(map, block_identifier, 1);
462 break;
464 case aload_2$:
465 (*offset) ++;
466 stack_map_push_local(map, block_identifier, 2);
467 break;
469 case aload_3$:
470 (*offset) ++;
471 stack_map_push_local(map, block_identifier, 3);
472 break;
474 case aaload$:
476 char object_class[128];
477 stack_entry* entry;
478 int classname_index;
479 int delta = 1;
481 (*offset) ++;
482 stack_entry_destroy(stack_map_pop(map));
484 entry = stack_map_pop(map);
485 classname_index = constants[entry->additional_data - 1].param1 - 1;
486 strncpy(object_class, constants[classname_index].data, constants[classname_index].data_len);
487 object_class[constants[classname_index].data_len] = '\0';
489 if (object_class[1] == 'L')
491 delta = 2;
492 object_class[strlen(object_class) - 1] = '\0';
494 stack_entry_destroy(entry);
495 stack_map_push_entry(map, ITEM_Object, cp_add_class(object_class + delta));
497 break;
499 case tableswitch$:
500 case lookupswitch$:
501 // TODO::
502 break;
504 case instanceof$:
505 (*offset) += 3;
506 stack_entry_destroy(stack_map_pop(map));
507 stack_map_push_entry(map, ITEM_Integer, 0);
508 break;
510 case ldc$:
511 (*offset) ++;
512 (*offset) ++;
513 stack_map_push_entry(map, ITEM_Bogus, 0);
514 break;
516 case ldc_w$:
517 (*offset) += 3;
518 stack_map_push_entry(map, ITEM_Bogus, 0);
519 break;
521 case getstatic$:
523 int t;
524 (*offset) ++;
525 t = code->bytecode[*offset];
526 t = t << 8 | (unsigned char)(code->bytecode[(*offset) + 1]);
527 t = constants[t-1].param2;
528 t = constants[t-1].param2;
529 (*offset) += 2;
530 switch(constants[t-1].data[0])
532 case 'L':
533 case '[':
535 char *class_name = (char*) mem_alloc(sizeof(char) * strlen(constants[t-1].data));
536 strcpy(class_name, constants[t-1].data + 1);
537 class_name[strlen(constants[t-1].data) - 2] = '\0';
538 stack_map_push_entry(map, ITEM_Object, cp_add_class(class_name));
539 mem_free(class_name);
540 break;
542 // case '[':
543 // stack_map_push_entry(map, ITEM_Object, t);
544 // break;
545 case 'I':
546 stack_map_push_entry(map, ITEM_Integer, 0);
547 break;
548 default:
549 stack_map_push_entry(map, ITEM_Bogus, 0);
553 break;
555 case new$:
556 (*offset) += 3;
557 stack_map_push_entry(map, ITEM_Bogus, 0);
558 break;
560 case getfield$:
561 (*offset) += 3;
562 break;
564 case putstatic$:
565 (*offset) += 3;
566 stack_entry_destroy(stack_map_pop(map));
567 break;
569 case putfield$:
570 (*offset) += 3;
571 stack_entry_destroy(stack_map_pop(map));
572 stack_entry_destroy(stack_map_pop(map));
573 break;
575 case invokevirtual$:
576 case invokespecial$:
577 case invokestatic$:
579 unsigned short int num;
580 int len, i = 0;
581 int oldstate, state = 0;
582 int count = 0;
583 int isVoid = 0;
584 char *descriptor;
585 char *class_name;
586 int state_machine_table[4][6] =
587 { /* ( ) L ; V else */
588 /* 0 */ { 1, -1, -1, -1, -1, -1 },
589 /* 1 */ {-1, 2, 3, -1, 1, 1 },
590 /* 2 */ {-1, -1, -1, -1, -1, -1 },
591 /* 3 */ { 3, 3, 3, 1, 3, 3 }
592 };
594 (*offset) ++;
595 num = (code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1]);
596 (*offset) += 2;
598 num = constants[num-1].param2;
599 num = constants[num-1].param2;
600 len = constants[num-1].data_len;
601 descriptor = constants[num-1].data;
603 while (i < len)
605 oldstate = state;
607 switch (descriptor[i])
609 case '(': state = state_machine_table[state][0]; break;
610 case ')': state = state_machine_table[state][1]; break;
611 case 'L': state = state_machine_table[state][2]; break;
612 case ';': state = state_machine_table[state][3]; break;
613 case 'V': state = state_machine_table[state][4]; break;
614 default : state = state_machine_table[state][5]; break;
616 i ++;
618 if ((state == 1) && (oldstate != 0))
619 count ++;
621 if (state == 2)
623 if (descriptor[i] == 'V')
624 isVoid = 1;
626 class_name = (char*) mem_alloc(len);
628 strcpy(class_name, descriptor + i);
630 break;
634 if (opcode != invokestatic$)
635 stack_entry_destroy(stack_map_pop(map));
636 while (count > 0)
638 stack_entry_destroy(stack_map_pop(map));
639 count --;
642 if (class_name[0] == 'L')
644 class_name[strlen(class_name) - 1] = '\0';
645 if (!isVoid)
646 stack_map_push_entry(map, ITEM_Object, cp_add_class(class_name+1));
648 else if (class_name[0] == 'I')
650 if (!isVoid)
651 stack_map_push_entry(map, ITEM_Integer,0);
653 else
655 if (!isVoid)
656 stack_map_push_entry(map, ITEM_Bogus, 0);
660 mem_free(class_name);
662 break;
665 /*case invokestatic$:
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)
692 oldstate = state;
694 switch (descriptor[i])
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;
703 i ++;
705 if ((state == 1) && (oldstate != 0))
706 count ++;
708 if (state == 2)
710 if (descriptor[i] == 'V')
711 isVoid = 1;
713 break;
717 while (count > 0)
719 stack_entry_destroy(stack_map_pop(map));
720 count --;
723 if (!isVoid)
724 stack_map_push_entry(map, ITEM_Bogus, 0);
726 break;*/
729 case newarray$:
730 (*offset) += 2;
731 break;
733 case anewarray$:
734 (*offset) += 3;
735 break;
737 case arraylength$:
738 (*offset) ++;
739 stack_entry_destroy(stack_map_pop(map));
740 stack_map_push_entry(map, ITEM_Integer, 0);
741 break;
743 case multianewarray$:
745 unsigned int i, t, s;
746 (*offset) ++;
747 t = code->bytecode[*offset];
748 t = t << 8 | (unsigned char)(code->bytecode[(*offset) + 1]);
749 (*offset) += 2;
750 i = code->bytecode[*offset];
751 (*offset) ++;
753 s = i;
754 while (i>0)
756 stack_entry_destroy(stack_map_pop(map));
757 i --;
760 stack_map_push_entry(map, ITEM_NewObject, *offset - 4);
761 break;
764 case ifnull$:
765 case ifnonnull$:
766 stack_entry_destroy(stack_map_pop(map));
767 (*offset) ++;
768 process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
769 (*offset) ++;
770 (*offset) ++;
771 break;
773 default:
774 die(22);
778 return 1;
782 /*
783 When a branch instruction is found, adds the target offset into the list.
784 */
785 void process_jump(stack_map *map, int position)
787 stack_map *new_map;
789 /* check if the position is already in the pending or output list */
790 stack_map_list *it;
791 it = pending_list;
793 while (it != NULL)
795 if (it->data->bytecode_offset == position)
796 return;
797 it = it->next;
800 it = output_list;
802 while (it != NULL)
804 if (it->data->bytecode_offset == position)
805 return;
806 it = it->next;
809 /* if here, add the offset into the pendign list */
810 new_map = stack_map_duplicate(map);
811 new_map->bytecode_offset = position;
812 stack_map_list_append(&pending_list, new_map);
816 /*
817 Create anew stack_entry object.
818 */
819 stack_entry* stack_entry_create()
821 stack_entry *new_entry = (stack_entry*) mem_alloc(sizeof(stack_entry));
823 if (new_entry == NULL)
824 die(1);
826 return new_entry;
830 /*
831 Delete all data used by stack_entry
832 */
833 void stack_entry_destroy(stack_entry *entry)
835 mem_free(entry);
839 /*
840 Create a copy of the stack entry.
841 */
842 stack_entry* stack_entry_duplicate(stack_entry *old_entry)
844 stack_entry* new_entry = (stack_entry*) mem_alloc(sizeof(stack_entry));
846 if (new_entry == NULL)
847 die(1);
849 new_entry->item_type = old_entry->item_type;
850 new_entry->additional_data = old_entry->additional_data;
852 return new_entry;
856 /*
857 Create a stackmap object
858 */
859 stack_map* stack_map_create()
861 stack_map *new_map = (stack_map*) mem_alloc(sizeof(stack_map));
863 if (new_map == NULL)
864 die(1);
866 new_map->allocated_number_of_items = 0;
867 new_map->number_of_items = 0;
869 return new_map;
873 /*
874 Destroy the stack map
875 */
876 void stack_map_destroy(stack_map *map)
878 int i;
879 for (i=0; i<map->number_of_items; i++)
881 stack_entry_destroy(map->stack[i]);
884 if (map->allocated_number_of_items > 0)
885 mem_free(map->stack);
887 mem_free(map);
891 /*
892 Create a copy of the map
893 */
894 stack_map* stack_map_duplicate(stack_map *old_map)
896 int i;
898 stack_map *new_map = (stack_map*) mem_alloc(sizeof(stack_map));
900 if (new_map == NULL)
901 die(1);
903 new_map->number_of_items = old_map->number_of_items;
904 new_map->allocated_number_of_items = old_map->allocated_number_of_items;
905 new_map->bytecode_offset = old_map->bytecode_offset;
907 if (old_map->allocated_number_of_items > 0)
909 new_map->stack = (stack_entry**) mem_alloc(sizeof(stack_entry) * old_map->allocated_number_of_items);
911 if (new_map->stack == NULL)
912 die(1);
915 for (i=0; i<old_map->number_of_items; i++)
916 new_map->stack[i] = stack_entry_duplicate(old_map->stack[i]);
918 return new_map;
922 /*
923 Take the top element from the stack
924 */
925 stack_entry* stack_map_pop(stack_map* map)
927 stack_entry* top_element;
929 top_element = map->stack[map->number_of_items - 1];
931 map->number_of_items --;
933 return top_element;
937 /*
938 Add a new element to the top of the stack
939 */
940 void stack_map_push(stack_map *map, stack_entry *entry)
942 stack_map_push_entry(map, entry->item_type, entry->additional_data);
946 /*
947 Add a new element to the top of the stack.
948 */
949 void stack_map_push_entry(stack_map *map, enum stack_item item_type, short int additional_data)
951 stack_entry *new_entry = stack_entry_create();
952 new_entry->item_type = item_type;
953 new_entry->additional_data = additional_data;
955 /*
956 Do realloc or malloc if needeed
957 */
958 if (map->allocated_number_of_items <= map->number_of_items)
960 if (map->allocated_number_of_items == 0)
962 map->stack = (stack_entry**) mem_alloc(sizeof(stack_entry*));
964 if (map->stack == NULL)
965 die(1);
967 map->allocated_number_of_items = 1;
969 else
971 map->stack = (stack_entry**) mem_realloc(map->stack, sizeof(stack_entry*) * (map->allocated_number_of_items + 1));
973 if (map->stack == NULL)
974 die(1);
976 map->allocated_number_of_items ++;
980 map->number_of_items ++;
981 map->stack[map->number_of_items - 1] = new_entry;
984 void stack_map_list_destroy(stack_map_list*);
986 /*
987 Push a local variable, determine its type
988 */
989 void stack_map_push_local(stack_map *map, identifier *block_identifier, int localNum)
991 type *variable_type = NULL;
992 char descriptor[256];
993 type_list *it;
994 int i = 0;
996 if (block_identifier == NULL)
998 /* if block is the root block, this should never happen */
999 stack_map_push_entry(map, ITEM_Bogus, 0);
1000 return;
1003 it = block_identifier->parameters;
1004 while (it != NULL)
1006 if (it->data == NULL)
1007 break;
1009 if (i == localNum)
1011 variable_type = type_duplicate(it->data);
1012 break;
1014 i ++;
1015 it = it->next;
1019 if ((block_identifier->identifier_class == function_name)
1020 && (variable_type == NULL))
1022 if (i == localNum)
1023 variable_type = type_duplicate(block_identifier->return_type);
1024 i ++;
1027 it = block_identifier->variables;
1028 while ((it != NULL) && (variable_type == NULL))
1030 if (it->data == NULL)
1031 break;
1033 if (i == localNum)
1035 variable_type = type_duplicate(it->data);
1036 break;
1038 i ++;
1039 it = it->next;
1042 switch (variable_type->type_class)
1044 case integer_type:
1045 case real_type:
1046 case char_type:
1047 case boolean_type:
1048 stack_map_push_entry(map, ITEM_Integer, 0);
1049 break;
1051 case array_type:
1052 get_field_descriptor(variable_type, descriptor);
1053 stack_map_push_entry(map, ITEM_Object, cp_add_class(descriptor));
1054 break;
1056 default:
1057 get_field_descriptor(variable_type, descriptor);
1058 descriptor[strlen(descriptor)-1] = '\0';
1059 stack_map_push_entry(map, ITEM_Object, cp_add_class(descriptor+1));
1060 break;
1063 type_destroy(variable_type);
1067 /*
1068 Append data to the end of the list
1069 */
1070 void stack_map_list_append(stack_map_list **list, stack_map* data)
1072 stack_map_list *it;
1074 if (*list == NULL)
1076 *list = (stack_map_list*)mem_alloc(sizeof(stack_map_list));
1077 if (*list == NULL)
1078 die(1);
1080 (*list)->data = data;
1081 (*list)->next = NULL;
1082 return;
1085 it = *list;
1087 while (it->next != NULL)
1088 it = it->next;
1090 it->next = (stack_map_list*) mem_alloc(sizeof(stack_map_list));
1092 if (it->next == NULL)
1093 die(1);
1095 it->next->data = data;
1096 it->next->next = NULL;
1102 /*
1103 Get the first element from the list
1104 */
1105 stack_map* stack_map_list_get(stack_map_list **list)
1107 stack_map_list *next;
1108 stack_map *data;
1110 if (*list == NULL)
1111 return NULL;
1113 next = (*list)->next;
1114 data = (*list)->data;
1116 *list = next;
1118 return data;