1 /********************************************************************
3 block.h - structures and functions used to hold program
4 block descriptions
6 Niksa Orlic, 2004-04-29
8 ********************************************************************/
13 //#include "../util/message.h"
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdio.h>
60 #pragma warning (disable:4305)
61 #pragma warning (disable:4761)
63 /*
64 Create an empty block
65 */
67 {
83 }
86 /*
87 Delete a block
88 */
90 {
95 /* delete all of its children */
97 {
99 }
102 {
104 }
106 /* do not delete the item->block_name */
108 }
111 /*
112 Check if a given name is legal name for a
113 new identifier in a block.
114 */
116 {
126 {
131 else
133 }
135 /* check the root block's types - those types are protected */
137 {
145 }
150 }
152 /*
153 Adds a single real constant into the block
154 */
156 {
167 }
170 /*
171 Adds a single integer constant into the block
172 */
174 {
185 }
188 /*
189 Adds a single character constant into the block
190 */
192 {
203 }
206 /*
207 Adds a single boolean constant into the block
208 */
210 {
221 }
224 /*
225 Adds a single string constant into the block
226 */
228 {
239 }
242 /*
243 Adds variables into a block. The variable names are
244 located inside a string list, and a type for all
245 the variables is described in var_type parameter.
246 */
248 {
256 {
259 }
262 {
266 }
267 else
271 {
272 // j-a-s-d: consecutive variable name collision fix
274 {
276 }
286 else
295 }
297 }
299 /*
300 Add a type into block. The name and type_type
301 are NOT copied.
302 */
304 {
311 }
314 /*
315 Adds a procedure declaration into the block
316 */
319 {
325 {
334 }
335 else
336 {
343 }
344 }
347 /*
348 Adds a function declaration into the block
349 */
352 {
358 {
367 }
368 else
369 {
377 }
378 }
381 /*
382 Loads (inserts) an external library into the project - load the class file and
383 enumerate all static functions.
384 */
386 {
396 /* create the full path to the library file */
397 /* global library directory */
399 #ifdef WIN32
401 #endif
402 #ifdef UNIX
404 #endif
407 /* project library directory */
409 #ifdef WIN32
411 #endif
412 #ifdef UNIX
414 #endif
419 {
423 }
425 /* create a new unit object */
432 /* try open the library file from the libraries directories */
435 {
437 }
439 {
440 /* if this fails, try to open an unit file */
443 #ifdef WIN32
445 #endif
446 #ifdef UNIX
448 #endif
455 {
456 // j-a-s-d: if unit is not found it must stop only if compiling
458 {
461 }
463 }
470 }
472 /* read the library file */
474 {
479 }
482 {
487 }
495 {
497 {
500 }
501 else
502 {
507 }
508 }
511 {
512 save_unit_name:
514 {
517 }
518 else
519 {
524 }
525 }
528 lel_finally:
532 }
535 /*
536 Reads the library file.
537 */
539 {
546 /* read and check magic number */
551 )
552 {
557 }
559 /* skip major and minor count */
562 /* read the number of constant pool entries */
565 /* allocate and read the constant pool */
569 {
577 {
608 }
609 }
615 /* TODO:: check that this class has the proper name, no package etc. */
616 /* check access flags */
619 {
621 }
623 /* TODO:: are there some limitations on super class? */
625 /* skip over the implemented interfaces */
628 {
630 }
632 /* skip over the fields */
635 {
642 {
647 }
648 }
650 /* read the methods and add them into the program scope */
654 {
664 /* read the method's attributes */
667 /* if the method is declared as 'public static' consider
668 adding it into the unit interface */
670 {
682 /* check that method parameters and return value are OK */
686 {
688 {
690 }
691 else
693 {
699 else
700 {
703 }
705 }
706 else
707 if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/lcdui/Image;", 32) == 0))
708 {
714 else
715 {
718 }
720 }
721 else
722 if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/lcdui/Command;", 34) == 0))
723 {
729 else
730 {
733 }
735 }
736 else
738 {
744 else
745 {
748 }
750 }
751 else
752 if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/rms/RecordStore;", 36) == 0))
753 {
759 else
760 {
763 }
765 }
766 else
768 {
773 else
774 {
777 }
778 }
779 else
781 {
783 }
784 else
785 {
788 }
789 }
795 // Strings in class has no null char
800 }
802 /* skip over all attributes */
804 {
809 }
810 }
814 rlf_finally:
815 /* free the constant pool from the memory */
817 {
820 }
824 }
827 {
831 {
833 {
851 {
872 }
875 }
879 {
894 }
898 {
910 }
914 {
932 {
934 params --;
935 }
938 }
942 {
961 {
963 params --;
964 }
967 }
969 }
970 }
971 }
974 /*
975 Adds parameters names into block.
976 */
979 {
986 {
989 }
992 {
1002 }
1007 }
1010 /*
1011 Checks if a forward declaration corresponds to a real
1012 function definition.
1014 The identifier 'declaration' is a function or a
1015 procedure that is forward.
1016 */
1021 {
1026 {
1028 }
1031 {
1034 }
1051 {
1056 }
1059 {
1060 if ((declaration->identifier_class != function_name) || (!type_equal(return_type, declaration->return_type)))
1062 }
1063 }
1066 /*
1067 Checks if there is any identifier contained in the current block that is
1068 forward function or procedure delcaration. If there is, report an error.
1069 */
1071 {
1084 )
1085 {
1088 }
1093 }
1096 /*
1097 Uses a given name to access all the defined types.
1098 Return a found type, or an error type if no type
1099 was found.
1100 */
1102 {
1114 {
1118 {
1120 {
1123 }
1126 }
1129 }
1133 }
1136 /*
1137 Retuns the type of the constant given by its name,
1138 or return error_type if cstr is not a constant name.
1139 */
1141 {
1152 {
1156 {
1158 {
1161 }
1164 }
1167 }
1171 }
1174 /*
1175 Return a copy of an identifier associated with a
1176 constant of a given name, or a none identifier
1177 if identifier is not a constant or not found.
1178 */
1180 {
1188 {
1192 {
1197 }
1200 }
1208 }
1211 /*
1212 Return an identifier from a given name
1213 */
1215 {
1224 {
1228 {
1233 else
1237 }
1240 }
1247 /*
1248 Search all units for a given identifier. If the same identifier is found
1249 in more then one unit, output ambiguity error.
1250 */
1252 {
1256 {
1260 {
1261 /*
1262 Search inside the unit for the given name
1263 */
1267 {
1269 {
1272 {
1275 else
1276 {
1280 }
1281 }
1285 }
1286 }
1287 }
1290 }
1291 }
1293 unit_search_done:
1296 {
1299 }
1302 }
1305 /*
1306 Returns the type of a variable given by its name.
1307 Return an error type if no variable was found.
1308 */
1310 {
1321 {
1325 {
1330 }
1333 }
1337 }
1339 /*
1340 Create the bytecode to initialize the new variable.
1341 */
1342 void initialize_variable(block *item, identifier *variable, char *name, int is_static, char *class_name)
1343 {
1346 /* if the variable belongs to the program block */
1348 {
1350 }
1353 {
1357 {
1361 {
1363 {
1380 }
1381 }
1382 }
1386 {
1388 {
1392 {
1394 {
1411 }
1412 }
1413 }
1414 else
1415 {
1431 {
1433 {
1450 }
1451 }
1452 }
1453 }
1458 {
1472 {
1474 {
1491 }
1492 }
1493 }
1497 {
1498 int method_index = cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;");
1506 {
1508 {
1525 }
1526 }
1527 }
1532 {
1536 {
1538 {
1555 }
1556 }
1557 }
1561 {
1562 int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
1580 {
1582 {
1599 }
1600 }
1601 }
1605 {
1617 {
1619 {
1636 }
1637 }
1638 }
1642 {
1644 /* no initialization needeed */
1645 }
1649 {
1659 /* put dimensions on to the stack */
1661 {
1663 {
1677 }
1678 }
1681 count ++;
1682 }
1688 // NEW:
1696 {
1697 /* initialize the fields */
1702 int *dimensions_sizes; // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1706 {
1708 c ++;
1709 }
1715 dimensions_sizes = (int*) mem_alloc(c * sizeof(int)); // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1718 /* reset */
1722 {
1724 {
1733 dimensions_sizes[c] = it->data->last_element-it->data->first_element; // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1734 }
1735 c++;
1737 }
1739 /* load */
1741 {
1743 {
1744 // OLD: bytecode_append(item->code, dup$);
1745 // NEW:
1747 }
1755 }
1757 /* new */
1762 {
1766 bytecode_append_short_int(item->code, cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;"));
1767 }
1769 {
1770 int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
1786 }
1787 else
1788 {
1794 }
1798 /* jump back */
1802 {
1804 {
1818 /* the value is increased by one */
1827 //it->data->last_element-it->data->first_element);
1828 dimensions_sizes[c]); // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1832 }
1833 c--;
1835 }
1838 }
1840 /*OLD: if (!storeIntoField)
1841 {
1842 switch(variable->variable_index)
1843 {
1844 case 0:
1845 bytecode_append(item->code, astore_0$);
1846 break;
1847 case 1:
1848 bytecode_append(item->code, astore_1$);
1849 break;
1850 case 2:
1851 bytecode_append(item->code, astore_2$);
1852 break;
1853 case 3:
1854 bytecode_append(item->code, astore_3$);
1855 break;
1856 default:
1857 bytecode_append(item->code, astore$);
1858 bytecode_append(item->code, (char)variable->variable_index);
1859 break;
1860 }
1861 } */
1869 {
1889 {
1891 {
1908 }
1909 }
1910 }
1917 {
1919 }
1920 }
1923 /* create the bytecode for storing data into the field */
1926 && (variable->variable_type->type_class != array_type)) /* array initialization stores the variable */
1927 {
1940 else
1943 }
1944 }
1948 {
1953 {
1956 {
1959 {
1964 }
1965 }
1967 pos ++;
1968 }
1969 }
1972 /*
1973 Writes the class file based on the information provided in the
1974 root block.
1975 */
1977 {
1982 /*** Insert the additional data into the constant pool ***/
1984 {
1987 {
1997 }
1998 }
1999 else
2000 {
2003 }
2006 /* Insert the data needed by the methods into the constant pool */
2009 {
2011 }
2015 {
2021 }
2023 /* add data to constant poll that is later needed */
2038 /*** Write data to the file ***/
2040 /* write the header */
2043 /* write constant pool */
2046 /* write the access flags, set to ACC_PUBLIC and ACC_SUPER */
2049 /* write the index to constat pool with this class description */
2052 /* write the index to constant pool with the super class description */
2056 {
2057 /* we have 1 interface */
2061 }
2062 else
2063 {
2064 /* unit has 0 interfaces */
2066 }
2068 /* write the fields (global variables in pascal) */
2070 {
2073 /* write the RNG field */
2074 {
2075 /* access flags: ACC_PUBLIC and ACC_STATIC */
2078 /* write the name index */
2081 /* write the descriptor index */
2084 /* write 0 attributes */
2086 }
2088 /* write the image (I) field */
2089 {
2090 /* access flags: ACC_PUBLIC and ACC_STATIC */
2093 /* write the name index */
2096 /* write the descriptor index */
2099 /* write 0 attributes */
2101 }
2103 /* write the this (T) field */
2104 {
2105 /* access flags: ACC_PUBLIC and ACC_STATIC */
2108 /* write the name index */
2111 /* write the descriptor index */
2114 /* write 0 attributes */
2116 }
2119 /* write the graphics (G) field */
2120 {
2121 /* access flags: ACC_PUBLIC and ACC_STATIC */
2124 /* write the name index */
2127 /* write the descriptor index */
2130 /* write 0 attributes */
2132 }
2134 /* write the key clicked (KC) field */
2135 {
2136 /* access flags: ACC_PUBLIC and ACC_STATIC */
2139 /* write the name index */
2142 /* write the descriptor index */
2145 /* write 0 attributes */
2147 }
2149 /* write the key pressed (KP) field */
2150 {
2151 /* access flags: ACC_PUBLIC and ACC_STATIC */
2154 /* write the name index */
2157 /* write the descriptor index */
2160 /* write 0 attributes */
2162 }
2164 /* write the INDEX COUNTER (IC) field */
2165 {
2166 /* access flags: ACC_PUBLIC and ACC_STATIC */
2169 /* write the name index */
2172 /* write the descriptor index */
2175 /* write 0 attributes */
2177 }
2178 }
2179 else
2180 {
2182 }
2187 /* write the methods */
2189 {
2190 /* write the methods count */
2193 /* write the constructor */
2196 /* write the paint method */
2199 /* write the run method */
2202 /* write the key pressed and key released methods */
2205 }
2206 else
2207 {
2209 }
2211 /* write all other methods */
2213 {
2215 }
2217 /* write the main (R) method - <clinit> for interfaces */
2221 /* we have no attributes */
2225 // TODO: deallocate constant pool
2226 }
2229 /*
2230 Writes the method to the file, if fp is NULL only add needeed
2231 data to the constant pool
2232 */
2234 {
2243 /* write access flags, ACC_PUBLIC and ACC_STATIC */
2247 {
2248 /*** it is the main block ***/
2250 /* write name index */
2253 else
2256 /* write the descriptor */
2258 }
2259 else
2260 {
2272 /*** procedure or function ***/
2274 /* write name index */
2278 /* write the descriptor */
2279 block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
2284 {
2287 }
2292 {
2299 }
2302 pos ++;
2307 else
2313 }
2315 //PREVERIFY map_list = preverify_bytecode(current_block->code, block_identifier);
2319 /* write the code */
2325 write_long_int(fp, current_block->code->bytecode_pos + 12); /* update the size later when we know it */
2332 else
2342 {
2354 do
2355 {
2363 /* write the locals */
2365 {
2368 }
2369 else
2370 {
2373 /* write the StackMap for locals */
2374 block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
2380 }
2385 /* write the stack items */
2389 {
2391 {
2393 }
2397 {
2400 }
2402 stack_map_size ++;
2403 }
2407 stack_map_entries ++;
2411 /* write the stack map size and the number of entries and
2412 the code attribute length */
2414 {
2424 }
2425 }
2426 else
2427 {
2429 }
2431 /* write the Exceptions attribute */
2439 }
2442 /*
2443 Creates the code for the following method:
2445 public void paint(Graphics g)
2446 {
2447 g.drawImage(IMG, 0, 0, Graphics.TOP|Graphics.LEFT);
2448 }
2449 */
2451 {
2456 /* create the code */
2458 /* PUSH param_1 */
2461 /* PUSH (I) */
2463 bytecode_append_short_int(code, cp_add_fieldref("M", "I", "Ljavax/microedition/lcdui/Image;"));
2465 /* PUSH 0; PUSH 0*/
2469 /* PUSH Graphics.LEFT|Graphics.TOP */
2473 /* invoke drawImage(Image, int, int, int) */
2476 cp_add_methodref("javax/microedition/lcdui/Graphics", "drawImage", "(Ljavax/microedition/lcdui/Image;III)V"));
2480 /* write the method headers */
2482 /* write access flags, ACC_PUBLIC */
2485 /* write method name */
2488 /* write method descriptor */
2491 /* write 1 attribute */
2494 /* write the Code attribute */
2498 /* write the max stack */
2501 /* max locals for program block */
2505 /* code length */
2508 /* write the code itself */
2516 }
2518 /*
2519 Creates the code for the following method:
2521 public void run()
2522 {
2523 R();
2524 }
2525 */
2527 {
2534 /* create the code */
2539 /* write the method headers */
2541 /* write access flags, ACC_PUBLIC */
2544 /* write method name */
2547 /* write method descriptor */
2550 /* write 1 attribute */
2553 /* write the Code attribute */
2557 /* write the max stack */
2560 /* max locals for program block */
2564 /* code length */
2567 /* write the code itself */
2575 }
2578 /*
2579 Creates the code for the following methods:
2581 public void keyPressed(int keyCode)
2582 {
2583 KC = keyCode;
2584 KP = keyCode;
2585 }
2587 public void keyReleased(int keyCode)
2588 {
2589 KP = 0;
2590 }
2591 */
2593 {
2598 /* create the code */
2608 /* write the method headers */
2610 /* write access flags, ACC_PUBLIC */
2613 /* write method name */
2616 /* write method descriptor */
2619 /* write 1 attribute */
2622 /* write the Code attribute */
2626 /* write the max stack */
2629 /* max locals for program block */
2633 /* code length */
2636 /* write the code itself */
2644 }
2646 {
2651 /* create the code */
2658 /* write the method headers */
2660 /* write access flags, ACC_PUBLIC */
2663 /* write method name */
2666 /* write method descriptor */
2669 /* write 1 attribute */
2672 /* write the Code attribute */
2676 /* write the max stack */
2679 /* max locals for program block */
2683 /* code length */
2686 /* write the code itself */
2694 }
2697 /*
2698 Creates the code for the class constructor.
2699 */
2701 {
2706 /* create the code */
2708 {
2712 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "<init>", "()V"));
2717 bytecode_append_short_int(code, cp_add_methodref("com/nokia/mid/ui/FullCanvas", "<init>", "()V"));
2723 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/game/GameCanvas", "<init>", "(Z)V"));
2728 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "setFullScreenMode", "(Z)V"));
2730 }
2734 /* write the method headers */
2736 /* write access flags, ACC_PUBLIC */
2739 /* write method name */
2742 /* write method descriptor */
2745 /* write 1 attribute */
2748 /* write the Code attribute */
2752 /* write the max stack */
2755 /* max locals for program block */
2759 /* code length */
2762 /* write the code itself */
2771 }
2774 /*
2775 Write the variables from the block as fields into the
2776 given class file. If fp==NULL only add constants into
2777 the constant pool.
2778 */
2780 {
2785 {
2786 /* access flags: ACC_PUBLIC and ACC_STATIC */
2789 /* write the name index */
2793 /* write the descriptor index */
2797 /* write 0 attributes */
2799 }
2801 /* write the left child */
2804 {
2806 }
2808 /* write the right child */
2811 {
2813 }
2814 }
2818 {
2822 /* for functions, add the return value */
2824 {
2829 }
2833 }
2836 {
2839 {
2843 {
2845 {
2856 {
2858 {
2863 }
2864 else
2865 {
2871 }
2872 }
2933 {
2942 {
2944 }
2955 }
2959 {
2967 }
2969 }
2970 }
2973 }
2974 }