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 }
799 }
801 /* skip over all attributes */
803 {
808 }
809 }
813 rlf_finally:
814 /* free the constant pool from the memory */
816 {
819 }
823 }
826 {
830 {
832 {
850 {
871 }
874 }
878 {
893 }
897 {
909 }
913 {
931 {
933 params --;
934 }
937 }
941 {
960 {
962 params --;
963 }
966 }
968 }
969 }
970 }
973 /*
974 Adds parameters names into block.
975 */
978 {
985 {
988 }
991 {
1001 }
1006 }
1009 /*
1010 Checks if a forward declaration corresponds to a real
1011 function definition.
1013 The identifier 'declaration' is a function or a
1014 procedure that is forward.
1015 */
1020 {
1025 {
1027 }
1030 {
1033 }
1050 {
1055 }
1058 {
1059 if ((declaration->identifier_class != function_name) || (!type_equal(return_type, declaration->return_type)))
1061 }
1062 }
1065 /*
1066 Checks if there is any identifier contained in the current block that is
1067 forward function or procedure delcaration. If there is, report an error.
1068 */
1070 {
1083 )
1084 {
1087 }
1092 }
1095 /*
1096 Uses a given name to access all the defined types.
1097 Return a found type, or an error type if no type
1098 was found.
1099 */
1101 {
1113 {
1117 {
1119 {
1122 }
1125 }
1128 }
1132 }
1135 /*
1136 Retuns the type of the constant given by its name,
1137 or return error_type if cstr is not a constant name.
1138 */
1140 {
1151 {
1155 {
1157 {
1160 }
1163 }
1166 }
1170 }
1173 /*
1174 Return a copy of an identifier associated with a
1175 constant of a given name, or a none identifier
1176 if identifier is not a constant or not found.
1177 */
1179 {
1187 {
1191 {
1196 }
1199 }
1207 }
1210 /*
1211 Return an identifier from a given name
1212 */
1214 {
1223 {
1227 {
1232 else
1236 }
1239 }
1246 /*
1247 Search all units for a given identifier. If the same identifier is found
1248 in more then one unit, output ambiguity error.
1249 */
1251 {
1255 {
1259 {
1260 /*
1261 Search inside the unit for the given name
1262 */
1266 {
1268 {
1271 {
1274 else
1275 {
1279 }
1280 }
1284 }
1285 }
1286 }
1289 }
1290 }
1292 unit_search_done:
1295 {
1298 }
1301 }
1304 /*
1305 Returns the type of a variable given by its name.
1306 Return an error type if no variable was found.
1307 */
1309 {
1320 {
1324 {
1329 }
1332 }
1336 }
1338 /*
1339 Create the bytecode to initialize the new variable.
1340 */
1341 void initialize_variable(block *item, identifier *variable, char *name, int is_static, char *class_name)
1342 {
1345 /* if the variable belongs to the program block */
1347 {
1349 }
1352 {
1356 {
1360 {
1362 {
1379 }
1380 }
1381 }
1385 {
1387 {
1391 {
1393 {
1410 }
1411 }
1412 }
1413 else
1414 {
1430 {
1432 {
1449 }
1450 }
1451 }
1452 }
1457 {
1471 {
1473 {
1490 }
1491 }
1492 }
1496 {
1497 int method_index = cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;");
1505 {
1507 {
1524 }
1525 }
1526 }
1531 {
1535 {
1537 {
1554 }
1555 }
1556 }
1560 {
1561 int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
1579 {
1581 {
1598 }
1599 }
1600 }
1604 {
1616 {
1618 {
1635 }
1636 }
1637 }
1641 {
1643 /* no initialization needeed */
1644 }
1648 {
1658 /* put dimensions on to the stack */
1660 {
1662 {
1676 }
1677 }
1680 count ++;
1681 }
1687 // NEW:
1695 {
1696 /* initialize the fields */
1701 int *dimensions_sizes; // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1705 {
1707 c ++;
1708 }
1714 dimensions_sizes = (int*) mem_alloc(c * sizeof(int)); // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1717 /* reset */
1721 {
1723 {
1732 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
1733 }
1734 c++;
1736 }
1738 /* load */
1740 {
1742 {
1743 // OLD: bytecode_append(item->code, dup$);
1744 // NEW:
1746 }
1754 }
1756 /* new */
1761 {
1765 bytecode_append_short_int(item->code, cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;"));
1766 }
1768 {
1769 int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
1785 }
1786 else
1787 {
1793 }
1797 /* jump back */
1801 {
1803 {
1817 /* the value is increased by one */
1826 //it->data->last_element-it->data->first_element);
1827 dimensions_sizes[c]); // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1831 }
1832 c--;
1834 }
1837 }
1839 /*OLD: if (!storeIntoField)
1840 {
1841 switch(variable->variable_index)
1842 {
1843 case 0:
1844 bytecode_append(item->code, astore_0$);
1845 break;
1846 case 1:
1847 bytecode_append(item->code, astore_1$);
1848 break;
1849 case 2:
1850 bytecode_append(item->code, astore_2$);
1851 break;
1852 case 3:
1853 bytecode_append(item->code, astore_3$);
1854 break;
1855 default:
1856 bytecode_append(item->code, astore$);
1857 bytecode_append(item->code, (char)variable->variable_index);
1858 break;
1859 }
1860 } */
1868 {
1888 {
1890 {
1907 }
1908 }
1909 }
1916 {
1918 }
1919 }
1922 /* create the bytecode for storing data into the field */
1925 && (variable->variable_type->type_class != array_type)) /* array initialization stores the variable */
1926 {
1939 else
1942 }
1943 }
1947 {
1952 {
1955 {
1958 {
1963 }
1964 }
1966 pos ++;
1967 }
1968 }
1971 /*
1972 Writes the class file based on the information provided in the
1973 root block.
1974 */
1976 {
1981 /*** Insert the additional data into the constant pool ***/
1983 {
1986 {
1996 }
1997 }
1998 else
1999 {
2002 }
2005 /* Insert the data needed by the methods into the constant pool */
2008 {
2010 }
2014 {
2020 }
2022 /* add data to constant poll that is later needed */
2037 /*** Write data to the file ***/
2039 /* write the header */
2042 /* write constant pool */
2045 /* write the access flags, set to ACC_PUBLIC and ACC_SUPER */
2048 /* write the index to constat pool with this class description */
2051 /* write the index to constant pool with the super class description */
2055 {
2056 /* we have 1 interface */
2060 }
2061 else
2062 {
2063 /* unit has 0 interfaces */
2065 }
2067 /* write the fields (global variables in pascal) */
2069 {
2072 /* write the RNG field */
2073 {
2074 /* access flags: ACC_PUBLIC and ACC_STATIC */
2077 /* write the name index */
2080 /* write the descriptor index */
2083 /* write 0 attributes */
2085 }
2087 /* write the image (I) field */
2088 {
2089 /* access flags: ACC_PUBLIC and ACC_STATIC */
2092 /* write the name index */
2095 /* write the descriptor index */
2098 /* write 0 attributes */
2100 }
2102 /* write the this (T) field */
2103 {
2104 /* access flags: ACC_PUBLIC and ACC_STATIC */
2107 /* write the name index */
2110 /* write the descriptor index */
2113 /* write 0 attributes */
2115 }
2118 /* write the graphics (G) field */
2119 {
2120 /* access flags: ACC_PUBLIC and ACC_STATIC */
2123 /* write the name index */
2126 /* write the descriptor index */
2129 /* write 0 attributes */
2131 }
2133 /* write the key clicked (KC) field */
2134 {
2135 /* access flags: ACC_PUBLIC and ACC_STATIC */
2138 /* write the name index */
2141 /* write the descriptor index */
2144 /* write 0 attributes */
2146 }
2148 /* write the key pressed (KP) field */
2149 {
2150 /* access flags: ACC_PUBLIC and ACC_STATIC */
2153 /* write the name index */
2156 /* write the descriptor index */
2159 /* write 0 attributes */
2161 }
2163 /* write the INDEX COUNTER (IC) field */
2164 {
2165 /* access flags: ACC_PUBLIC and ACC_STATIC */
2168 /* write the name index */
2171 /* write the descriptor index */
2174 /* write 0 attributes */
2176 }
2177 }
2178 else
2179 {
2181 }
2186 /* write the methods */
2188 {
2189 /* write the methods count */
2192 /* write the constructor */
2195 /* write the paint method */
2198 /* write the run method */
2201 /* write the key pressed and key released methods */
2204 }
2205 else
2206 {
2208 }
2210 /* write all other methods */
2212 {
2214 }
2216 /* write the main (R) method - <clinit> for interfaces */
2220 /* we have no attributes */
2224 // TODO: deallocate constant pool
2225 }
2228 /*
2229 Writes the method to the file, if fp is NULL only add needeed
2230 data to the constant pool
2231 */
2233 {
2242 /* write access flags, ACC_PUBLIC and ACC_STATIC */
2246 {
2247 /*** it is the main block ***/
2249 /* write name index */
2252 else
2255 /* write the descriptor */
2257 }
2258 else
2259 {
2271 /*** procedure or function ***/
2273 /* write name index */
2277 /* write the descriptor */
2278 block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
2283 {
2286 }
2291 {
2298 }
2301 pos ++;
2306 else
2312 }
2314 //PREVERIFY map_list = preverify_bytecode(current_block->code, block_identifier);
2318 /* write the code */
2324 write_long_int(fp, current_block->code->bytecode_pos + 12); /* update the size later when we know it */
2331 else
2341 {
2353 do
2354 {
2362 /* write the locals */
2364 {
2367 }
2368 else
2369 {
2372 /* write the StackMap for locals */
2373 block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
2379 }
2384 /* write the stack items */
2388 {
2390 {
2392 }
2396 {
2399 }
2401 stack_map_size ++;
2402 }
2406 stack_map_entries ++;
2410 /* write the stack map size and the number of entries and
2411 the code attribute length */
2413 {
2423 }
2424 }
2425 else
2426 {
2428 }
2430 /* write the Exceptions attribute */
2438 }
2441 /*
2442 Creates the code for the following method:
2444 public void paint(Graphics g)
2445 {
2446 g.drawImage(IMG, 0, 0, Graphics.TOP|Graphics.LEFT);
2447 }
2448 */
2450 {
2455 /* create the code */
2457 /* PUSH param_1 */
2460 /* PUSH (I) */
2462 bytecode_append_short_int(code, cp_add_fieldref("M", "I", "Ljavax/microedition/lcdui/Image;"));
2464 /* PUSH 0; PUSH 0*/
2468 /* PUSH Graphics.LEFT|Graphics.TOP */
2472 /* invoke drawImage(Image, int, int, int) */
2475 cp_add_methodref("javax/microedition/lcdui/Graphics", "drawImage", "(Ljavax/microedition/lcdui/Image;III)V"));
2479 /* write the method headers */
2481 /* write access flags, ACC_PUBLIC */
2484 /* write method name */
2487 /* write method descriptor */
2490 /* write 1 attribute */
2493 /* write the Code attribute */
2497 /* write the max stack */
2500 /* max locals for program block */
2504 /* code length */
2507 /* write the code itself */
2515 }
2517 /*
2518 Creates the code for the following method:
2520 public void run()
2521 {
2522 R();
2523 }
2524 */
2526 {
2533 /* create the code */
2544 /* write the method headers */
2546 /* write access flags, ACC_PUBLIC */
2549 /* write method name */
2552 /* write method descriptor */
2555 /* write 1 attribute */
2558 /* write the Code attribute */
2562 /* write the max stack */
2565 /* max locals for program block */
2568 /* code length */
2571 /* write the code itself */
2577 /* write exception table length*/
2580 /* write the exception table */
2587 /* StackMap attribute */
2593 /* 2 frames*/
2596 /* write the frame 0 */
2599 /* write the locals */
2607 /* 0 stack entries */
2610 /* write the frame 1 */
2613 /* write the locals*/
2620 /* 1 stack entry */
2628 /* write the frame 2 */
2631 /* write the locals */
2638 /* 0 stack entries */
2641 }
2644 /*
2645 Creates the code for the following methods:
2647 public void keyPressed(int keyCode)
2648 {
2649 KC = keyCode;
2650 KP = keyCode;
2651 }
2653 public void keyReleased(int keyCode)
2654 {
2655 KP = 0;
2656 }
2657 */
2659 {
2664 /* create the code */
2674 /* write the method headers */
2676 /* write access flags, ACC_PUBLIC */
2679 /* write method name */
2682 /* write method descriptor */
2685 /* write 1 attribute */
2688 /* write the Code attribute */
2692 /* write the max stack */
2695 /* max locals for program block */
2699 /* code length */
2702 /* write the code itself */
2710 }
2712 {
2717 /* create the code */
2724 /* write the method headers */
2726 /* write access flags, ACC_PUBLIC */
2729 /* write method name */
2732 /* write method descriptor */
2735 /* write 1 attribute */
2738 /* write the Code attribute */
2742 /* write the max stack */
2745 /* max locals for program block */
2749 /* code length */
2752 /* write the code itself */
2760 }
2763 /*
2764 Creates the code for the class constructor.
2765 */
2767 {
2772 /* create the code */
2774 {
2778 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "<init>", "()V"));
2783 bytecode_append_short_int(code, cp_add_methodref("com/nokia/mid/ui/FullCanvas", "<init>", "()V"));
2789 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/game/GameCanvas", "<init>", "(Z)V"));
2794 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "setFullScreenMode", "(Z)V"));
2796 }
2800 /* write the method headers */
2802 /* write access flags, ACC_PUBLIC */
2805 /* write method name */
2808 /* write method descriptor */
2811 /* write 1 attribute */
2814 /* write the Code attribute */
2818 /* write the max stack */
2821 /* max locals for program block */
2825 /* code length */
2828 /* write the code itself */
2837 }
2840 /*
2841 Write the variables from the block as fields into the
2842 given class file. If fp==NULL only add constants into
2843 the constant pool.
2844 */
2846 {
2851 {
2852 /* access flags: ACC_PUBLIC and ACC_STATIC */
2855 /* write the name index */
2859 /* write the descriptor index */
2863 /* write 0 attributes */
2865 }
2867 /* write the left child */
2870 {
2872 }
2874 /* write the right child */
2877 {
2879 }
2880 }
2884 {
2888 /* for functions, add the return value */
2890 {
2895 }
2899 }
2902 {
2905 {
2909 {
2911 {
2922 {
2924 {
2929 }
2930 else
2931 {
2937 }
2938 }
2999 {
3008 {
3010 }
3021 }
3025 {
3033 }
3035 }
3036 }
3039 }
3040 }