DEADSOFTWARE

Remove exception catching in main module
[mp3cc.git] / mpc / structures / block.c
1 /********************************************************************
3 block.h - structures and functions used to hold program
4 block descriptions
6 Niksa Orlic, 2004-04-29
8 ********************************************************************/
11 #include "../util/strings.h"
12 #include "../util/error.h"
13 //#include "../util/message.h"
14 #include "../classgen/bytecode.h"
15 #include "type_list.h"
16 #include "string_list.h"
17 #include "type.h"
18 #include "identifier.h"
19 #include "name_table.h"
20 #include "unit.h"
21 #include "block.h"
22 #include "../classgen/preverify.h"
24 #include "../util/memory.h"
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdio.h>
30 #include "../classgen/constant_pool.h"
31 #include "../classgen/classgen.h"
33 extern int linenum;
34 extern int new_linenum;
35 extern block* root_block;
36 extern char *global_library_directory;
37 extern char *project_library_directory;
39 extern char *user_libraries;
40 extern char **units;
42 extern int detect_units_only;
44 extern constant_pool *constants;
45 extern int constant_pool_size;
47 extern int usesFloat;
48 extern int usesRecordStore;
49 extern int usesHttp;
51 extern int canvasType;
53 extern int mathType;
55 extern int compiling_unit;
56 extern string* str_program_name;
58 extern char* output_path;
60 #pragma warning (disable:4305)
61 #pragma warning (disable:4761)
63 /*
64 Create an empty block
65 */
66 block* block_create(block *parent_block, string *block_name)
67 {
68 block *new_block;
69 new_block = (block*) mem_alloc(sizeof(block));
71 new_block->names = name_table_create();
72 new_block->parent_block = parent_block;
73 new_block->block_name = block_name; /* do not copy the name, just point to it */
75 new_block->next_variable_index = 0;
76 new_block->next_parameter_index = 0;
78 new_block->code = bytecode_create();
80 new_block->children_count = 0;
82 return new_block;
83 }
86 /*
87 Delete a block
88 */
89 void block_destroy(block *item)
90 {
91 int i;
92 name_table_destroy(item->names);
93 bytecode_destroy(item->code);
95 /* delete all of its children */
96 for(i=0; i<item->children_count; i++)
97 {
98 block_destroy(item->children[i]);
99 }
101 if (item->children_count > 0)
103 mem_free(item->children);
106 /* do not delete the item->block_name */
107 mem_free(item);
111 /*
112 Check if a given name is legal name for a
113 new identifier in a block.
114 */
115 int block_check_name(block *item, char *cstr)
117 int return_value = 1;
119 string *name;
120 identifier *descriptor;
121 name = string_from_cstr(cstr);
123 descriptor = name_table_find(item->names, name);
125 if (descriptor != NULL)
127 if (((descriptor->identifier_class == procedure_name)
128 || (descriptor->identifier_class == function_name))
129 && (descriptor->forward_declaration == 1))
130 return_value = 1;
131 else
132 return_value = 0;
135 /* check the root block's types - those types are protected */
136 if (return_value == 1)
138 while (item->parent_block != NULL)
139 item = item->parent_block;
141 descriptor = name_table_find(item->names, name);
143 if ((descriptor != NULL) && (descriptor->identifier_class == type_name))
144 return_value = 0;
147 string_destroy(name);
149 return return_value;
152 /*
153 Adds a single real constant into the block
154 */
155 void add_real_constant(block *item, float value, char *cstr_name)
157 string *name;
158 identifier *descriptor;
160 name = string_from_cstr(cstr_name);
161 descriptor = identifier_create();
162 descriptor->identifier_class = constant_name;
163 descriptor->constant_type = type_create();
164 descriptor->constant_type->type_class = real_type;
165 descriptor->constant_real_value = value;
166 name_table_insert(item->names, name, descriptor);
170 /*
171 Adds a single integer constant into the block
172 */
173 void add_integer_constant(block *item, long int value, char *cstr_name)
175 string *name;
176 identifier *descriptor;
178 name = string_from_cstr(cstr_name);
179 descriptor = identifier_create();
180 descriptor->identifier_class = constant_name;
181 descriptor->constant_type = type_create();
182 descriptor->constant_type->type_class = integer_type;
183 descriptor->constant_int_value = value;
184 name_table_insert(item->names, name, descriptor);
188 /*
189 Adds a single character constant into the block
190 */
191 void add_char_constant(block *item, char value, char *cstr_name)
193 string *name;
194 identifier *descriptor;
196 name = string_from_cstr(cstr_name);
197 descriptor = identifier_create();
198 descriptor->identifier_class = constant_name;
199 descriptor->constant_type = type_create();
200 descriptor->constant_type->type_class = char_type;
201 descriptor->constant_int_value = value;
202 name_table_insert(item->names, name, descriptor);
206 /*
207 Adds a single boolean constant into the block
208 */
209 void add_boolean_constant(block *item, char value, char *cstr_name)
211 string *name;
212 identifier *descriptor;
214 name = string_from_cstr(cstr_name);
215 descriptor = identifier_create();
216 descriptor->identifier_class = constant_name;
217 descriptor->constant_type = type_create();
218 descriptor->constant_type->type_class = boolean_type;
219 descriptor->constant_int_value = value;
220 name_table_insert(item->names, name, descriptor);
224 /*
225 Adds a single string constant into the block
226 */
227 void add_string_constant(block *item, string *value, char *cstr_name)
229 string *name;
230 identifier *descriptor;
232 name = string_from_cstr(cstr_name);
233 descriptor = identifier_create();
234 descriptor->identifier_class = constant_name;
235 descriptor->constant_type = type_create();
236 descriptor->constant_type->type_class = string_type;
237 descriptor->constant_string_value = string_duplicate(value);
238 name_table_insert(item->names, name, descriptor);
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 */
247 void add_variables(block *item, string_list *identifier_list, type *var_type)
249 string_list *it;
250 identifier *descriptor;
251 identifier *block_identifier;
253 it = identifier_list;
255 if (it->data == NULL)
257 type_destroy(var_type);
258 return;
261 if(item->parent_block != root_block)
263 block_identifier = name_table_find(item->parent_block->names, item->block_name);
264 if (block_identifier->variables == NULL)
265 block_identifier->variables = type_list_create();
267 else
268 block_identifier = NULL;
270 while (it != NULL)
272 // j-a-s-d: consecutive variable name collision fix
273 if (!block_check_name(item, it->data->cstr))
275 add_error_message(400, it->data->cstr, "");
277 descriptor = identifier_create();
278 descriptor->identifier_class = variable_name;
279 descriptor->variable_type = type_duplicate(var_type);
280 descriptor->variable_index = item->next_variable_index;
281 descriptor->belongs_to_program_block = (item->parent_block == root_block);
282 name_table_insert(item->names, string_duplicate(it->data), descriptor);
284 if (compiling_unit == 0)
285 initialize_variable(item, descriptor, it->data->cstr, 1, "M");
286 else
287 initialize_variable(item, descriptor, it->data->cstr, 1, string_get_cstr(str_program_name));
289 if (block_identifier != NULL)
290 type_list_append(block_identifier->variables, descriptor->variable_type);
292 item->next_variable_index ++;
294 it = it->next;
299 /*
300 Add a type into block. The name and type_type
301 are NOT copied.
302 */
303 void add_type(block *item, string *name, type *type_type)
305 identifier *descriptor;
307 descriptor = identifier_create();
308 descriptor->identifier_class = type_name;
309 descriptor->defined_type = type_type;
310 name_table_insert(item->names, name, descriptor);
314 /*
315 Adds a procedure declaration into the block
316 */
317 void add_procedure(block *item, string *name, type_list *parameters,
318 int forward_declaration, int linenum)
320 identifier *descriptor;
322 descriptor = name_table_find(item->names, name);
324 if (descriptor != NULL)
326 if ((forward_declaration != -1)
327 && (descriptor->forward_declaration != -1))
328 check_forward_declaration(descriptor, parameters,
329 forward_declaration, NULL);
331 if ((descriptor->forward_declaration == -1)
332 || (forward_declaration != -1))
333 descriptor->forward_declaration = forward_declaration;
335 else
337 descriptor = identifier_create();
338 descriptor->identifier_class = procedure_name;
339 descriptor->parameters = parameters;
340 descriptor->forward_declaration = forward_declaration;
341 descriptor->subprogram_linenum = linenum;
342 name_table_insert(item->names, name, descriptor);
347 /*
348 Adds a function declaration into the block
349 */
350 void add_function(block *item, string *name, type_list *parameters,
351 type *return_type, int forward_declaration, int linenum)
353 identifier *descriptor;
355 descriptor = name_table_find(item->names, name);
357 if (descriptor != NULL)
359 if ((forward_declaration != -1)
360 && (descriptor->forward_declaration != -1))
361 check_forward_declaration(descriptor, parameters,
362 forward_declaration, return_type);
364 if ((descriptor->forward_declaration == -1)
365 || (forward_declaration != -1))
366 descriptor->forward_declaration = forward_declaration;
368 else
370 descriptor = identifier_create();
371 descriptor->identifier_class = function_name;
372 descriptor->parameters = parameters;
373 descriptor->return_type = return_type;
374 descriptor->forward_declaration = forward_declaration;
375 descriptor->subprogram_linenum = linenum;
376 name_table_insert(item->names, name, descriptor);
381 /*
382 Loads (inserts) an external library into the project - load the class file and
383 enumerate all static functions.
384 */
385 void load_extern_library(string* library_name)
387 FILE *library_file = NULL;
388 FILE *symbol_file = NULL;
389 string *global_library_path;
390 string *project_library_path;
391 unit *library_unit;
392 identifier *unit_identifier;
394 lowercase(library_name->cstr);
396 /* create the full path to the library file */
397 /* global library directory */
398 global_library_path = string_from_cstr(global_library_directory);
399 #ifdef WIN32
400 string_append(global_library_path, string_from_cstr("\\Lib_"));
401 #endif
402 #ifdef UNIX
403 string_append(global_library_path, string_from_cstr("/Lib_"));
404 #endif
405 string_append(global_library_path, library_name);
406 string_append(global_library_path, string_from_cstr(".class"));
407 /* project library directory */
408 project_library_path = string_from_cstr(project_library_directory);
409 #ifdef WIN32
410 string_append(project_library_path, string_from_cstr("\\Lib_"));
411 #endif
412 #ifdef UNIX
413 string_append(project_library_path, string_from_cstr("/Lib_"));
414 #endif
415 string_append(project_library_path, library_name);
416 string_append(project_library_path, string_from_cstr(".class"));
418 if (name_table_find(root_block->names, library_name) != NULL)
420 add_error_message(450, string_get_cstr(library_name), "");
421 fclose(library_file);
422 goto lel_finally;
425 /* create a new unit object */
426 library_unit = unit_create(string_duplicate(library_name));
427 unit_identifier = identifier_create();
428 unit_identifier->identifier_class = unit_name;
429 unit_identifier->unit_block = library_unit;
430 name_table_insert(root_block->names, string_duplicate(library_name), unit_identifier);
432 /* try open the library file from the libraries directories */
433 library_file = fopen(project_library_path->cstr, "rb");
434 if (library_file == NULL)
436 library_file = fopen(global_library_path->cstr, "rb");
438 if (library_file == NULL)
440 /* if this fails, try to open an unit file */
441 char *filename = (char*)malloc(strlen(output_path) + string_length(library_name) + 10);
443 #ifdef WIN32
444 sprintf(filename, "%s\\%s.bsf", output_path, string_get_cstr(library_name));
445 #endif
446 #ifdef UNIX
447 sprintf(filename, "%s/%s.bsf", output_path, string_get_cstr(library_name));
448 #endif
450 symbol_file = fopen(filename, "rb");
452 free(filename);
454 if (symbol_file == NULL)
456 // j-a-s-d: if unit is not found it must stop only if compiling
457 if (!detect_units_only)
459 add_error_message(448, library_name->cstr, "");
460 goto lel_finally;
465 if (detect_units_only)
466 requires(0, library_name->cstr);
467 } else {
468 if (!detect_units_only)
469 requires(1, library_name->cstr);
472 /* read the library file */
473 if (library_file)
475 library_unit->is_library = 1;
476 if (detect_units_only == 0)
477 read_library_file(library_file, library_unit);
478 fclose(library_file);
481 if (symbol_file)
483 library_unit->is_library = 0;
484 if (detect_units_only == 0)
485 read_symbol_file(symbol_file, library_unit);
486 fclose(symbol_file);
489 unit_identifier->identifier_class = unit_name;
490 unit_identifier->unit_block = library_unit;
492 name_table_insert(root_block->names, library_name , unit_identifier);
494 if (library_file)
496 if (user_libraries == NULL)
498 user_libraries = malloc(library_name->length+1);
499 strcpy(user_libraries, library_name->cstr);
501 else
503 int len = strlen(user_libraries);
504 user_libraries = realloc(user_libraries, len + 3 + library_name->length);
505 user_libraries[strlen(user_libraries)] = ' ';
506 strcpy(user_libraries + len + 1, library_name->cstr);
510 if (symbol_file)
512 save_unit_name:
513 if (*units == NULL)
515 *units = malloc(library_name->length+1);
516 strcpy(*units, library_name->cstr);
518 else
520 int len = strlen(*units);
521 *units = realloc(*units, len + 3 + library_name->length);
522 (*units)[len] = ' ';
523 strcpy(*units + len + 1, library_name->cstr);
528 lel_finally:
529 string_destroy(library_name);
530 string_destroy(project_library_path);
531 string_destroy(global_library_path);
535 /*
536 Reads the library file.
537 */
538 void read_library_file(FILE* library_file, unit* library_unit)
540 int constant_pool_count;
541 struct constant_pool_struct *constant_pool;
542 int access_flags, this_class, super_class;
543 int interface_count, field_count, methods_count;
544 int i, j;
546 /* read and check magic number */
547 if ((fgetc(library_file) != 0xca)
548 || (fgetc(library_file) != 0xfe)
549 || (fgetc(library_file) != 0xba)
550 || (fgetc(library_file) != 0xbe)
553 add_error_message(449, "", "");
554 fclose(library_file);
555 die(6);
556 return;
559 /* skip major and minor count */
560 read_long_int(library_file);
562 /* read the number of constant pool entries */
563 constant_pool_count = read_short_int(library_file);
565 /* allocate and read the constant pool */
566 constant_pool = mem_alloc(sizeof(struct constant_pool_struct) * constant_pool_count);
568 for (i = 1; i<constant_pool_count; i++)
570 int tag;
572 tag = fgetc(library_file);
573 constant_pool[i].tag = tag;
574 constant_pool[i].data = NULL;
576 switch (tag)
578 case 7: /* ClassInfo */
579 case 8: /* StringInfo */
580 constant_pool[i].param1 = read_short_int(library_file);
581 break;
582 case 9: /* Fieldref */
583 case 10: /* Methodref */
584 case 11: /* Instanceref*/
585 case 12: /* NameAndType */
586 constant_pool[i].param1 = read_short_int(library_file);
587 constant_pool[i].param2 = read_short_int(library_file);
588 break;
589 case 3: /* Integer */
590 case 4: /* Float */
591 constant_pool[i].param1 = read_long_int(library_file);
592 break;
593 case 5: /* Long */
594 case 6: /* double */
595 constant_pool[i].param1 = read_long_int(library_file);
596 constant_pool[i].param2 = read_long_int(library_file);
597 break;
599 case 1: /* Utf8 */
600 constant_pool[i].data_len = read_short_int(library_file);
601 constant_pool[i].data = mem_alloc(sizeof(char) * constant_pool[i].data_len);
602 fread(constant_pool[i].data, 1, constant_pool[i].data_len, library_file);
603 break;
605 default:
606 add_error_message(449, "", "");
607 goto rlf_finally;
611 access_flags = read_short_int(library_file);
612 this_class= read_short_int(library_file);
613 super_class = read_short_int(library_file);
615 /* TODO:: check that this class has the proper name, no package etc. */
616 /* check access flags */
617 if ((access_flags & 0x0200) // ACC_INTERFACE
618 || (access_flags & 0x0400)) // ACC_ABSTRACT
620 add_error_message(451, "", "");
623 /* TODO:: are there some limitations on super class? */
625 /* skip over the implemented interfaces */
626 interface_count = read_short_int(library_file);
627 for(i=0; i<interface_count; i++)
629 read_short_int(library_file);
632 /* skip over the fields */
633 field_count = read_short_int(library_file);
634 for(i=0; i<field_count; i++)
636 int attributes_count;
637 read_short_int(library_file);
638 read_short_int(library_file);
639 read_short_int(library_file);
640 attributes_count = read_short_int(library_file);
641 for(j=0; j<attributes_count; j++)
643 int length;
644 read_short_int(library_file);
645 length = read_long_int(library_file);
646 fseek(library_file, length, SEEK_CUR);
650 /* read the methods and add them into the program scope */
651 methods_count = read_short_int(library_file);
653 for (i = 0; i<methods_count; i++)
655 short int method_access_flags;
656 short int method_name_index;
657 short int method_descriptor_index;
658 short int attributes_count;
660 method_access_flags = read_short_int(library_file);
661 method_name_index = read_short_int(library_file);
662 method_descriptor_index = read_short_int(library_file);
664 /* read the method's attributes */
665 attributes_count = read_short_int(library_file);
667 /* if the method is declared as 'public static' consider
668 adding it into the unit interface */
669 if(method_access_flags == 0x0009)
671 char *descriptor;
672 int parsing_return_type = 0;
673 identifier *method;
674 string *method_name;
675 int j;
677 method = identifier_create();
678 method->forward_declaration = 0;
679 method->standard_function = 0;
680 method->parameters = type_list_create();
682 /* check that method parameters and return value are OK */
683 descriptor = constant_pool[method_descriptor_index].data;
685 for(j = 1; j<constant_pool[method_descriptor_index].data_len; j++)
687 if (descriptor[j] == ')')
689 parsing_return_type = 1;
691 else
692 if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljava/lang/String;", 18) == 0))
694 type* new_type = type_create();
695 new_type->type_class = string_type;
697 if (!parsing_return_type)
698 type_list_append(method->parameters, new_type);
699 else
701 method->return_type = new_type;
702 method->identifier_class = function_name;
704 j += 17;
706 else
707 if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/lcdui/Image;", 32) == 0))
709 type* new_type = type_create();
710 new_type->type_class = image_type;
712 if (!parsing_return_type)
713 type_list_append(method->parameters, new_type);
714 else
716 method->return_type = new_type;
717 method->identifier_class = function_name;
719 j += 31;
721 else
722 if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/lcdui/Command;", 34) == 0))
724 type* new_type = type_create();
725 new_type->type_class = command_type;
727 if (!parsing_return_type)
728 type_list_append(method->parameters, new_type);
729 else
731 method->return_type = new_type;
732 method->identifier_class = function_name;
734 j += 33;
736 else
737 if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljava/io/InputStream;", 21) == 0))
739 type* new_type = type_create();
740 new_type->type_class = stream_type;
742 if (!parsing_return_type)
743 type_list_append(method->parameters, new_type);
744 else
746 method->return_type = new_type;
747 method->identifier_class = function_name;
749 j += 20;
751 else
752 if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/rms/RecordStore;", 36) == 0))
754 type* new_type = type_create();
755 new_type->type_class = record_store_type;
757 if (!parsing_return_type)
758 type_list_append(method->parameters, new_type);
759 else
761 method->return_type = new_type;
762 method->identifier_class = function_name;
764 j += 35;
766 else
767 if (descriptor[j] == 'I')
769 type* new_type = type_create();
770 new_type->type_class = integer_type;
771 if (!parsing_return_type)
772 type_list_append(method->parameters, new_type);
773 else
775 method->return_type = new_type;
776 method->identifier_class = function_name;
779 else
780 if ((descriptor[j] == 'V') && (parsing_return_type))
782 method->identifier_class = procedure_name;
784 else
786 add_error_message(452, "", "");
787 break;
791 method->unit_function = 1;
792 method->container_unit = library_unit;
793 method_name = string_create();
794 method_name->length = constant_pool[method_name_index].data_len;
795 // Strings in class has no null char
796 method_name->cstr = malloc(method_name->length + 2);
797 strncpy(method_name->cstr, constant_pool[method_name_index].data, method_name->length);
798 method_name->cstr[method_name->length + 1] = '\0';
799 name_table_insert(library_unit->names, method_name, method);
802 /* skip over all attributes */
803 for (j=0; j<attributes_count; j++)
805 long int length;
806 int name = read_short_int(library_file);
807 length = read_long_int(library_file);
808 fseek(library_file, length, SEEK_CUR);
814 rlf_finally:
815 /* free the constant pool from the memory */
816 for (i = 1; i<constant_pool_count; i++)
818 if (constant_pool[i].data != NULL)
819 mem_free(constant_pool[i].data);
822 mem_free(constant_pool);
826 void read_symbol_file(FILE *symbol_file, struct unit_struct* library_unit)
828 char tag;
830 while(fread(&tag, 1, 1, symbol_file) == 1)
832 switch(tag)
834 case 1:
835 { /* constant */
836 identifier *constant;
837 string* name;
838 char type;
840 constant = identifier_create();
841 constant->identifier_class = constant_name;
842 constant->unit_function = 1;
843 constant->container_unit = library_unit;
845 name = bsf_read_STRING(symbol_file);
846 fread(&type, 1, 1, symbol_file);
848 constant->constant_type = type_create();
850 switch (type)
852 case 1:
853 constant->constant_type->type_class = integer_type;
854 fread(&constant->constant_int_value, sizeof(int), 1, symbol_file);
855 break;
856 case 2:
857 constant->constant_type->type_class = real_type;
858 fread(&constant->constant_real_value, sizeof(float), 1, symbol_file);
859 break;
860 case 3:
861 constant->constant_type->type_class = boolean_type;
862 fread(&constant->constant_int_value, sizeof(char), 1, symbol_file);
863 break;
864 case 4:
865 constant->constant_type->type_class = char_type;
866 fread(&constant->constant_int_value, sizeof(char), 1, symbol_file);
867 break;
868 case 5:
869 constant->constant_type->type_class = string_type;
870 constant->constant_string_value = bsf_read_STRING(symbol_file);
871 break;
874 name_table_insert(library_unit->names, name, constant);
876 break;
878 case 2:
880 string *var_name;
881 type *var_type;
882 identifier *variable = identifier_create();
884 variable->identifier_class = variable_name;
886 var_name = bsf_read_STRING(symbol_file);
887 var_type = bsf_read_TYPE(symbol_file);
889 variable->variable_type = var_type;
890 variable->unit_function = 1;
891 variable->container_unit = library_unit;
893 name_table_insert(library_unit->names, var_name, variable);
895 break;
897 case 3:
899 string *name;
900 identifier *type_identifier = identifier_create();
902 type_identifier->identifier_class = type_name;
904 name = bsf_read_STRING(symbol_file);
905 type_identifier->defined_type = bsf_read_TYPE(symbol_file);
906 type_identifier->unit_function = 1;
907 type_identifier->container_unit = library_unit;
909 name_table_insert(library_unit->names, name, type_identifier);
911 break;
913 case 4:
915 string *name;
916 char params;
917 identifier* procedure = identifier_create();
919 procedure->forward_declaration = 0;
920 procedure->standard_function = 0;
921 procedure->identifier_class = procedure_name;
922 procedure->unit_function = 1;
923 procedure->container_unit = library_unit;
924 procedure->subprogram_linenum = 1;
926 procedure->parameters = type_list_create();
928 name = bsf_read_STRING(symbol_file);
929 fread(&params, 1, 1, symbol_file);
931 while (params > 0)
933 type_list_append(procedure->parameters, bsf_read_TYPE(symbol_file));
934 params --;
937 name_table_insert(library_unit->names, name, procedure);
939 break;
941 case 5:
943 string *name;
944 char params;
945 identifier* function = identifier_create();
947 function->forward_declaration = 0;
948 function->standard_function = 0;
949 function->identifier_class = function_name;
950 function->unit_function = 1;
951 function->container_unit = library_unit;
952 function->subprogram_linenum = 1;
954 function->parameters = type_list_create();
956 name = bsf_read_STRING(symbol_file);
957 function->return_type = bsf_read_TYPE(symbol_file);
958 fread(&params, 1, 1, symbol_file);
960 while (params > 0)
962 type_list_append(function->parameters, bsf_read_TYPE(symbol_file));
963 params --;
966 name_table_insert(library_unit->names, name, function);
968 break;
974 /*
975 Adds parameters names into block.
976 */
977 void add_parameters(block *item, string_list *parameters_list,
978 type *parameters_type, int is_parameter_variable)
980 string_list *it;
981 identifier *descriptor;
983 it = parameters_list;
985 if (it->data == NULL)
987 type_destroy(parameters_type);
988 return;
991 while (it != NULL)
993 descriptor = identifier_create();
994 descriptor->identifier_class = parameter_name;
995 descriptor->parameter_index = item->next_parameter_index;
996 item-> next_parameter_index ++;
997 descriptor->parameter_type = type_duplicate(parameters_type);
998 descriptor->is_parameter_variable = is_parameter_variable;
999 name_table_insert(item->names, string_duplicate(it->data), descriptor);
1001 it = it->next;
1004 item->next_variable_index = item->next_parameter_index;
1006 type_destroy(parameters_type);
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 */
1017 void check_forward_declaration(identifier *declaration,
1018 type_list *parameters,
1019 int forward_declaration,
1020 type *return_type)
1022 int different_parameter;
1024 if ((declaration->identifier_class != procedure_name)
1025 && (declaration->identifier_class != function_name))
1027 return;
1030 if (forward_declaration)
1032 add_error_message(401, "", "");
1033 return;
1036 if ((return_type == NULL) /* it is a procedure */
1037 && (declaration->identifier_class == function_name))
1038 add_error_message(402, "function", "");
1040 if ((return_type != NULL) /* it is a function*/
1041 && (declaration->identifier_class == procedure_name))
1042 add_error_message(402, "procedure", "");
1044 different_parameter = type_list_different_parameter(
1045 parameters, declaration->parameters);
1047 if (different_parameter == -1)
1048 add_error_message(403, "", "");
1050 if (different_parameter > 0)
1052 char number[8];
1054 sprintf(number, "%d", different_parameter);
1055 add_error_message(404, number, "");
1058 if (return_type != NULL)
1060 if ((declaration->identifier_class != function_name) || (!type_equal(return_type, declaration->return_type)))
1061 add_error_message(405, "", "");
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 */
1070 void check_unmatched_forward_declarations(block *current_block, name_table *node)
1072 int i;
1073 identifier *declaration;
1075 if ((node == NULL) || (node->descriptor == NULL))
1076 return;
1078 declaration = node->descriptor;
1080 if (
1081 ((declaration->identifier_class == procedure_name) ||
1082 (declaration->identifier_class == function_name))
1083 && (declaration->forward_declaration == 1)
1086 new_linenum=declaration->subprogram_linenum;
1087 add_error_message(441, "", "");
1090 check_unmatched_forward_declarations(current_block, node->left_child);
1091 check_unmatched_forward_declarations(current_block, node->right_child);
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 */
1101 type *type_from_name(block *current_block, char *cstr)
1103 type *found_type;
1104 string *name;
1105 identifier *declaration;
1108 found_type = type_create();
1109 found_type->type_class = error_type;
1111 name = string_from_cstr(cstr);
1113 while (current_block != NULL)
1115 declaration = name_table_find(current_block->names, name);
1117 if (declaration != NULL)
1119 if (declaration->identifier_class == type_name)
1121 type_destroy(found_type);
1122 found_type = type_duplicate(declaration->defined_type);
1125 break;
1128 current_block = current_block->parent_block;
1131 string_destroy(name);
1132 return found_type;
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 */
1140 type *get_constant_type(block *current_block, char *cstr)
1142 type *found_type;
1143 string *name;
1144 identifier *declaration;
1146 found_type = type_create();
1147 found_type->type_class = error_type;
1149 name = string_from_cstr(cstr);
1151 while (current_block != NULL)
1153 declaration = name_table_find(current_block->names, name);
1155 if (declaration != NULL)
1157 if (declaration->identifier_class == constant_name)
1159 type_destroy(found_type);
1160 found_type = type_duplicate(declaration->constant_type);
1163 break;
1166 current_block = current_block->parent_block;
1169 string_destroy(name);
1170 return found_type;
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 */
1179 identifier *get_constant_identifier(block *current_block, char *cstr)
1181 string *name;
1182 identifier *found_constant = NULL;
1183 identifier *declaration;
1185 name = string_from_cstr(cstr);
1187 while (current_block != NULL)
1189 declaration = name_table_find(current_block->names, name);
1191 if (declaration != NULL)
1193 if (declaration->identifier_class == constant_name)
1194 found_constant = identifier_duplicate(declaration);
1196 break;
1199 current_block = current_block->parent_block;
1202 string_destroy(name);
1204 if (found_constant == NULL)
1205 found_constant = identifier_create();
1207 return found_constant;
1211 /*
1212 Return an identifier from a given name
1213 */
1214 identifier *get_identifier(block *current_block, char *cstr)
1216 string *name;
1217 identifier *found_identifier = NULL;
1218 identifier *declaration;
1219 name_table *name_table_it;
1221 name = string_from_cstr(cstr);
1223 while (current_block != NULL)
1225 declaration = name_table_find(current_block->names, name);
1227 if (declaration != NULL)
1229 found_identifier = identifier_duplicate(declaration);
1231 if (current_block->parent_block == root_block)
1232 found_identifier->belongs_to_program_block = 1;
1233 else
1234 found_identifier->belongs_to_program_block = 0;
1236 break;
1239 current_block = current_block->parent_block;
1242 string_destroy(name);
1244 if (found_identifier != NULL)
1245 return found_identifier;
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 */
1251 if (root_block->names->name != NULL)
1253 name_table_it = root_block->names;
1255 while (name_table_it != NULL)
1257 identifier *descriptor = name_table_it->descriptor;
1259 if (descriptor->identifier_class == unit_name)
1261 /*
1262 Search inside the unit for the given name
1263 */
1264 name_table *unit_table_it = descriptor->unit_block->names;
1266 if (unit_table_it->name != NULL)
1268 while (unit_table_it != NULL)
1270 if(STRING_COMPARE(string_get_cstr(unit_table_it->name),
1271 cstr) == 0)
1273 if (found_identifier == NULL)
1274 found_identifier = identifier_duplicate(unit_table_it->descriptor);
1275 else
1277 add_error_message(459, cstr, "");
1278 found_identifier = NULL;
1279 goto unit_search_done;
1284 unit_table_it = unit_table_it->next;
1289 name_table_it = name_table_it->next;
1293 unit_search_done:
1295 if (found_identifier == NULL)
1297 found_identifier = identifier_create();
1298 found_identifier->belongs_to_program_block = 0;
1301 return found_identifier;
1305 /*
1306 Returns the type of a variable given by its name.
1307 Return an error type if no variable was found.
1308 */
1309 type *get_variable_type(block *current_block, char *cstr)
1311 type *found_type;
1312 string *name;
1313 identifier *declaration;
1315 found_type = type_create();
1316 found_type->type_class = error_type;
1318 name = string_from_cstr(cstr);
1320 while (current_block != NULL)
1322 declaration = name_table_find(current_block->names, name);
1324 if (declaration != NULL)
1326 if (declaration->identifier_class == variable_name)
1327 found_type = type_duplicate(declaration->variable_type);
1329 break;
1332 current_block = current_block->parent_block;
1335 string_destroy(name);
1336 return found_type;
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)
1344 int storeIntoField = 0;
1346 /* if the variable belongs to the program block */
1347 if (variable->belongs_to_program_block)
1349 storeIntoField = 1;
1352 switch(variable->variable_type->type_class)
1354 case integer_type:
1355 case char_type:
1356 case boolean_type:
1358 bytecode_append(item->code, iconst_0$);
1360 if (!storeIntoField)
1362 switch(variable->variable_index)
1364 case 0:
1365 bytecode_append(item->code, istore_0$);
1366 break;
1367 case 1:
1368 bytecode_append(item->code, istore_1$);
1369 break;
1370 case 2:
1371 bytecode_append(item->code, istore_2$);
1372 break;
1373 case 3:
1374 bytecode_append(item->code, istore_3$);
1375 break;
1376 default:
1377 bytecode_append(item->code, istore$);
1378 bytecode_append(item->code, (char)variable->variable_index);
1379 break;
1383 break; // case integer_type
1385 case real_type:
1387 if (mathType == 1)
1389 bytecode_append(item->code, iconst_0$);
1391 if (!storeIntoField)
1393 switch(variable->variable_index)
1395 case 0:
1396 bytecode_append(item->code, istore_0$);
1397 break;
1398 case 1:
1399 bytecode_append(item->code, istore_1$);
1400 break;
1401 case 2:
1402 bytecode_append(item->code, istore_2$);
1403 break;
1404 case 3:
1405 bytecode_append(item->code, istore_3$);
1406 break;
1407 default:
1408 bytecode_append(item->code, istore$);
1409 bytecode_append(item->code, (char)variable->variable_index);
1410 break;
1414 else
1416 int method_index;
1417 int class_index;
1419 usesFloat = 1;
1421 class_index = cp_add_class("Real");
1422 method_index = cp_add_methodref("Real", "<init>", "()V");
1424 bytecode_append(item->code, new$);
1425 bytecode_append_short_int(item->code, (short)class_index);
1426 bytecode_append(item->code, dup$);
1427 bytecode_append(item->code, invokespecial$);
1428 bytecode_append_short_int(item->code, (short)method_index);
1430 if (!storeIntoField)
1432 switch(variable->variable_index)
1434 case 0:
1435 bytecode_append(item->code, astore_0$);
1436 break;
1437 case 1:
1438 bytecode_append(item->code, astore_1$);
1439 break;
1440 case 2:
1441 bytecode_append(item->code, astore_2$);
1442 break;
1443 case 3:
1444 bytecode_append(item->code, astore_3$);
1445 break;
1446 default:
1447 bytecode_append(item->code, astore$);
1448 bytecode_append(item->code, variable->variable_index);
1449 break;
1454 break;
1457 case string_type:
1459 int method_index;
1460 int class_index;
1462 class_index = cp_add_class("java/lang/String");
1463 method_index = cp_add_methodref("java/lang/String", "<init>", "()V");
1465 bytecode_append(item->code, new$);
1466 bytecode_append_short_int(item->code, (short)class_index);
1467 bytecode_append(item->code, dup$);
1468 bytecode_append(item->code, invokespecial$);
1469 bytecode_append_short_int(item->code, (short)method_index);
1471 if (!storeIntoField)
1473 switch(variable->variable_index)
1475 case 0:
1476 bytecode_append(item->code, astore_0$);
1477 break;
1478 case 1:
1479 bytecode_append(item->code, astore_1$);
1480 break;
1481 case 2:
1482 bytecode_append(item->code, astore_2$);
1483 break;
1484 case 3:
1485 bytecode_append(item->code, astore_3$);
1486 break;
1487 default:
1488 bytecode_append(item->code, astore$);
1489 bytecode_append(item->code, variable->variable_index);
1490 break;
1494 break;
1496 case image_type:
1498 int method_index = cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;");
1500 bytecode_append(item->code, iconst_1$);
1501 bytecode_append(item->code, iconst_1$);
1502 bytecode_append(item->code, invokestatic$);
1503 bytecode_append_short_int(item->code, method_index);
1505 if (!storeIntoField)
1507 switch(variable->variable_index)
1509 case 0:
1510 bytecode_append(item->code, astore_0$);
1511 break;
1512 case 1:
1513 bytecode_append(item->code, astore_1$);
1514 break;
1515 case 2:
1516 bytecode_append(item->code, astore_2$);
1517 break;
1518 case 3:
1519 bytecode_append(item->code, astore_3$);
1520 break;
1521 default:
1522 bytecode_append(item->code, astore$);
1523 bytecode_append(item->code, (char)variable->variable_index);
1524 break;
1528 break; // case image_type
1531 case stream_type:
1533 bytecode_append(item->code, aconst_null$);
1535 if (!storeIntoField)
1537 switch(variable->variable_index)
1539 case 0:
1540 bytecode_append(item->code, astore_0$);
1541 break;
1542 case 1:
1543 bytecode_append(item->code, astore_1$);
1544 break;
1545 case 2:
1546 bytecode_append(item->code, astore_2$);
1547 break;
1548 case 3:
1549 bytecode_append(item->code, astore_3$);
1550 break;
1551 default:
1552 bytecode_append(item->code, astore$);
1553 bytecode_append(item->code, (char)variable->variable_index);
1554 break;
1558 break; // case stream_type
1560 case command_type:
1562 int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
1564 bytecode_append(item->code, new$);
1565 bytecode_append_short_int(item->code, cp_add_class("javax/microedition/lcdui/Command"));
1566 bytecode_append(item->code, dup$);
1568 bytecode_append(item->code, new$);
1569 bytecode_append_short_int(item->code, cp_add_class("java/lang/String"));
1570 bytecode_append(item->code, dup$);
1571 bytecode_append(item->code, invokespecial$);
1572 bytecode_append_short_int(item->code, cp_add_methodref("java/lang/String", "<init>", "()V"));
1574 bytecode_append(item->code, iconst_1$);
1575 bytecode_append(item->code, iconst_1$);
1576 bytecode_append(item->code, invokespecial$);
1577 bytecode_append_short_int(item->code, method_index);
1579 if (!storeIntoField)
1581 switch(variable->variable_index)
1583 case 0:
1584 bytecode_append(item->code, astore_0$);
1585 break;
1586 case 1:
1587 bytecode_append(item->code, astore_1$);
1588 break;
1589 case 2:
1590 bytecode_append(item->code, astore_2$);
1591 break;
1592 case 3:
1593 bytecode_append(item->code, astore_3$);
1594 break;
1595 default:
1596 bytecode_append(item->code, astore$);
1597 bytecode_append(item->code, (char)variable->variable_index);
1598 break;
1602 break; // case command_type
1604 case http_type:
1606 int method_index = cp_add_methodref("H", "<init>", "()V");
1607 usesHttp = 1;
1609 bytecode_append(item->code, new$);
1610 bytecode_append_short_int(item->code, cp_add_class("H"));
1611 bytecode_append(item->code, dup$);
1613 bytecode_append(item->code, invokespecial$);
1614 bytecode_append_short_int(item->code, method_index);
1616 if (!storeIntoField)
1618 switch(variable->variable_index)
1620 case 0:
1621 bytecode_append(item->code, astore_0$);
1622 break;
1623 case 1:
1624 bytecode_append(item->code, astore_1$);
1625 break;
1626 case 2:
1627 bytecode_append(item->code, astore_2$);
1628 break;
1629 case 3:
1630 bytecode_append(item->code, astore_3$);
1631 break;
1632 default:
1633 bytecode_append(item->code, astore$);
1634 bytecode_append(item->code, (char)variable->variable_index);
1635 break;
1639 break; // case http_type
1641 case record_store_type:
1643 usesRecordStore = 1;
1644 /* no initialization needeed */
1646 break;
1648 case array_type:
1650 int count = 0;
1651 type_list *it = variable->variable_type->dimensions_list;
1652 char *descriptor;
1653 descriptor = (char*) mem_alloc(1024);
1654 if (descriptor == NULL)
1655 die(1);
1657 get_field_descriptor(variable->variable_type, descriptor);
1659 /* put dimensions on to the stack */
1660 while (it != NULL)
1662 if (it->data != NULL)
1664 int size;
1665 size = it->data->last_element - it->data->first_element + 1;
1667 if (size <= 0) {
1668 add_error_message(437, "", "");
1669 } else if (size <= 127) {
1670 bytecode_append(item->code, bipush$);
1671 bytecode_append(item->code, (char)size);
1672 } else if (size <= 32767) {
1673 bytecode_append(item->code, sipush$);
1674 bytecode_append_short_int(item->code, (short)size);
1675 } else {
1676 add_error_message(438, "", "");
1679 it = it->next;
1681 count ++;
1684 bytecode_append(item->code, multianewarray$);
1685 bytecode_append_short_int(item->code, cp_add_class(descriptor));
1686 bytecode_append(item->code, (char)count);
1688 // NEW:
1689 create_put_variable_bytecode(variable, item->code, name, storeIntoField);
1691 if((variable->variable_type->element_type->type_class == record_type)
1692 || (variable->variable_type->element_type->type_class == string_type)
1693 || ((variable->variable_type->element_type->type_class == real_type) && (mathType != 1))
1694 || (variable->variable_type->element_type->type_class == image_type)
1695 || (variable->variable_type->element_type->type_class == command_type))
1697 /* initialize the fields */
1698 unsigned short int c = 0;
1699 char descriptor[128];
1700 unsigned short int num;
1701 int *offsets;
1702 int *dimensions_sizes; // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1703 type_list *it = variable->variable_type->dimensions_list;
1705 while (it != NULL)
1707 it = it->next;
1708 c ++;
1711 if (variable->variable_type->element_type->type_class == real_type)
1712 usesFloat = 1;
1714 offsets = (int*) mem_alloc(c * sizeof(int));
1715 dimensions_sizes = (int*) mem_alloc(c * sizeof(int)); // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1716 num = c;
1718 /* reset */
1719 it = variable->variable_type->dimensions_list;
1720 c = 0;
1721 while (it != NULL)
1723 if (it->data != NULL)
1725 bytecode_append(item->code, getstatic$);
1726 bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
1727 bytecode_append(item->code, sipush$);
1728 bytecode_append_short_int(item->code, c);
1729 bytecode_append(item->code, iconst_0$);
1730 bytecode_append(item->code, iastore$);
1732 offsets[c] = item->code->bytecode_pos;
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
1735 c++;
1736 it = it->next;
1739 /* load */
1740 for(c=0; c<num; c++)
1742 if ((c < (num-1)) || (c == 0))
1744 // OLD: bytecode_append(item->code, dup$);
1745 // NEW:
1746 create_variable_bytecode(variable, item->code, name, storeIntoField);
1748 bytecode_append(item->code, getstatic$);
1749 bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
1750 bytecode_append(item->code, sipush$);
1751 bytecode_append_short_int(item->code, c);
1752 bytecode_append(item->code, iaload$);
1753 if (c < (num-1))
1754 bytecode_append(item->code, aaload$);
1757 /* new */
1758 get_field_descriptor(variable->variable_type->element_type, descriptor);
1759 descriptor[strlen(descriptor)-1] = '\0';
1761 if (variable->variable_type->element_type->type_class == image_type)
1763 bytecode_append(item->code, iconst_1$);
1764 bytecode_append(item->code, iconst_1$);
1765 bytecode_append(item->code, invokestatic$);
1766 bytecode_append_short_int(item->code, cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;"));
1768 else if (variable->variable_type->element_type->type_class == command_type)
1770 int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
1772 bytecode_append(item->code, new$);
1773 bytecode_append_short_int(item->code, cp_add_class("javax/microedition/lcdui/Command"));
1774 bytecode_append(item->code, dup$);
1776 bytecode_append(item->code, new$);
1777 bytecode_append_short_int(item->code, cp_add_class("java/lang/String"));
1778 bytecode_append(item->code, dup$);
1779 bytecode_append(item->code, invokespecial$);
1780 bytecode_append_short_int(item->code, cp_add_methodref("java/lang/String", "<init>", "()V"));
1782 bytecode_append(item->code, iconst_1$);
1783 bytecode_append(item->code, iconst_1$);
1784 bytecode_append(item->code, invokespecial$);
1785 bytecode_append_short_int(item->code, method_index);
1787 else
1789 bytecode_append(item->code, new$);
1790 bytecode_append_short_int(item->code, cp_add_class(descriptor+1));
1791 bytecode_append(item->code, dup$);
1792 bytecode_append(item->code, invokespecial$);
1793 bytecode_append_short_int(item->code, cp_add_methodref(descriptor+1, "<init>", "()V"));
1796 bytecode_append(item->code, aastore$);
1798 /* jump back */
1799 it = variable->variable_type->dimensions_list;
1800 c = num-1;
1801 while (it != NULL)
1803 if (it->data != NULL)
1805 short int offset;
1806 bytecode_append(item->code, getstatic$);
1807 bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
1808 bytecode_append(item->code, dup$);
1809 bytecode_append(item->code, sipush$);
1810 bytecode_append_short_int(item->code, c);
1811 bytecode_append(item->code, iaload$);
1812 bytecode_append(item->code, iconst_1$);
1813 bytecode_append(item->code, iadd$);
1814 bytecode_append(item->code, sipush$);
1815 bytecode_append_short_int(item->code, c);
1816 bytecode_append(item->code, swap$);
1817 bytecode_append(item->code, iastore$);
1818 /* the value is increased by one */
1820 bytecode_append(item->code, getstatic$);
1821 bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
1822 bytecode_append(item->code, sipush$);
1823 bytecode_append_short_int(item->code, c);
1824 bytecode_append(item->code, iaload$);
1825 bytecode_append(item->code, sipush$);
1826 bytecode_append_short_int(item->code,
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
1829 bytecode_append(item->code, if_icmple$);
1830 offset = offsets[c] - item->code->bytecode_pos + 1;
1831 bytecode_append_short_int(item->code, offset);
1833 c--;
1834 it = it->next;
1837 mem_free(offsets);
1840 /*OLD: if (!storeIntoField)
1842 switch(variable->variable_index)
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;
1861 } */
1863 mem_free(descriptor);
1865 break;
1866 } // case array_type
1868 case record_type:
1870 char *descriptor;
1871 descriptor = (char*) mem_alloc(1024);
1873 if(descriptor == NULL)
1874 die(1);
1876 get_field_descriptor(variable->variable_type, descriptor);
1878 descriptor[strlen(descriptor) - 1] = '\0';
1880 bytecode_append(item->code, new$);
1881 bytecode_append_short_int(item->code, cp_add_class(descriptor + 1));
1882 bytecode_append(item->code, dup$);
1883 bytecode_append(item->code, invokespecial$);
1884 bytecode_append_short_int(item->code, cp_add_methodref(descriptor + 1, "<init>", "()V"));
1886 mem_free(descriptor);
1888 if (!storeIntoField)
1890 switch(variable->variable_index)
1892 case 0:
1893 bytecode_append(item->code, astore_0$);
1894 break;
1895 case 1:
1896 bytecode_append(item->code, astore_1$);
1897 break;
1898 case 2:
1899 bytecode_append(item->code, astore_2$);
1900 break;
1901 case 3:
1902 bytecode_append(item->code, astore_3$);
1903 break;
1904 default:
1905 bytecode_append(item->code, astore$);
1906 bytecode_append(item->code, (char)variable->variable_index);
1907 break;
1911 break;
1913 case error_type:
1914 break;
1916 default:
1918 die(14);
1923 /* create the bytecode for storing data into the field */
1924 if ((storeIntoField)
1925 && (variable->variable_type->type_class != record_store_type)
1926 && (variable->variable_type->type_class != array_type)) /* array initialization stores the variable */
1928 int field_index;
1929 char descriptor[512];
1930 get_field_descriptor(variable->variable_type, descriptor);
1932 if (name == NULL)
1933 die(23);
1935 lowercase(name);
1936 field_index = cp_add_fieldref(class_name, name, descriptor);
1938 if (is_static)
1939 bytecode_append(item->code, putstatic$);
1940 else
1941 bytecode_append(item->code, putfield$);
1942 bytecode_append_short_int(item->code, (short)field_index);
1947 void transform_break_stmts(bytecode *code, int start_offset, int end_offset, int jump_pos)
1949 int jump_offset;
1950 int pos = start_offset;
1952 while (pos < end_offset)
1954 if (((unsigned char)(code->bytecode[pos]) == (unsigned char)break_stmt$)
1955 && ((pos + 2) < end_offset))
1957 if ((code->bytecode[pos+1] == 0)
1958 && (code->bytecode[pos+2] == 0))
1960 jump_offset = jump_pos - pos;
1961 code->bytecode[pos] = goto$;
1962 code->bytecode[pos+1] = (jump_offset) >> 8;
1963 code->bytecode[pos+2] = jump_offset;
1967 pos ++;
1972 /*
1973 Writes the class file based on the information provided in the
1974 root block.
1975 */
1976 void create_class_file(block *program_block, FILE *fp)
1978 int this_class_index;
1979 int super_class_index;
1980 int i;
1982 /*** Insert the additional data into the constant pool ***/
1983 if (compiling_unit == 0)
1985 this_class_index = cp_add_class("M");
1986 switch (canvasType)
1988 case NORMAL:
1989 super_class_index = cp_add_class("javax/microedition/lcdui/Canvas");
1990 break;
1991 case FULL_NOKIA:
1992 super_class_index = cp_add_class("com/nokia/mid/ui/FullCanvas");
1993 break;
1994 case FULL_MIDP20:
1995 super_class_index = cp_add_class("javax/microedition/lcdui/game/GameCanvas");
1996 break;
1999 else
2001 this_class_index = cp_add_class(string_get_cstr(str_program_name));
2002 super_class_index = cp_add_class("java/lang/Object");
2006 /* Insert the data needed by the methods into the constant pool */
2007 write_method(program_block, NULL);
2008 for(i=0; i<program_block->children_count; i++)
2010 write_method(program_block->children[i], NULL);
2012 write_block_fields(program_block->names, NULL);
2014 if (compiling_unit == 0)
2016 write_constructor(NULL);
2017 write_paint_method(NULL);
2018 write_run_method(NULL);
2019 write_keypressed_method(NULL);
2020 write_keyreleased_method(NULL);
2023 /* add data to constant poll that is later needed */
2024 cp_add_utf8("I");
2025 cp_add_utf8("T");
2026 cp_add_utf8("G");
2027 cp_add_utf8("KC");
2028 cp_add_utf8("KP");
2029 cp_add_utf8("IC");
2030 cp_add_utf8("[I");
2031 cp_add_utf8("Ljavax/microedition/lcdui/Image;");
2032 cp_add_utf8("LM;");
2033 cp_add_class("M");
2034 cp_add_utf8("Ljavax/microedition/lcdui/Graphics;");
2035 cp_add_class("java/lang/Runnable");
2036 cp_add_utf8("StackMap");
2038 /*** Write data to the file ***/
2040 /* write the header */
2041 create_class_file_header(fp);
2043 /* write constant pool */
2044 write_constant_pool(fp);
2046 /* write the access flags, set to ACC_PUBLIC and ACC_SUPER */
2047 write_short_int(fp, 0x0021);
2049 /* write the index to constat pool with this class description */
2050 write_short_int(fp, (short)this_class_index);
2052 /* write the index to constant pool with the super class description */
2053 write_short_int(fp, (short)super_class_index);
2055 if (compiling_unit == 0)
2057 /* we have 1 interface */
2058 write_short_int(fp, 1);
2060 write_short_int(fp, cp_add_class("java/lang/Runnable"));
2062 else
2064 /* unit has 0 interfaces */
2065 write_short_int(fp, 0);
2068 /* write the fields (global variables in pascal) */
2069 if (compiling_unit == 0)
2071 write_short_int(fp, (short)(program_block->next_variable_index + 7));
2073 /* write the RNG field */
2075 /* access flags: ACC_PUBLIC and ACC_STATIC */
2076 write_short_int(fp, 0x0001 | 0x0008);
2078 /* write the name index */
2079 write_short_int(fp, cp_add_utf8("RNG"));
2081 /* write the descriptor index */
2082 write_short_int(fp, cp_add_utf8("Ljava/util/Random;"));
2084 /* write 0 attributes */
2085 write_short_int(fp, 0);
2088 /* write the image (I) field */
2090 /* access flags: ACC_PUBLIC and ACC_STATIC */
2091 write_short_int(fp, 0x0001 | 0x0008);
2093 /* write the name index */
2094 write_short_int(fp, cp_add_utf8("I"));
2096 /* write the descriptor index */
2097 write_short_int(fp, cp_add_utf8("Ljavax/microedition/lcdui/Image;"));
2099 /* write 0 attributes */
2100 write_short_int(fp, 0);
2103 /* write the this (T) field */
2105 /* access flags: ACC_PUBLIC and ACC_STATIC */
2106 write_short_int(fp, 0x0001 | 0x0008);
2108 /* write the name index */
2109 write_short_int(fp, cp_add_utf8("T"));
2111 /* write the descriptor index */
2112 write_short_int(fp, cp_add_utf8("LM;"));
2114 /* write 0 attributes */
2115 write_short_int(fp, 0);
2119 /* write the graphics (G) field */
2121 /* access flags: ACC_PUBLIC and ACC_STATIC */
2122 write_short_int(fp, 0x0001 | 0x0008);
2124 /* write the name index */
2125 write_short_int(fp, cp_add_utf8("G"));
2127 /* write the descriptor index */
2128 write_short_int(fp, cp_add_utf8("Ljavax/microedition/lcdui/Graphics;"));
2130 /* write 0 attributes */
2131 write_short_int(fp, 0);
2134 /* write the key clicked (KC) field */
2136 /* access flags: ACC_PUBLIC and ACC_STATIC */
2137 write_short_int(fp, 0x0001 | 0x0008);
2139 /* write the name index */
2140 write_short_int(fp, cp_add_utf8("KC"));
2142 /* write the descriptor index */
2143 write_short_int(fp, cp_add_utf8("I"));
2145 /* write 0 attributes */
2146 write_short_int(fp, 0);
2149 /* write the key pressed (KP) field */
2151 /* access flags: ACC_PUBLIC and ACC_STATIC */
2152 write_short_int(fp, 0x0001 | 0x0008);
2154 /* write the name index */
2155 write_short_int(fp, cp_add_utf8("KP"));
2157 /* write the descriptor index */
2158 write_short_int(fp, cp_add_utf8("I"));
2160 /* write 0 attributes */
2161 write_short_int(fp, 0);
2164 /* write the INDEX COUNTER (IC) field */
2166 /* access flags: ACC_PUBLIC and ACC_STATIC */
2167 write_short_int(fp, 0x0001 | 0x0008);
2169 /* write the name index */
2170 write_short_int(fp, cp_add_utf8("IC"));
2172 /* write the descriptor index */
2173 write_short_int(fp, cp_add_utf8("[I"));
2175 /* write 0 attributes */
2176 write_short_int(fp, 0);
2179 else
2181 write_short_int(fp, (short)(program_block->next_variable_index));
2184 write_block_fields(program_block->names, fp);
2187 /* write the methods */
2188 if (compiling_unit == 0)
2190 /* write the methods count */
2191 write_short_int(fp, (short)(program_block->children_count + 6));
2193 /* write the constructor */
2194 write_constructor(fp);
2196 /* write the paint method */
2197 write_paint_method(fp);
2199 /* write the run method */
2200 write_run_method(fp);
2202 /* write the key pressed and key released methods */
2203 write_keypressed_method(fp);
2204 write_keyreleased_method(fp);
2206 else
2208 write_short_int(fp, (short)(program_block->children_count + 1));
2211 /* write all other methods */
2212 for(i=0; i<program_block->children_count; i++)
2214 write_method(program_block->children[i], fp);
2217 /* write the main (R) method - <clinit> for interfaces */
2218 write_method(program_block, fp);
2221 /* we have no attributes */
2222 write_short_int(fp, 0);
2225 // TODO: deallocate constant pool
2229 /*
2230 Writes the method to the file, if fp is NULL only add needeed
2231 data to the constant pool
2232 */
2233 void write_method(block *current_block, FILE *fp)
2235 identifier *block_identifier = NULL;
2236 stack_map_list *map_list;
2237 int code_attribute_length, code_attribute_length_offset;
2238 int stack_map_attribute_offset;
2239 int stack_map_size;
2240 int stack_map_entries;
2241 int tmp_offset;
2243 /* write access flags, ACC_PUBLIC and ACC_STATIC */
2244 write_short_int(fp, 0x0001 | 0x0008);
2246 if(current_block->parent_block == root_block)
2248 /*** it is the main block ***/
2250 /* write name index */
2251 if (compiling_unit == 0)
2252 write_short_int(fp, cp_add_utf8("R"));
2253 else
2254 write_short_int(fp, cp_add_utf8("<clinit>"));
2256 /* write the descriptor */
2257 write_short_int(fp, cp_add_utf8("()V"));
2259 else
2261 char *descriptor;
2262 int pos = 1;
2263 type_list *it;
2265 descriptor = (char*) mem_alloc(5*1024);
2267 if (descriptor == NULL)
2268 die(1);
2270 descriptor[0] = '(';
2272 /*** procedure or function ***/
2274 /* write name index */
2275 lowercase(current_block->block_name->cstr);
2276 write_short_int(fp, cp_add_utf8(current_block->block_name->cstr));
2278 /* write the descriptor */
2279 block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
2281 if ((block_identifier == NULL)
2282 || (block_identifier->identifier_class != function_name
2283 && block_identifier->identifier_class != procedure_name))
2285 mem_free(descriptor);
2286 die(17);
2289 it = block_identifier->parameters;
2291 while(it != NULL)
2293 if (it->data == NULL)
2294 break;
2296 get_field_descriptor(it->data, descriptor + pos);
2297 pos = strlen(descriptor);
2298 it = it->next;
2301 descriptor[pos] = ')';
2302 pos ++;
2303 descriptor[pos] = '\0';
2305 if (block_identifier->identifier_class == procedure_name)
2306 strcat(descriptor, "V");
2307 else
2308 get_field_descriptor(block_identifier->return_type, descriptor + pos);
2310 write_short_int(fp, cp_add_utf8(descriptor));
2312 mem_free(descriptor);
2315 //PREVERIFY map_list = preverify_bytecode(current_block->code, block_identifier);
2316 map_list = NULL;
2319 /* write the code */
2320 write_short_int(fp, 2); /* attribute count */
2322 write_short_int(fp, cp_add_utf8("Code"));
2323 if (fp != NULL)
2324 code_attribute_length_offset = ftell(fp);
2325 write_long_int(fp, current_block->code->bytecode_pos + 12); /* update the size later when we know it */
2326 code_attribute_length = current_block->code->bytecode_pos + 12;
2328 write_short_int(fp, 32); /* max stack */
2330 if (current_block->parent_block == root_block)
2331 write_short_int(fp, 0); /* max locals for program block */
2332 else
2333 write_short_int(fp, current_block->next_variable_index + 2); /* max locals */
2335 write_long_int(fp, current_block->code->bytecode_pos); /* code length */
2337 if(fp != NULL)
2338 fwrite(current_block->code->bytecode, current_block->code->bytecode_pos, 1, fp);
2340 write_short_int(fp, 0);
2341 if (map_list != NULL)
2343 write_short_int(fp, 1); /* The Code has one attribute (The StackMap attribute) */
2345 write_short_int(fp, cp_add_utf8("StackMap"));
2346 if (fp != NULL)
2347 stack_map_attribute_offset = ftell(fp);
2348 write_long_int(fp, 0); /* attribute length */
2349 write_short_int(fp, 0); /* number of entries; these two fields will be filled in later */
2351 stack_map_size = 2;
2352 stack_map_entries = 0;
2354 do
2356 int i;
2357 stack_map *map = stack_map_list_get(&map_list);
2359 if (map != NULL)
2360 write_short_int(fp, (short)(map->bytecode_offset));
2361 stack_map_size += 2;
2363 /* write the locals */
2364 if (current_block->parent_block == root_block)
2366 write_short_int(fp, 0);
2367 stack_map_size += 2;
2369 else
2371 identifier *block_identifier;
2373 /* write the StackMap for locals */
2374 block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
2376 write_short_int(fp, (short)current_block->next_variable_index);
2377 stack_map_size += 2;
2379 write_locals_stackmap(fp, block_identifier, &stack_map_size);
2382 if (map == NULL)
2383 break;
2385 /* write the stack items */
2386 write_short_int(fp, (short)map->number_of_items);
2387 stack_map_size += 2;
2388 for(i=0; i<map->number_of_items; i++)
2390 if (fp != NULL)
2392 fwrite(&(map->stack[i]->item_type), 1, 1, fp);
2395 if ((map->stack[i]->item_type == ITEM_Object)
2396 || (map->stack[i]->item_type == ITEM_NewObject))
2398 write_short_int(fp, map->stack[i]->additional_data);
2399 stack_map_size += 2;
2402 stack_map_size ++;
2405 stack_map_destroy(map);
2407 stack_map_entries ++;
2409 } while (map_list != NULL);
2411 /* write the stack map size and the number of entries and
2412 the code attribute length */
2413 if (fp != NULL)
2415 tmp_offset = ftell(fp);
2416 fseek(fp, stack_map_attribute_offset, SEEK_SET);
2417 write_long_int(fp, stack_map_size); /* attribute length */
2418 write_short_int(fp, (short)stack_map_entries); /* number of entries */
2420 fseek(fp, code_attribute_length_offset, SEEK_SET);
2421 write_long_int(fp, code_attribute_length + 6 + stack_map_size);
2423 fseek(fp, tmp_offset, SEEK_SET);
2426 else
2428 write_short_int(fp, 0);
2431 /* write the Exceptions attribute */
2432 write_short_int(fp, cp_add_utf8("Exceptions"));
2434 write_long_int(fp, 4);
2436 write_short_int(fp, 1);
2437 write_short_int(fp, cp_add_class("java/lang/Exception"));
2442 /*
2443 Creates the code for the following method:
2445 public void paint(Graphics g)
2447 g.drawImage(IMG, 0, 0, Graphics.TOP|Graphics.LEFT);
2449 */
2450 void write_paint_method(FILE *fp)
2452 bytecode *code = bytecode_create();
2453 if (code == NULL)
2454 die(1);
2456 /* create the code */
2458 /* PUSH param_1 */
2459 bytecode_append(code, aload_1$);
2461 /* PUSH (I) */
2462 bytecode_append(code, getstatic$);
2463 bytecode_append_short_int(code, cp_add_fieldref("M", "I", "Ljavax/microedition/lcdui/Image;"));
2465 /* PUSH 0; PUSH 0*/
2466 bytecode_append(code, iconst_0$);
2467 bytecode_append(code, iconst_0$);
2469 /* PUSH Graphics.LEFT|Graphics.TOP */
2470 bytecode_append(code, bipush$);
2471 bytecode_append(code, 20);
2473 /* invoke drawImage(Image, int, int, int) */
2474 bytecode_append(code, invokevirtual$);
2475 bytecode_append_short_int(code,
2476 cp_add_methodref("javax/microedition/lcdui/Graphics", "drawImage", "(Ljavax/microedition/lcdui/Image;III)V"));
2478 bytecode_append(code, return$);
2480 /* write the method headers */
2482 /* write access flags, ACC_PUBLIC */
2483 write_short_int(fp, 0x0001);
2485 /* write method name */
2486 write_short_int(fp, cp_add_utf8("paint"));
2488 /* write method descriptor */
2489 write_short_int(fp, cp_add_utf8("(Ljavax/microedition/lcdui/Graphics;)V"));
2491 /* write 1 attribute */
2492 write_short_int(fp, 1);
2494 /* write the Code attribute */
2495 write_short_int(fp, cp_add_utf8("Code"));
2496 write_long_int(fp, code->bytecode_pos + 12);
2498 /* write the max stack */
2499 write_short_int(fp, 10);
2501 /* max locals for program block */
2502 write_short_int(fp, 2);
2505 /* code length */
2506 write_long_int(fp, code->bytecode_pos);
2508 /* write the code itself */
2509 if (fp != NULL)
2510 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2512 bytecode_destroy(code);
2514 write_short_int(fp, 0);
2515 write_short_int(fp, 0);
2518 /*
2519 Creates the code for the following method:
2521 public void run()
2523 R();
2525 */
2526 void write_run_method(FILE *fp)
2528 char tag;
2530 bytecode *code = bytecode_create();
2531 if (code == NULL)
2532 die(1);
2534 /* create the code */
2535 bytecode_append(code, invokestatic$);
2536 bytecode_append_short_int(code, cp_add_methodref("M", "R", "()V"));
2537 bytecode_append(code, return$);
2539 /* write the method headers */
2541 /* write access flags, ACC_PUBLIC */
2542 write_short_int(fp, 0x0001);
2544 /* write method name */
2545 write_short_int(fp, cp_add_utf8("run"));
2547 /* write method descriptor */
2548 write_short_int(fp, cp_add_utf8("()V"));
2550 /* write 1 attribute */
2551 write_short_int(fp, 1);
2553 /* write the Code attribute */
2554 write_short_int(fp, cp_add_utf8("Code"));
2555 write_long_int(fp, code->bytecode_pos + 12);
2557 /* write the max stack */
2558 write_short_int(fp, 2);
2560 /* max locals for program block */
2561 write_short_int(fp, 2);
2564 /* code length */
2565 write_long_int(fp, code->bytecode_pos);
2567 /* write the code itself */
2568 if (fp != NULL)
2569 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2571 bytecode_destroy(code);
2573 write_short_int(fp, 0);
2574 write_short_int(fp, 0);
2578 /*
2579 Creates the code for the following methods:
2581 public void keyPressed(int keyCode)
2583 KC = keyCode;
2584 KP = keyCode;
2587 public void keyReleased(int keyCode)
2589 KP = 0;
2591 */
2592 void write_keypressed_method(FILE *fp)
2594 bytecode *code = bytecode_create();
2595 if (code == NULL)
2596 die(1);
2598 /* create the code */
2599 bytecode_append(code, iload_1$);
2600 bytecode_append(code, dup$);
2601 bytecode_append(code, putstatic$);
2602 bytecode_append_short_int(code, cp_add_fieldref("M", "KC", "I"));
2603 bytecode_append(code, putstatic$);
2604 bytecode_append_short_int(code, cp_add_fieldref("M", "KP", "I"));
2606 bytecode_append(code, return$);
2608 /* write the method headers */
2610 /* write access flags, ACC_PUBLIC */
2611 write_short_int(fp, 0x0001);
2613 /* write method name */
2614 write_short_int(fp, cp_add_utf8("keyPressed"));
2616 /* write method descriptor */
2617 write_short_int(fp, cp_add_utf8("(I)V"));
2619 /* write 1 attribute */
2620 write_short_int(fp, 1);
2622 /* write the Code attribute */
2623 write_short_int(fp, cp_add_utf8("Code"));
2624 write_long_int(fp, code->bytecode_pos + 12);
2626 /* write the max stack */
2627 write_short_int(fp, 2);
2629 /* max locals for program block */
2630 write_short_int(fp, 2);
2633 /* code length */
2634 write_long_int(fp, code->bytecode_pos);
2636 /* write the code itself */
2637 if (fp != NULL)
2638 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2640 bytecode_destroy(code);
2642 write_short_int(fp, 0);
2643 write_short_int(fp, 0);
2645 void write_keyreleased_method(FILE *fp)
2647 bytecode *code = bytecode_create();
2648 if (code == NULL)
2649 die(1);
2651 /* create the code */
2652 bytecode_append(code, iconst_0$);
2653 bytecode_append(code, putstatic$);
2654 bytecode_append_short_int(code, cp_add_fieldref("M", "KP", "I"));
2656 bytecode_append(code, return$);
2658 /* write the method headers */
2660 /* write access flags, ACC_PUBLIC */
2661 write_short_int(fp, 0x0001);
2663 /* write method name */
2664 write_short_int(fp, cp_add_utf8("keyReleased"));
2666 /* write method descriptor */
2667 write_short_int(fp, cp_add_utf8("(I)V"));
2669 /* write 1 attribute */
2670 write_short_int(fp, 1);
2672 /* write the Code attribute */
2673 write_short_int(fp, cp_add_utf8("Code"));
2674 write_long_int(fp, code->bytecode_pos + 12);
2676 /* write the max stack */
2677 write_short_int(fp, 2);
2679 /* max locals for program block */
2680 write_short_int(fp, 2);
2683 /* code length */
2684 write_long_int(fp, code->bytecode_pos);
2686 /* write the code itself */
2687 if (fp != NULL)
2688 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2690 bytecode_destroy(code);
2692 write_short_int(fp, 0);
2693 write_short_int(fp, 0);
2697 /*
2698 Creates the code for the class constructor.
2699 */
2700 void write_constructor(FILE *fp)
2702 bytecode *code = bytecode_create();
2703 if (code == NULL)
2704 die(1);
2706 /* create the code */
2707 switch (canvasType)
2709 case NORMAL:
2710 bytecode_append(code, aload_0$);
2711 bytecode_append(code, invokespecial$);
2712 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "<init>", "()V"));
2713 break;
2714 case FULL_NOKIA:
2715 bytecode_append(code, aload_0$);
2716 bytecode_append(code, invokespecial$);
2717 bytecode_append_short_int(code, cp_add_methodref("com/nokia/mid/ui/FullCanvas", "<init>", "()V"));
2718 break;
2719 case FULL_MIDP20:
2720 bytecode_append(code, aload_0$);
2721 bytecode_append(code, iconst_0$);
2722 bytecode_append(code, invokespecial$);
2723 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/game/GameCanvas", "<init>", "(Z)V"));
2725 bytecode_append(code, aload_0$);
2726 bytecode_append(code, iconst_1$);
2727 bytecode_append(code, invokevirtual$);
2728 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "setFullScreenMode", "(Z)V"));
2729 break;
2732 bytecode_append(code, return$);
2734 /* write the method headers */
2736 /* write access flags, ACC_PUBLIC */
2737 write_short_int(fp, 0x0001);
2739 /* write method name */
2740 write_short_int(fp, cp_add_utf8("<init>"));
2742 /* write method descriptor */
2743 write_short_int(fp, cp_add_utf8("()V"));
2745 /* write 1 attribute */
2746 write_short_int(fp, 1);
2748 /* write the Code attribute */
2749 write_short_int(fp, cp_add_utf8("Code"));
2750 write_long_int(fp, code->bytecode_pos + 12);
2752 /* write the max stack */
2753 write_short_int(fp, 10);
2755 /* max locals for program block */
2756 write_short_int(fp, 2);
2759 /* code length */
2760 write_long_int(fp, code->bytecode_pos);
2762 /* write the code itself */
2763 if (fp != NULL)
2764 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2766 bytecode_destroy(code);
2768 write_short_int(fp, 0);
2769 write_short_int(fp, 0);
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 */
2779 void write_block_fields(name_table *names, FILE *fp)
2781 char descriptor[128];
2783 if ((names->descriptor != NULL)
2784 && (names->descriptor->identifier_class == variable_name))
2786 /* access flags: ACC_PUBLIC and ACC_STATIC */
2787 write_short_int(fp, 0x0001 | 0x0008);
2789 /* write the name index */
2790 lowercase(names->name->cstr);
2791 write_short_int(fp, cp_add_utf8(names->name->cstr));
2793 /* write the descriptor index */
2794 get_field_descriptor(names->descriptor->variable_type, descriptor);
2795 write_short_int(fp, cp_add_utf8(descriptor));
2797 /* write 0 attributes */
2798 write_short_int(fp, 0);
2801 /* write the left child */
2802 if ((names->descriptor != NULL)
2803 && (names->left_child != NULL))
2805 write_block_fields(names->left_child, fp);
2808 /* write the right child */
2809 if ((names->descriptor != NULL)
2810 && (names->right_child != NULL))
2812 write_block_fields(names->right_child, fp);
2817 void write_locals_stackmap(FILE *fp, identifier *block_identifier, int *stack_map_size)
2819 type_list *it = block_identifier->parameters;
2820 write_stackmap(fp, it, stack_map_size);
2822 /* for functions, add the return value */
2823 if (block_identifier->identifier_class == function_name)
2825 it = type_list_create();
2826 type_list_append(it, block_identifier->return_type);
2827 write_stackmap(fp, it, stack_map_size);
2828 type_list_destroy(it);
2831 it = block_identifier->variables;
2832 write_stackmap(fp, it, stack_map_size);
2835 void write_stackmap(FILE *fp, type_list *it, int *stack_map_size)
2838 while (it != NULL)
2840 char c;
2842 if (it->data != NULL)
2844 switch(it->data->type_class)
2846 case integer_type:
2847 case char_type:
2848 case boolean_type:
2849 c = 1;
2850 if (fp != NULL)
2851 fwrite(&c, 1, 1, fp);
2852 (*stack_map_size) ++;
2853 break;
2855 case real_type:
2857 if (mathType == 1)
2859 c = 1;
2860 if (fp != NULL)
2861 fwrite(&c, 1, 1, fp);
2862 (*stack_map_size) ++;
2864 else
2866 c = 7;
2867 if (fp != NULL)
2868 fwrite(&c, 1, 1, fp);
2869 write_short_int(fp, cp_add_class("Real"));
2870 (*stack_map_size) += 3;
2873 break;
2875 case string_type:
2876 c = 7;
2877 if (fp != NULL)
2878 fwrite(&c, 1, 1, fp);
2879 write_short_int(fp, cp_add_class("java/lang/String"));
2880 (*stack_map_size) += 3;
2881 break;
2883 case image_type:
2884 c = 7;
2885 if (fp != NULL)
2886 fwrite(&c, 1, 1, fp);
2887 write_short_int(fp, cp_add_class("javax/microedition/lcdui/Image"));
2888 (*stack_map_size) += 3;
2889 break;
2891 case command_type:
2892 c = 7;
2893 if (fp != NULL)
2894 fwrite(&c, 1, 1, fp);
2895 write_short_int(fp, cp_add_class("javax/microedition/lcdui/Command"));
2896 (*stack_map_size) += 3;
2897 break;
2900 case stream_type:
2901 c = 7;
2902 if (fp != NULL)
2903 fwrite(&c, 1, 1, fp);
2904 write_short_int(fp, cp_add_class("java/io/InputStream"));
2905 (*stack_map_size) += 3;
2906 break;
2908 case record_store_type:
2909 c = 7;
2910 if (fp != NULL)
2911 fwrite(&c, 1, 1, fp);
2912 write_short_int(fp, cp_add_class("javax/microedition/rms/RecordStore"));
2913 (*stack_map_size) += 3;
2914 break;
2916 case http_type:
2917 c = 7;
2918 if (fp != NULL)
2919 fwrite(&c, 1, 1, fp);
2920 write_short_int(fp, cp_add_class("H"));
2921 (*stack_map_size) += 3;
2922 break;
2924 case alert_type:
2925 c = 7;
2926 if (fp != NULL)
2927 fwrite(&c, 1, 1, fp);
2928 write_short_int(fp, cp_add_class("Ljavax/microedition/lcdui/AlertType;"));
2929 (*stack_map_size) += 3;
2930 break;
2932 case array_type:
2934 char descriptor[512];
2935 char element_type[128];
2936 int i, len;
2938 get_field_descriptor(it->data->element_type, element_type);
2940 len = type_list_length(it->data->dimensions_list);
2941 for(i=0; i < len; i++)
2943 descriptor[i] = '[';
2946 descriptor[len] = '\0';
2948 sprintf(descriptor + len, "%s", element_type);
2950 c = 7;
2951 if (fp != NULL)
2952 fwrite(&c, 1, 1, fp);
2953 write_short_int(fp, cp_add_class(descriptor));
2954 (*stack_map_size) += 3;
2956 break;
2958 case record_type:
2960 char descriptor[16];
2961 c = 7;
2962 if (fp != NULL)
2963 fwrite(&c, 1, 1, fp);
2964 sprintf(descriptor, "R_%d", it->data->unique_record_ID);
2965 write_short_int(fp, cp_add_class(descriptor));
2966 (*stack_map_size) += 3;
2968 break;
2972 it = it->next;