DEADSOFTWARE

cb7b9d4bdf085b1e561905672b59464d49f72aef
[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 method_name->cstr = malloc(method_name->length + 1);
796 strcpy(method_name->cstr, constant_pool[method_name_index].data);
797 method_name->cstr[method_name->length] = '\0';
798 name_table_insert(library_unit->names, method_name, method);
801 /* skip over all attributes */
802 for (j=0; j<attributes_count; j++)
804 long int length;
805 int name = read_short_int(library_file);
806 length = read_long_int(library_file);
807 fseek(library_file, length, SEEK_CUR);
813 rlf_finally:
814 /* free the constant pool from the memory */
815 for (i = 1; i<constant_pool_count; i++)
817 if (constant_pool[i].data != NULL)
818 mem_free(constant_pool[i].data);
821 mem_free(constant_pool);
825 void read_symbol_file(FILE *symbol_file, struct unit_struct* library_unit)
827 char tag;
829 while(fread(&tag, 1, 1, symbol_file) == 1)
831 switch(tag)
833 case 1:
834 { /* constant */
835 identifier *constant;
836 string* name;
837 char type;
839 constant = identifier_create();
840 constant->identifier_class = constant_name;
841 constant->unit_function = 1;
842 constant->container_unit = library_unit;
844 name = bsf_read_STRING(symbol_file);
845 fread(&type, 1, 1, symbol_file);
847 constant->constant_type = type_create();
849 switch (type)
851 case 1:
852 constant->constant_type->type_class = integer_type;
853 fread(&constant->constant_int_value, sizeof(int), 1, symbol_file);
854 break;
855 case 2:
856 constant->constant_type->type_class = real_type;
857 fread(&constant->constant_real_value, sizeof(float), 1, symbol_file);
858 break;
859 case 3:
860 constant->constant_type->type_class = boolean_type;
861 fread(&constant->constant_int_value, sizeof(char), 1, symbol_file);
862 break;
863 case 4:
864 constant->constant_type->type_class = char_type;
865 fread(&constant->constant_int_value, sizeof(char), 1, symbol_file);
866 break;
867 case 5:
868 constant->constant_type->type_class = string_type;
869 constant->constant_string_value = bsf_read_STRING(symbol_file);
870 break;
873 name_table_insert(library_unit->names, name, constant);
875 break;
877 case 2:
879 string *var_name;
880 type *var_type;
881 identifier *variable = identifier_create();
883 variable->identifier_class = variable_name;
885 var_name = bsf_read_STRING(symbol_file);
886 var_type = bsf_read_TYPE(symbol_file);
888 variable->variable_type = var_type;
889 variable->unit_function = 1;
890 variable->container_unit = library_unit;
892 name_table_insert(library_unit->names, var_name, variable);
894 break;
896 case 3:
898 string *name;
899 identifier *type_identifier = identifier_create();
901 type_identifier->identifier_class = type_name;
903 name = bsf_read_STRING(symbol_file);
904 type_identifier->defined_type = bsf_read_TYPE(symbol_file);
905 type_identifier->unit_function = 1;
906 type_identifier->container_unit = library_unit;
908 name_table_insert(library_unit->names, name, type_identifier);
910 break;
912 case 4:
914 string *name;
915 char params;
916 identifier* procedure = identifier_create();
918 procedure->forward_declaration = 0;
919 procedure->standard_function = 0;
920 procedure->identifier_class = procedure_name;
921 procedure->unit_function = 1;
922 procedure->container_unit = library_unit;
923 procedure->subprogram_linenum = 1;
925 procedure->parameters = type_list_create();
927 name = bsf_read_STRING(symbol_file);
928 fread(&params, 1, 1, symbol_file);
930 while (params > 0)
932 type_list_append(procedure->parameters, bsf_read_TYPE(symbol_file));
933 params --;
936 name_table_insert(library_unit->names, name, procedure);
938 break;
940 case 5:
942 string *name;
943 char params;
944 identifier* function = identifier_create();
946 function->forward_declaration = 0;
947 function->standard_function = 0;
948 function->identifier_class = function_name;
949 function->unit_function = 1;
950 function->container_unit = library_unit;
951 function->subprogram_linenum = 1;
953 function->parameters = type_list_create();
955 name = bsf_read_STRING(symbol_file);
956 function->return_type = bsf_read_TYPE(symbol_file);
957 fread(&params, 1, 1, symbol_file);
959 while (params > 0)
961 type_list_append(function->parameters, bsf_read_TYPE(symbol_file));
962 params --;
965 name_table_insert(library_unit->names, name, function);
967 break;
973 /*
974 Adds parameters names into block.
975 */
976 void add_parameters(block *item, string_list *parameters_list,
977 type *parameters_type, int is_parameter_variable)
979 string_list *it;
980 identifier *descriptor;
982 it = parameters_list;
984 if (it->data == NULL)
986 type_destroy(parameters_type);
987 return;
990 while (it != NULL)
992 descriptor = identifier_create();
993 descriptor->identifier_class = parameter_name;
994 descriptor->parameter_index = item->next_parameter_index;
995 item-> next_parameter_index ++;
996 descriptor->parameter_type = type_duplicate(parameters_type);
997 descriptor->is_parameter_variable = is_parameter_variable;
998 name_table_insert(item->names, string_duplicate(it->data), descriptor);
1000 it = it->next;
1003 item->next_variable_index = item->next_parameter_index;
1005 type_destroy(parameters_type);
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 */
1016 void check_forward_declaration(identifier *declaration,
1017 type_list *parameters,
1018 int forward_declaration,
1019 type *return_type)
1021 int different_parameter;
1023 if ((declaration->identifier_class != procedure_name)
1024 && (declaration->identifier_class != function_name))
1026 return;
1029 if (forward_declaration)
1031 add_error_message(401, "", "");
1032 return;
1035 if ((return_type == NULL) /* it is a procedure */
1036 && (declaration->identifier_class == function_name))
1037 add_error_message(402, "function", "");
1039 if ((return_type != NULL) /* it is a function*/
1040 && (declaration->identifier_class == procedure_name))
1041 add_error_message(402, "procedure", "");
1043 different_parameter = type_list_different_parameter(
1044 parameters, declaration->parameters);
1046 if (different_parameter == -1)
1047 add_error_message(403, "", "");
1049 if (different_parameter > 0)
1051 char number[8];
1053 sprintf(number, "%d", different_parameter);
1054 add_error_message(404, number, "");
1057 if (return_type != NULL)
1059 if ((declaration->identifier_class != function_name) || (!type_equal(return_type, declaration->return_type)))
1060 add_error_message(405, "", "");
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 */
1069 void check_unmatched_forward_declarations(block *current_block, name_table *node)
1071 int i;
1072 identifier *declaration;
1074 if ((node == NULL) || (node->descriptor == NULL))
1075 return;
1077 declaration = node->descriptor;
1079 if (
1080 ((declaration->identifier_class == procedure_name) ||
1081 (declaration->identifier_class == function_name))
1082 && (declaration->forward_declaration == 1)
1085 new_linenum=declaration->subprogram_linenum;
1086 add_error_message(441, "", "");
1089 check_unmatched_forward_declarations(current_block, node->left_child);
1090 check_unmatched_forward_declarations(current_block, node->right_child);
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 */
1100 type *type_from_name(block *current_block, char *cstr)
1102 type *found_type;
1103 string *name;
1104 identifier *declaration;
1107 found_type = type_create();
1108 found_type->type_class = error_type;
1110 name = string_from_cstr(cstr);
1112 while (current_block != NULL)
1114 declaration = name_table_find(current_block->names, name);
1116 if (declaration != NULL)
1118 if (declaration->identifier_class == type_name)
1120 type_destroy(found_type);
1121 found_type = type_duplicate(declaration->defined_type);
1124 break;
1127 current_block = current_block->parent_block;
1130 string_destroy(name);
1131 return found_type;
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 */
1139 type *get_constant_type(block *current_block, char *cstr)
1141 type *found_type;
1142 string *name;
1143 identifier *declaration;
1145 found_type = type_create();
1146 found_type->type_class = error_type;
1148 name = string_from_cstr(cstr);
1150 while (current_block != NULL)
1152 declaration = name_table_find(current_block->names, name);
1154 if (declaration != NULL)
1156 if (declaration->identifier_class == constant_name)
1158 type_destroy(found_type);
1159 found_type = type_duplicate(declaration->constant_type);
1162 break;
1165 current_block = current_block->parent_block;
1168 string_destroy(name);
1169 return found_type;
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 */
1178 identifier *get_constant_identifier(block *current_block, char *cstr)
1180 string *name;
1181 identifier *found_constant = NULL;
1182 identifier *declaration;
1184 name = string_from_cstr(cstr);
1186 while (current_block != NULL)
1188 declaration = name_table_find(current_block->names, name);
1190 if (declaration != NULL)
1192 if (declaration->identifier_class == constant_name)
1193 found_constant = identifier_duplicate(declaration);
1195 break;
1198 current_block = current_block->parent_block;
1201 string_destroy(name);
1203 if (found_constant == NULL)
1204 found_constant = identifier_create();
1206 return found_constant;
1210 /*
1211 Return an identifier from a given name
1212 */
1213 identifier *get_identifier(block *current_block, char *cstr)
1215 string *name;
1216 identifier *found_identifier = NULL;
1217 identifier *declaration;
1218 name_table *name_table_it;
1220 name = string_from_cstr(cstr);
1222 while (current_block != NULL)
1224 declaration = name_table_find(current_block->names, name);
1226 if (declaration != NULL)
1228 found_identifier = identifier_duplicate(declaration);
1230 if (current_block->parent_block == root_block)
1231 found_identifier->belongs_to_program_block = 1;
1232 else
1233 found_identifier->belongs_to_program_block = 0;
1235 break;
1238 current_block = current_block->parent_block;
1241 string_destroy(name);
1243 if (found_identifier != NULL)
1244 return found_identifier;
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 */
1250 if (root_block->names->name != NULL)
1252 name_table_it = root_block->names;
1254 while (name_table_it != NULL)
1256 identifier *descriptor = name_table_it->descriptor;
1258 if (descriptor->identifier_class == unit_name)
1260 /*
1261 Search inside the unit for the given name
1262 */
1263 name_table *unit_table_it = descriptor->unit_block->names;
1265 if (unit_table_it->name != NULL)
1267 while (unit_table_it != NULL)
1269 if(STRING_COMPARE(string_get_cstr(unit_table_it->name),
1270 cstr) == 0)
1272 if (found_identifier == NULL)
1273 found_identifier = identifier_duplicate(unit_table_it->descriptor);
1274 else
1276 add_error_message(459, cstr, "");
1277 found_identifier = NULL;
1278 goto unit_search_done;
1283 unit_table_it = unit_table_it->next;
1288 name_table_it = name_table_it->next;
1292 unit_search_done:
1294 if (found_identifier == NULL)
1296 found_identifier = identifier_create();
1297 found_identifier->belongs_to_program_block = 0;
1300 return found_identifier;
1304 /*
1305 Returns the type of a variable given by its name.
1306 Return an error type if no variable was found.
1307 */
1308 type *get_variable_type(block *current_block, char *cstr)
1310 type *found_type;
1311 string *name;
1312 identifier *declaration;
1314 found_type = type_create();
1315 found_type->type_class = error_type;
1317 name = string_from_cstr(cstr);
1319 while (current_block != NULL)
1321 declaration = name_table_find(current_block->names, name);
1323 if (declaration != NULL)
1325 if (declaration->identifier_class == variable_name)
1326 found_type = type_duplicate(declaration->variable_type);
1328 break;
1331 current_block = current_block->parent_block;
1334 string_destroy(name);
1335 return found_type;
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)
1343 int storeIntoField = 0;
1345 /* if the variable belongs to the program block */
1346 if (variable->belongs_to_program_block)
1348 storeIntoField = 1;
1351 switch(variable->variable_type->type_class)
1353 case integer_type:
1354 case char_type:
1355 case boolean_type:
1357 bytecode_append(item->code, iconst_0$);
1359 if (!storeIntoField)
1361 switch(variable->variable_index)
1363 case 0:
1364 bytecode_append(item->code, istore_0$);
1365 break;
1366 case 1:
1367 bytecode_append(item->code, istore_1$);
1368 break;
1369 case 2:
1370 bytecode_append(item->code, istore_2$);
1371 break;
1372 case 3:
1373 bytecode_append(item->code, istore_3$);
1374 break;
1375 default:
1376 bytecode_append(item->code, istore$);
1377 bytecode_append(item->code, (char)variable->variable_index);
1378 break;
1382 break; // case integer_type
1384 case real_type:
1386 if (mathType == 1)
1388 bytecode_append(item->code, iconst_0$);
1390 if (!storeIntoField)
1392 switch(variable->variable_index)
1394 case 0:
1395 bytecode_append(item->code, istore_0$);
1396 break;
1397 case 1:
1398 bytecode_append(item->code, istore_1$);
1399 break;
1400 case 2:
1401 bytecode_append(item->code, istore_2$);
1402 break;
1403 case 3:
1404 bytecode_append(item->code, istore_3$);
1405 break;
1406 default:
1407 bytecode_append(item->code, istore$);
1408 bytecode_append(item->code, (char)variable->variable_index);
1409 break;
1413 else
1415 int method_index;
1416 int class_index;
1418 usesFloat = 1;
1420 class_index = cp_add_class("Real");
1421 method_index = cp_add_methodref("Real", "<init>", "()V");
1423 bytecode_append(item->code, new$);
1424 bytecode_append_short_int(item->code, (short)class_index);
1425 bytecode_append(item->code, dup$);
1426 bytecode_append(item->code, invokespecial$);
1427 bytecode_append_short_int(item->code, (short)method_index);
1429 if (!storeIntoField)
1431 switch(variable->variable_index)
1433 case 0:
1434 bytecode_append(item->code, astore_0$);
1435 break;
1436 case 1:
1437 bytecode_append(item->code, astore_1$);
1438 break;
1439 case 2:
1440 bytecode_append(item->code, astore_2$);
1441 break;
1442 case 3:
1443 bytecode_append(item->code, astore_3$);
1444 break;
1445 default:
1446 bytecode_append(item->code, astore$);
1447 bytecode_append(item->code, variable->variable_index);
1448 break;
1453 break;
1456 case string_type:
1458 int method_index;
1459 int class_index;
1461 class_index = cp_add_class("java/lang/String");
1462 method_index = cp_add_methodref("java/lang/String", "<init>", "()V");
1464 bytecode_append(item->code, new$);
1465 bytecode_append_short_int(item->code, (short)class_index);
1466 bytecode_append(item->code, dup$);
1467 bytecode_append(item->code, invokespecial$);
1468 bytecode_append_short_int(item->code, (short)method_index);
1470 if (!storeIntoField)
1472 switch(variable->variable_index)
1474 case 0:
1475 bytecode_append(item->code, astore_0$);
1476 break;
1477 case 1:
1478 bytecode_append(item->code, astore_1$);
1479 break;
1480 case 2:
1481 bytecode_append(item->code, astore_2$);
1482 break;
1483 case 3:
1484 bytecode_append(item->code, astore_3$);
1485 break;
1486 default:
1487 bytecode_append(item->code, astore$);
1488 bytecode_append(item->code, variable->variable_index);
1489 break;
1493 break;
1495 case image_type:
1497 int method_index = cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;");
1499 bytecode_append(item->code, iconst_1$);
1500 bytecode_append(item->code, iconst_1$);
1501 bytecode_append(item->code, invokestatic$);
1502 bytecode_append_short_int(item->code, method_index);
1504 if (!storeIntoField)
1506 switch(variable->variable_index)
1508 case 0:
1509 bytecode_append(item->code, astore_0$);
1510 break;
1511 case 1:
1512 bytecode_append(item->code, astore_1$);
1513 break;
1514 case 2:
1515 bytecode_append(item->code, astore_2$);
1516 break;
1517 case 3:
1518 bytecode_append(item->code, astore_3$);
1519 break;
1520 default:
1521 bytecode_append(item->code, astore$);
1522 bytecode_append(item->code, (char)variable->variable_index);
1523 break;
1527 break; // case image_type
1530 case stream_type:
1532 bytecode_append(item->code, aconst_null$);
1534 if (!storeIntoField)
1536 switch(variable->variable_index)
1538 case 0:
1539 bytecode_append(item->code, astore_0$);
1540 break;
1541 case 1:
1542 bytecode_append(item->code, astore_1$);
1543 break;
1544 case 2:
1545 bytecode_append(item->code, astore_2$);
1546 break;
1547 case 3:
1548 bytecode_append(item->code, astore_3$);
1549 break;
1550 default:
1551 bytecode_append(item->code, astore$);
1552 bytecode_append(item->code, (char)variable->variable_index);
1553 break;
1557 break; // case stream_type
1559 case command_type:
1561 int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
1563 bytecode_append(item->code, new$);
1564 bytecode_append_short_int(item->code, cp_add_class("javax/microedition/lcdui/Command"));
1565 bytecode_append(item->code, dup$);
1567 bytecode_append(item->code, new$);
1568 bytecode_append_short_int(item->code, cp_add_class("java/lang/String"));
1569 bytecode_append(item->code, dup$);
1570 bytecode_append(item->code, invokespecial$);
1571 bytecode_append_short_int(item->code, cp_add_methodref("java/lang/String", "<init>", "()V"));
1573 bytecode_append(item->code, iconst_1$);
1574 bytecode_append(item->code, iconst_1$);
1575 bytecode_append(item->code, invokespecial$);
1576 bytecode_append_short_int(item->code, method_index);
1578 if (!storeIntoField)
1580 switch(variable->variable_index)
1582 case 0:
1583 bytecode_append(item->code, astore_0$);
1584 break;
1585 case 1:
1586 bytecode_append(item->code, astore_1$);
1587 break;
1588 case 2:
1589 bytecode_append(item->code, astore_2$);
1590 break;
1591 case 3:
1592 bytecode_append(item->code, astore_3$);
1593 break;
1594 default:
1595 bytecode_append(item->code, astore$);
1596 bytecode_append(item->code, (char)variable->variable_index);
1597 break;
1601 break; // case command_type
1603 case http_type:
1605 int method_index = cp_add_methodref("H", "<init>", "()V");
1606 usesHttp = 1;
1608 bytecode_append(item->code, new$);
1609 bytecode_append_short_int(item->code, cp_add_class("H"));
1610 bytecode_append(item->code, dup$);
1612 bytecode_append(item->code, invokespecial$);
1613 bytecode_append_short_int(item->code, method_index);
1615 if (!storeIntoField)
1617 switch(variable->variable_index)
1619 case 0:
1620 bytecode_append(item->code, astore_0$);
1621 break;
1622 case 1:
1623 bytecode_append(item->code, astore_1$);
1624 break;
1625 case 2:
1626 bytecode_append(item->code, astore_2$);
1627 break;
1628 case 3:
1629 bytecode_append(item->code, astore_3$);
1630 break;
1631 default:
1632 bytecode_append(item->code, astore$);
1633 bytecode_append(item->code, (char)variable->variable_index);
1634 break;
1638 break; // case http_type
1640 case record_store_type:
1642 usesRecordStore = 1;
1643 /* no initialization needeed */
1645 break;
1647 case array_type:
1649 int count = 0;
1650 type_list *it = variable->variable_type->dimensions_list;
1651 char *descriptor;
1652 descriptor = (char*) mem_alloc(1024);
1653 if (descriptor == NULL)
1654 die(1);
1656 get_field_descriptor(variable->variable_type, descriptor);
1658 /* put dimensions on to the stack */
1659 while (it != NULL)
1661 if (it->data != NULL)
1663 int size;
1664 size = it->data->last_element - it->data->first_element + 1;
1666 if (size <= 0) {
1667 add_error_message(437, "", "");
1668 } else if (size <= 127) {
1669 bytecode_append(item->code, bipush$);
1670 bytecode_append(item->code, (char)size);
1671 } else if (size <= 32767) {
1672 bytecode_append(item->code, sipush$);
1673 bytecode_append_short_int(item->code, (short)size);
1674 } else {
1675 add_error_message(438, "", "");
1678 it = it->next;
1680 count ++;
1683 bytecode_append(item->code, multianewarray$);
1684 bytecode_append_short_int(item->code, cp_add_class(descriptor));
1685 bytecode_append(item->code, (char)count);
1687 // NEW:
1688 create_put_variable_bytecode(variable, item->code, name, storeIntoField);
1690 if((variable->variable_type->element_type->type_class == record_type)
1691 || (variable->variable_type->element_type->type_class == string_type)
1692 || ((variable->variable_type->element_type->type_class == real_type) && (mathType != 1))
1693 || (variable->variable_type->element_type->type_class == image_type)
1694 || (variable->variable_type->element_type->type_class == command_type))
1696 /* initialize the fields */
1697 unsigned short int c = 0;
1698 char descriptor[128];
1699 unsigned short int num;
1700 int *offsets;
1701 int *dimensions_sizes; // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1702 type_list *it = variable->variable_type->dimensions_list;
1704 while (it != NULL)
1706 it = it->next;
1707 c ++;
1710 if (variable->variable_type->element_type->type_class == real_type)
1711 usesFloat = 1;
1713 offsets = (int*) mem_alloc(c * sizeof(int));
1714 dimensions_sizes = (int*) mem_alloc(c * sizeof(int)); // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
1715 num = c;
1717 /* reset */
1718 it = variable->variable_type->dimensions_list;
1719 c = 0;
1720 while (it != NULL)
1722 if (it->data != NULL)
1724 bytecode_append(item->code, getstatic$);
1725 bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
1726 bytecode_append(item->code, sipush$);
1727 bytecode_append_short_int(item->code, c);
1728 bytecode_append(item->code, iconst_0$);
1729 bytecode_append(item->code, iastore$);
1731 offsets[c] = item->code->bytecode_pos;
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
1734 c++;
1735 it = it->next;
1738 /* load */
1739 for(c=0; c<num; c++)
1741 if ((c < (num-1)) || (c == 0))
1743 // OLD: bytecode_append(item->code, dup$);
1744 // NEW:
1745 create_variable_bytecode(variable, item->code, name, storeIntoField);
1747 bytecode_append(item->code, getstatic$);
1748 bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
1749 bytecode_append(item->code, sipush$);
1750 bytecode_append_short_int(item->code, c);
1751 bytecode_append(item->code, iaload$);
1752 if (c < (num-1))
1753 bytecode_append(item->code, aaload$);
1756 /* new */
1757 get_field_descriptor(variable->variable_type->element_type, descriptor);
1758 descriptor[strlen(descriptor)-1] = '\0';
1760 if (variable->variable_type->element_type->type_class == image_type)
1762 bytecode_append(item->code, iconst_1$);
1763 bytecode_append(item->code, iconst_1$);
1764 bytecode_append(item->code, invokestatic$);
1765 bytecode_append_short_int(item->code, cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;"));
1767 else if (variable->variable_type->element_type->type_class == command_type)
1769 int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
1771 bytecode_append(item->code, new$);
1772 bytecode_append_short_int(item->code, cp_add_class("javax/microedition/lcdui/Command"));
1773 bytecode_append(item->code, dup$);
1775 bytecode_append(item->code, new$);
1776 bytecode_append_short_int(item->code, cp_add_class("java/lang/String"));
1777 bytecode_append(item->code, dup$);
1778 bytecode_append(item->code, invokespecial$);
1779 bytecode_append_short_int(item->code, cp_add_methodref("java/lang/String", "<init>", "()V"));
1781 bytecode_append(item->code, iconst_1$);
1782 bytecode_append(item->code, iconst_1$);
1783 bytecode_append(item->code, invokespecial$);
1784 bytecode_append_short_int(item->code, method_index);
1786 else
1788 bytecode_append(item->code, new$);
1789 bytecode_append_short_int(item->code, cp_add_class(descriptor+1));
1790 bytecode_append(item->code, dup$);
1791 bytecode_append(item->code, invokespecial$);
1792 bytecode_append_short_int(item->code, cp_add_methodref(descriptor+1, "<init>", "()V"));
1795 bytecode_append(item->code, aastore$);
1797 /* jump back */
1798 it = variable->variable_type->dimensions_list;
1799 c = num-1;
1800 while (it != NULL)
1802 if (it->data != NULL)
1804 short int offset;
1805 bytecode_append(item->code, getstatic$);
1806 bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
1807 bytecode_append(item->code, dup$);
1808 bytecode_append(item->code, sipush$);
1809 bytecode_append_short_int(item->code, c);
1810 bytecode_append(item->code, iaload$);
1811 bytecode_append(item->code, iconst_1$);
1812 bytecode_append(item->code, iadd$);
1813 bytecode_append(item->code, sipush$);
1814 bytecode_append_short_int(item->code, c);
1815 bytecode_append(item->code, swap$);
1816 bytecode_append(item->code, iastore$);
1817 /* the value is increased by one */
1819 bytecode_append(item->code, getstatic$);
1820 bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
1821 bytecode_append(item->code, sipush$);
1822 bytecode_append_short_int(item->code, c);
1823 bytecode_append(item->code, iaload$);
1824 bytecode_append(item->code, sipush$);
1825 bytecode_append_short_int(item->code,
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
1828 bytecode_append(item->code, if_icmple$);
1829 offset = offsets[c] - item->code->bytecode_pos + 1;
1830 bytecode_append_short_int(item->code, offset);
1832 c--;
1833 it = it->next;
1836 mem_free(offsets);
1839 /*OLD: if (!storeIntoField)
1841 switch(variable->variable_index)
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;
1860 } */
1862 mem_free(descriptor);
1864 break;
1865 } // case array_type
1867 case record_type:
1869 char *descriptor;
1870 descriptor = (char*) mem_alloc(1024);
1872 if(descriptor == NULL)
1873 die(1);
1875 get_field_descriptor(variable->variable_type, descriptor);
1877 descriptor[strlen(descriptor) - 1] = '\0';
1879 bytecode_append(item->code, new$);
1880 bytecode_append_short_int(item->code, cp_add_class(descriptor + 1));
1881 bytecode_append(item->code, dup$);
1882 bytecode_append(item->code, invokespecial$);
1883 bytecode_append_short_int(item->code, cp_add_methodref(descriptor + 1, "<init>", "()V"));
1885 mem_free(descriptor);
1887 if (!storeIntoField)
1889 switch(variable->variable_index)
1891 case 0:
1892 bytecode_append(item->code, astore_0$);
1893 break;
1894 case 1:
1895 bytecode_append(item->code, astore_1$);
1896 break;
1897 case 2:
1898 bytecode_append(item->code, astore_2$);
1899 break;
1900 case 3:
1901 bytecode_append(item->code, astore_3$);
1902 break;
1903 default:
1904 bytecode_append(item->code, astore$);
1905 bytecode_append(item->code, (char)variable->variable_index);
1906 break;
1910 break;
1912 case error_type:
1913 break;
1915 default:
1917 die(14);
1922 /* create the bytecode for storing data into the field */
1923 if ((storeIntoField)
1924 && (variable->variable_type->type_class != record_store_type)
1925 && (variable->variable_type->type_class != array_type)) /* array initialization stores the variable */
1927 int field_index;
1928 char descriptor[512];
1929 get_field_descriptor(variable->variable_type, descriptor);
1931 if (name == NULL)
1932 die(23);
1934 lowercase(name);
1935 field_index = cp_add_fieldref(class_name, name, descriptor);
1937 if (is_static)
1938 bytecode_append(item->code, putstatic$);
1939 else
1940 bytecode_append(item->code, putfield$);
1941 bytecode_append_short_int(item->code, (short)field_index);
1946 void transform_break_stmts(bytecode *code, int start_offset, int end_offset, int jump_pos)
1948 int jump_offset;
1949 int pos = start_offset;
1951 while (pos < end_offset)
1953 if (((unsigned char)(code->bytecode[pos]) == (unsigned char)break_stmt$)
1954 && ((pos + 2) < end_offset))
1956 if ((code->bytecode[pos+1] == 0)
1957 && (code->bytecode[pos+2] == 0))
1959 jump_offset = jump_pos - pos;
1960 code->bytecode[pos] = goto$;
1961 code->bytecode[pos+1] = (jump_offset) >> 8;
1962 code->bytecode[pos+2] = jump_offset;
1966 pos ++;
1971 /*
1972 Writes the class file based on the information provided in the
1973 root block.
1974 */
1975 void create_class_file(block *program_block, FILE *fp)
1977 int this_class_index;
1978 int super_class_index;
1979 int i;
1981 /*** Insert the additional data into the constant pool ***/
1982 if (compiling_unit == 0)
1984 this_class_index = cp_add_class("M");
1985 switch (canvasType)
1987 case NORMAL:
1988 super_class_index = cp_add_class("javax/microedition/lcdui/Canvas");
1989 break;
1990 case FULL_NOKIA:
1991 super_class_index = cp_add_class("com/nokia/mid/ui/FullCanvas");
1992 break;
1993 case FULL_MIDP20:
1994 super_class_index = cp_add_class("javax/microedition/lcdui/game/GameCanvas");
1995 break;
1998 else
2000 this_class_index = cp_add_class(string_get_cstr(str_program_name));
2001 super_class_index = cp_add_class("java/lang/Object");
2005 /* Insert the data needed by the methods into the constant pool */
2006 write_method(program_block, NULL);
2007 for(i=0; i<program_block->children_count; i++)
2009 write_method(program_block->children[i], NULL);
2011 write_block_fields(program_block->names, NULL);
2013 if (compiling_unit == 0)
2015 write_constructor(NULL);
2016 write_paint_method(NULL);
2017 write_run_method(NULL);
2018 write_keypressed_method(NULL);
2019 write_keyreleased_method(NULL);
2022 /* add data to constant poll that is later needed */
2023 cp_add_utf8("I");
2024 cp_add_utf8("T");
2025 cp_add_utf8("G");
2026 cp_add_utf8("KC");
2027 cp_add_utf8("KP");
2028 cp_add_utf8("IC");
2029 cp_add_utf8("[I");
2030 cp_add_utf8("Ljavax/microedition/lcdui/Image;");
2031 cp_add_utf8("LM;");
2032 cp_add_class("M");
2033 cp_add_utf8("Ljavax/microedition/lcdui/Graphics;");
2034 cp_add_class("java/lang/Runnable");
2035 cp_add_utf8("StackMap");
2037 /*** Write data to the file ***/
2039 /* write the header */
2040 create_class_file_header(fp);
2042 /* write constant pool */
2043 write_constant_pool(fp);
2045 /* write the access flags, set to ACC_PUBLIC and ACC_SUPER */
2046 write_short_int(fp, 0x0021);
2048 /* write the index to constat pool with this class description */
2049 write_short_int(fp, (short)this_class_index);
2051 /* write the index to constant pool with the super class description */
2052 write_short_int(fp, (short)super_class_index);
2054 if (compiling_unit == 0)
2056 /* we have 1 interface */
2057 write_short_int(fp, 1);
2059 write_short_int(fp, cp_add_class("java/lang/Runnable"));
2061 else
2063 /* unit has 0 interfaces */
2064 write_short_int(fp, 0);
2067 /* write the fields (global variables in pascal) */
2068 if (compiling_unit == 0)
2070 write_short_int(fp, (short)(program_block->next_variable_index + 7));
2072 /* write the RNG field */
2074 /* access flags: ACC_PUBLIC and ACC_STATIC */
2075 write_short_int(fp, 0x0001 | 0x0008);
2077 /* write the name index */
2078 write_short_int(fp, cp_add_utf8("RNG"));
2080 /* write the descriptor index */
2081 write_short_int(fp, cp_add_utf8("Ljava/util/Random;"));
2083 /* write 0 attributes */
2084 write_short_int(fp, 0);
2087 /* write the image (I) field */
2089 /* access flags: ACC_PUBLIC and ACC_STATIC */
2090 write_short_int(fp, 0x0001 | 0x0008);
2092 /* write the name index */
2093 write_short_int(fp, cp_add_utf8("I"));
2095 /* write the descriptor index */
2096 write_short_int(fp, cp_add_utf8("Ljavax/microedition/lcdui/Image;"));
2098 /* write 0 attributes */
2099 write_short_int(fp, 0);
2102 /* write the this (T) field */
2104 /* access flags: ACC_PUBLIC and ACC_STATIC */
2105 write_short_int(fp, 0x0001 | 0x0008);
2107 /* write the name index */
2108 write_short_int(fp, cp_add_utf8("T"));
2110 /* write the descriptor index */
2111 write_short_int(fp, cp_add_utf8("LM;"));
2113 /* write 0 attributes */
2114 write_short_int(fp, 0);
2118 /* write the graphics (G) field */
2120 /* access flags: ACC_PUBLIC and ACC_STATIC */
2121 write_short_int(fp, 0x0001 | 0x0008);
2123 /* write the name index */
2124 write_short_int(fp, cp_add_utf8("G"));
2126 /* write the descriptor index */
2127 write_short_int(fp, cp_add_utf8("Ljavax/microedition/lcdui/Graphics;"));
2129 /* write 0 attributes */
2130 write_short_int(fp, 0);
2133 /* write the key clicked (KC) field */
2135 /* access flags: ACC_PUBLIC and ACC_STATIC */
2136 write_short_int(fp, 0x0001 | 0x0008);
2138 /* write the name index */
2139 write_short_int(fp, cp_add_utf8("KC"));
2141 /* write the descriptor index */
2142 write_short_int(fp, cp_add_utf8("I"));
2144 /* write 0 attributes */
2145 write_short_int(fp, 0);
2148 /* write the key pressed (KP) field */
2150 /* access flags: ACC_PUBLIC and ACC_STATIC */
2151 write_short_int(fp, 0x0001 | 0x0008);
2153 /* write the name index */
2154 write_short_int(fp, cp_add_utf8("KP"));
2156 /* write the descriptor index */
2157 write_short_int(fp, cp_add_utf8("I"));
2159 /* write 0 attributes */
2160 write_short_int(fp, 0);
2163 /* write the INDEX COUNTER (IC) field */
2165 /* access flags: ACC_PUBLIC and ACC_STATIC */
2166 write_short_int(fp, 0x0001 | 0x0008);
2168 /* write the name index */
2169 write_short_int(fp, cp_add_utf8("IC"));
2171 /* write the descriptor index */
2172 write_short_int(fp, cp_add_utf8("[I"));
2174 /* write 0 attributes */
2175 write_short_int(fp, 0);
2178 else
2180 write_short_int(fp, (short)(program_block->next_variable_index));
2183 write_block_fields(program_block->names, fp);
2186 /* write the methods */
2187 if (compiling_unit == 0)
2189 /* write the methods count */
2190 write_short_int(fp, (short)(program_block->children_count + 6));
2192 /* write the constructor */
2193 write_constructor(fp);
2195 /* write the paint method */
2196 write_paint_method(fp);
2198 /* write the run method */
2199 write_run_method(fp);
2201 /* write the key pressed and key released methods */
2202 write_keypressed_method(fp);
2203 write_keyreleased_method(fp);
2205 else
2207 write_short_int(fp, (short)(program_block->children_count + 1));
2210 /* write all other methods */
2211 for(i=0; i<program_block->children_count; i++)
2213 write_method(program_block->children[i], fp);
2216 /* write the main (R) method - <clinit> for interfaces */
2217 write_method(program_block, fp);
2220 /* we have no attributes */
2221 write_short_int(fp, 0);
2224 // TODO: deallocate constant pool
2228 /*
2229 Writes the method to the file, if fp is NULL only add needeed
2230 data to the constant pool
2231 */
2232 void write_method(block *current_block, FILE *fp)
2234 identifier *block_identifier = NULL;
2235 stack_map_list *map_list;
2236 int code_attribute_length, code_attribute_length_offset;
2237 int stack_map_attribute_offset;
2238 int stack_map_size;
2239 int stack_map_entries;
2240 int tmp_offset;
2242 /* write access flags, ACC_PUBLIC and ACC_STATIC */
2243 write_short_int(fp, 0x0001 | 0x0008);
2245 if(current_block->parent_block == root_block)
2247 /*** it is the main block ***/
2249 /* write name index */
2250 if (compiling_unit == 0)
2251 write_short_int(fp, cp_add_utf8("R"));
2252 else
2253 write_short_int(fp, cp_add_utf8("<clinit>"));
2255 /* write the descriptor */
2256 write_short_int(fp, cp_add_utf8("()V"));
2258 else
2260 char *descriptor;
2261 int pos = 1;
2262 type_list *it;
2264 descriptor = (char*) mem_alloc(5*1024);
2266 if (descriptor == NULL)
2267 die(1);
2269 descriptor[0] = '(';
2271 /*** procedure or function ***/
2273 /* write name index */
2274 lowercase(current_block->block_name->cstr);
2275 write_short_int(fp, cp_add_utf8(current_block->block_name->cstr));
2277 /* write the descriptor */
2278 block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
2280 if ((block_identifier == NULL)
2281 || (block_identifier->identifier_class != function_name
2282 && block_identifier->identifier_class != procedure_name))
2284 mem_free(descriptor);
2285 die(17);
2288 it = block_identifier->parameters;
2290 while(it != NULL)
2292 if (it->data == NULL)
2293 break;
2295 get_field_descriptor(it->data, descriptor + pos);
2296 pos = strlen(descriptor);
2297 it = it->next;
2300 descriptor[pos] = ')';
2301 pos ++;
2302 descriptor[pos] = '\0';
2304 if (block_identifier->identifier_class == procedure_name)
2305 strcat(descriptor, "V");
2306 else
2307 get_field_descriptor(block_identifier->return_type, descriptor + pos);
2309 write_short_int(fp, cp_add_utf8(descriptor));
2311 mem_free(descriptor);
2314 //PREVERIFY map_list = preverify_bytecode(current_block->code, block_identifier);
2315 map_list = NULL;
2318 /* write the code */
2319 write_short_int(fp, 2); /* attribute count */
2321 write_short_int(fp, cp_add_utf8("Code"));
2322 if (fp != NULL)
2323 code_attribute_length_offset = ftell(fp);
2324 write_long_int(fp, current_block->code->bytecode_pos + 12); /* update the size later when we know it */
2325 code_attribute_length = current_block->code->bytecode_pos + 12;
2327 write_short_int(fp, 32); /* max stack */
2329 if (current_block->parent_block == root_block)
2330 write_short_int(fp, 0); /* max locals for program block */
2331 else
2332 write_short_int(fp, current_block->next_variable_index + 2); /* max locals */
2334 write_long_int(fp, current_block->code->bytecode_pos); /* code length */
2336 if(fp != NULL)
2337 fwrite(current_block->code->bytecode, current_block->code->bytecode_pos, 1, fp);
2339 write_short_int(fp, 0);
2340 if (map_list != NULL)
2342 write_short_int(fp, 1); /* The Code has one attribute (The StackMap attribute) */
2344 write_short_int(fp, cp_add_utf8("StackMap"));
2345 if (fp != NULL)
2346 stack_map_attribute_offset = ftell(fp);
2347 write_long_int(fp, 0); /* attribute length */
2348 write_short_int(fp, 0); /* number of entries; these two fields will be filled in later */
2350 stack_map_size = 2;
2351 stack_map_entries = 0;
2353 do
2355 int i;
2356 stack_map *map = stack_map_list_get(&map_list);
2358 if (map != NULL)
2359 write_short_int(fp, (short)(map->bytecode_offset));
2360 stack_map_size += 2;
2362 /* write the locals */
2363 if (current_block->parent_block == root_block)
2365 write_short_int(fp, 0);
2366 stack_map_size += 2;
2368 else
2370 identifier *block_identifier;
2372 /* write the StackMap for locals */
2373 block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
2375 write_short_int(fp, (short)current_block->next_variable_index);
2376 stack_map_size += 2;
2378 write_locals_stackmap(fp, block_identifier, &stack_map_size);
2381 if (map == NULL)
2382 break;
2384 /* write the stack items */
2385 write_short_int(fp, (short)map->number_of_items);
2386 stack_map_size += 2;
2387 for(i=0; i<map->number_of_items; i++)
2389 if (fp != NULL)
2391 fwrite(&(map->stack[i]->item_type), 1, 1, fp);
2394 if ((map->stack[i]->item_type == ITEM_Object)
2395 || (map->stack[i]->item_type == ITEM_NewObject))
2397 write_short_int(fp, map->stack[i]->additional_data);
2398 stack_map_size += 2;
2401 stack_map_size ++;
2404 stack_map_destroy(map);
2406 stack_map_entries ++;
2408 } while (map_list != NULL);
2410 /* write the stack map size and the number of entries and
2411 the code attribute length */
2412 if (fp != NULL)
2414 tmp_offset = ftell(fp);
2415 fseek(fp, stack_map_attribute_offset, SEEK_SET);
2416 write_long_int(fp, stack_map_size); /* attribute length */
2417 write_short_int(fp, (short)stack_map_entries); /* number of entries */
2419 fseek(fp, code_attribute_length_offset, SEEK_SET);
2420 write_long_int(fp, code_attribute_length + 6 + stack_map_size);
2422 fseek(fp, tmp_offset, SEEK_SET);
2425 else
2427 write_short_int(fp, 0);
2430 /* write the Exceptions attribute */
2431 write_short_int(fp, cp_add_utf8("Exceptions"));
2433 write_long_int(fp, 4);
2435 write_short_int(fp, 1);
2436 write_short_int(fp, cp_add_class("java/lang/Exception"));
2441 /*
2442 Creates the code for the following method:
2444 public void paint(Graphics g)
2446 g.drawImage(IMG, 0, 0, Graphics.TOP|Graphics.LEFT);
2448 */
2449 void write_paint_method(FILE *fp)
2451 bytecode *code = bytecode_create();
2452 if (code == NULL)
2453 die(1);
2455 /* create the code */
2457 /* PUSH param_1 */
2458 bytecode_append(code, aload_1$);
2460 /* PUSH (I) */
2461 bytecode_append(code, getstatic$);
2462 bytecode_append_short_int(code, cp_add_fieldref("M", "I", "Ljavax/microedition/lcdui/Image;"));
2464 /* PUSH 0; PUSH 0*/
2465 bytecode_append(code, iconst_0$);
2466 bytecode_append(code, iconst_0$);
2468 /* PUSH Graphics.LEFT|Graphics.TOP */
2469 bytecode_append(code, bipush$);
2470 bytecode_append(code, 20);
2472 /* invoke drawImage(Image, int, int, int) */
2473 bytecode_append(code, invokevirtual$);
2474 bytecode_append_short_int(code,
2475 cp_add_methodref("javax/microedition/lcdui/Graphics", "drawImage", "(Ljavax/microedition/lcdui/Image;III)V"));
2477 bytecode_append(code, return$);
2479 /* write the method headers */
2481 /* write access flags, ACC_PUBLIC */
2482 write_short_int(fp, 0x0001);
2484 /* write method name */
2485 write_short_int(fp, cp_add_utf8("paint"));
2487 /* write method descriptor */
2488 write_short_int(fp, cp_add_utf8("(Ljavax/microedition/lcdui/Graphics;)V"));
2490 /* write 1 attribute */
2491 write_short_int(fp, 1);
2493 /* write the Code attribute */
2494 write_short_int(fp, cp_add_utf8("Code"));
2495 write_long_int(fp, code->bytecode_pos + 12);
2497 /* write the max stack */
2498 write_short_int(fp, 10);
2500 /* max locals for program block */
2501 write_short_int(fp, 2);
2504 /* code length */
2505 write_long_int(fp, code->bytecode_pos);
2507 /* write the code itself */
2508 if (fp != NULL)
2509 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2511 bytecode_destroy(code);
2513 write_short_int(fp, 0);
2514 write_short_int(fp, 0);
2517 /*
2518 Creates the code for the following method:
2520 public void run()
2522 R();
2524 */
2525 void write_run_method(FILE *fp)
2527 char tag;
2529 bytecode *code = bytecode_create();
2530 if (code == NULL)
2531 die(1);
2533 /* create the code */
2534 bytecode_append(code, invokestatic$);
2535 bytecode_append_short_int(code, cp_add_methodref("M", "R", "()V"));
2537 bytecode_append(code, goto$);
2538 bytecode_append_short_int(code, 4);
2540 bytecode_append(code, pop$); /* the exception handler */
2542 bytecode_append(code, return$);
2544 /* write the method headers */
2546 /* write access flags, ACC_PUBLIC */
2547 write_short_int(fp, 0x0001);
2549 /* write method name */
2550 write_short_int(fp, cp_add_utf8("run"));
2552 /* write method descriptor */
2553 write_short_int(fp, cp_add_utf8("()V"));
2555 /* write 1 attribute */
2556 write_short_int(fp, 1);
2558 /* write the Code attribute */
2559 write_short_int(fp, cp_add_utf8("Code"));
2560 write_long_int(fp, code->bytecode_pos + 20 + 38); /* 38 = stackmap size */
2562 /* write the max stack */
2563 write_short_int(fp, 2);
2565 /* max locals for program block */
2566 write_short_int(fp, 1);
2568 /* code length */
2569 write_long_int(fp, code->bytecode_pos);
2571 /* write the code itself */
2572 if (fp != NULL)
2573 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2575 bytecode_destroy(code);
2577 /* write exception table length*/
2578 write_short_int(fp, 1);
2580 /* write the exception table */
2581 write_short_int(fp, 0);
2582 write_short_int(fp, 3);
2583 write_short_int(fp, 6);
2584 write_short_int(fp, cp_add_class("java/lang/Exception"));
2587 /* StackMap attribute */
2588 write_short_int(fp, 1);
2590 write_short_int(fp, cp_add_utf8("StackMap"));
2591 write_long_int(fp, 32);
2593 /* 2 frames*/
2594 write_short_int(fp, 3);
2596 /* write the frame 0 */
2597 write_short_int(fp, 0);
2599 /* write the locals */
2600 write_short_int(fp, 1);
2601 tag = 7;
2602 if (fp != NULL)
2603 fwrite(&tag, 1, 1, fp);
2604 write_short_int(fp, cp_add_class("M"));
2607 /* 0 stack entries */
2608 write_short_int(fp, 0);
2610 /* write the frame 1 */
2611 write_short_int(fp, 6);
2613 /* write the locals*/
2614 write_short_int(fp, 1);
2615 tag = 7;
2616 if (fp != NULL)
2617 fwrite(&tag, 1, 1, fp);
2618 write_short_int(fp, cp_add_class("M"));
2620 /* 1 stack entry */
2621 write_short_int(fp, 1);
2622 tag = 7;
2623 if (fp != NULL)
2624 fwrite(&tag, 1, 1, fp);
2625 write_short_int(fp, cp_add_class("java/lang/Exception"));
2628 /* write the frame 2 */
2629 write_short_int(fp, 7);
2631 /* write the locals */
2632 write_short_int(fp, 1);
2633 tag = 7;
2634 if (fp != NULL)
2635 fwrite(&tag, 1, 1, fp);
2636 write_short_int(fp, cp_add_class("M"));
2638 /* 0 stack entries */
2639 write_short_int(fp, 0);
2644 /*
2645 Creates the code for the following methods:
2647 public void keyPressed(int keyCode)
2649 KC = keyCode;
2650 KP = keyCode;
2653 public void keyReleased(int keyCode)
2655 KP = 0;
2657 */
2658 void write_keypressed_method(FILE *fp)
2660 bytecode *code = bytecode_create();
2661 if (code == NULL)
2662 die(1);
2664 /* create the code */
2665 bytecode_append(code, iload_1$);
2666 bytecode_append(code, dup$);
2667 bytecode_append(code, putstatic$);
2668 bytecode_append_short_int(code, cp_add_fieldref("M", "KC", "I"));
2669 bytecode_append(code, putstatic$);
2670 bytecode_append_short_int(code, cp_add_fieldref("M", "KP", "I"));
2672 bytecode_append(code, return$);
2674 /* write the method headers */
2676 /* write access flags, ACC_PUBLIC */
2677 write_short_int(fp, 0x0001);
2679 /* write method name */
2680 write_short_int(fp, cp_add_utf8("keyPressed"));
2682 /* write method descriptor */
2683 write_short_int(fp, cp_add_utf8("(I)V"));
2685 /* write 1 attribute */
2686 write_short_int(fp, 1);
2688 /* write the Code attribute */
2689 write_short_int(fp, cp_add_utf8("Code"));
2690 write_long_int(fp, code->bytecode_pos + 12);
2692 /* write the max stack */
2693 write_short_int(fp, 2);
2695 /* max locals for program block */
2696 write_short_int(fp, 2);
2699 /* code length */
2700 write_long_int(fp, code->bytecode_pos);
2702 /* write the code itself */
2703 if (fp != NULL)
2704 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2706 bytecode_destroy(code);
2708 write_short_int(fp, 0);
2709 write_short_int(fp, 0);
2711 void write_keyreleased_method(FILE *fp)
2713 bytecode *code = bytecode_create();
2714 if (code == NULL)
2715 die(1);
2717 /* create the code */
2718 bytecode_append(code, iconst_0$);
2719 bytecode_append(code, putstatic$);
2720 bytecode_append_short_int(code, cp_add_fieldref("M", "KP", "I"));
2722 bytecode_append(code, return$);
2724 /* write the method headers */
2726 /* write access flags, ACC_PUBLIC */
2727 write_short_int(fp, 0x0001);
2729 /* write method name */
2730 write_short_int(fp, cp_add_utf8("keyReleased"));
2732 /* write method descriptor */
2733 write_short_int(fp, cp_add_utf8("(I)V"));
2735 /* write 1 attribute */
2736 write_short_int(fp, 1);
2738 /* write the Code attribute */
2739 write_short_int(fp, cp_add_utf8("Code"));
2740 write_long_int(fp, code->bytecode_pos + 12);
2742 /* write the max stack */
2743 write_short_int(fp, 2);
2745 /* max locals for program block */
2746 write_short_int(fp, 2);
2749 /* code length */
2750 write_long_int(fp, code->bytecode_pos);
2752 /* write the code itself */
2753 if (fp != NULL)
2754 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2756 bytecode_destroy(code);
2758 write_short_int(fp, 0);
2759 write_short_int(fp, 0);
2763 /*
2764 Creates the code for the class constructor.
2765 */
2766 void write_constructor(FILE *fp)
2768 bytecode *code = bytecode_create();
2769 if (code == NULL)
2770 die(1);
2772 /* create the code */
2773 switch (canvasType)
2775 case NORMAL:
2776 bytecode_append(code, aload_0$);
2777 bytecode_append(code, invokespecial$);
2778 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "<init>", "()V"));
2779 break;
2780 case FULL_NOKIA:
2781 bytecode_append(code, aload_0$);
2782 bytecode_append(code, invokespecial$);
2783 bytecode_append_short_int(code, cp_add_methodref("com/nokia/mid/ui/FullCanvas", "<init>", "()V"));
2784 break;
2785 case FULL_MIDP20:
2786 bytecode_append(code, aload_0$);
2787 bytecode_append(code, iconst_0$);
2788 bytecode_append(code, invokespecial$);
2789 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/game/GameCanvas", "<init>", "(Z)V"));
2791 bytecode_append(code, aload_0$);
2792 bytecode_append(code, iconst_1$);
2793 bytecode_append(code, invokevirtual$);
2794 bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "setFullScreenMode", "(Z)V"));
2795 break;
2798 bytecode_append(code, return$);
2800 /* write the method headers */
2802 /* write access flags, ACC_PUBLIC */
2803 write_short_int(fp, 0x0001);
2805 /* write method name */
2806 write_short_int(fp, cp_add_utf8("<init>"));
2808 /* write method descriptor */
2809 write_short_int(fp, cp_add_utf8("()V"));
2811 /* write 1 attribute */
2812 write_short_int(fp, 1);
2814 /* write the Code attribute */
2815 write_short_int(fp, cp_add_utf8("Code"));
2816 write_long_int(fp, code->bytecode_pos + 12);
2818 /* write the max stack */
2819 write_short_int(fp, 10);
2821 /* max locals for program block */
2822 write_short_int(fp, 2);
2825 /* code length */
2826 write_long_int(fp, code->bytecode_pos);
2828 /* write the code itself */
2829 if (fp != NULL)
2830 fwrite(code->bytecode, 1, code->bytecode_pos, fp);
2832 bytecode_destroy(code);
2834 write_short_int(fp, 0);
2835 write_short_int(fp, 0);
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 */
2845 void write_block_fields(name_table *names, FILE *fp)
2847 char descriptor[128];
2849 if ((names->descriptor != NULL)
2850 && (names->descriptor->identifier_class == variable_name))
2852 /* access flags: ACC_PUBLIC and ACC_STATIC */
2853 write_short_int(fp, 0x0001 | 0x0008);
2855 /* write the name index */
2856 lowercase(names->name->cstr);
2857 write_short_int(fp, cp_add_utf8(names->name->cstr));
2859 /* write the descriptor index */
2860 get_field_descriptor(names->descriptor->variable_type, descriptor);
2861 write_short_int(fp, cp_add_utf8(descriptor));
2863 /* write 0 attributes */
2864 write_short_int(fp, 0);
2867 /* write the left child */
2868 if ((names->descriptor != NULL)
2869 && (names->left_child != NULL))
2871 write_block_fields(names->left_child, fp);
2874 /* write the right child */
2875 if ((names->descriptor != NULL)
2876 && (names->right_child != NULL))
2878 write_block_fields(names->right_child, fp);
2883 void write_locals_stackmap(FILE *fp, identifier *block_identifier, int *stack_map_size)
2885 type_list *it = block_identifier->parameters;
2886 write_stackmap(fp, it, stack_map_size);
2888 /* for functions, add the return value */
2889 if (block_identifier->identifier_class == function_name)
2891 it = type_list_create();
2892 type_list_append(it, block_identifier->return_type);
2893 write_stackmap(fp, it, stack_map_size);
2894 type_list_destroy(it);
2897 it = block_identifier->variables;
2898 write_stackmap(fp, it, stack_map_size);
2901 void write_stackmap(FILE *fp, type_list *it, int *stack_map_size)
2904 while (it != NULL)
2906 char c;
2908 if (it->data != NULL)
2910 switch(it->data->type_class)
2912 case integer_type:
2913 case char_type:
2914 case boolean_type:
2915 c = 1;
2916 if (fp != NULL)
2917 fwrite(&c, 1, 1, fp);
2918 (*stack_map_size) ++;
2919 break;
2921 case real_type:
2923 if (mathType == 1)
2925 c = 1;
2926 if (fp != NULL)
2927 fwrite(&c, 1, 1, fp);
2928 (*stack_map_size) ++;
2930 else
2932 c = 7;
2933 if (fp != NULL)
2934 fwrite(&c, 1, 1, fp);
2935 write_short_int(fp, cp_add_class("Real"));
2936 (*stack_map_size) += 3;
2939 break;
2941 case string_type:
2942 c = 7;
2943 if (fp != NULL)
2944 fwrite(&c, 1, 1, fp);
2945 write_short_int(fp, cp_add_class("java/lang/String"));
2946 (*stack_map_size) += 3;
2947 break;
2949 case image_type:
2950 c = 7;
2951 if (fp != NULL)
2952 fwrite(&c, 1, 1, fp);
2953 write_short_int(fp, cp_add_class("javax/microedition/lcdui/Image"));
2954 (*stack_map_size) += 3;
2955 break;
2957 case command_type:
2958 c = 7;
2959 if (fp != NULL)
2960 fwrite(&c, 1, 1, fp);
2961 write_short_int(fp, cp_add_class("javax/microedition/lcdui/Command"));
2962 (*stack_map_size) += 3;
2963 break;
2966 case stream_type:
2967 c = 7;
2968 if (fp != NULL)
2969 fwrite(&c, 1, 1, fp);
2970 write_short_int(fp, cp_add_class("java/io/InputStream"));
2971 (*stack_map_size) += 3;
2972 break;
2974 case record_store_type:
2975 c = 7;
2976 if (fp != NULL)
2977 fwrite(&c, 1, 1, fp);
2978 write_short_int(fp, cp_add_class("javax/microedition/rms/RecordStore"));
2979 (*stack_map_size) += 3;
2980 break;
2982 case http_type:
2983 c = 7;
2984 if (fp != NULL)
2985 fwrite(&c, 1, 1, fp);
2986 write_short_int(fp, cp_add_class("H"));
2987 (*stack_map_size) += 3;
2988 break;
2990 case alert_type:
2991 c = 7;
2992 if (fp != NULL)
2993 fwrite(&c, 1, 1, fp);
2994 write_short_int(fp, cp_add_class("Ljavax/microedition/lcdui/AlertType;"));
2995 (*stack_map_size) += 3;
2996 break;
2998 case array_type:
3000 char descriptor[512];
3001 char element_type[128];
3002 int i, len;
3004 get_field_descriptor(it->data->element_type, element_type);
3006 len = type_list_length(it->data->dimensions_list);
3007 for(i=0; i < len; i++)
3009 descriptor[i] = '[';
3012 descriptor[len] = '\0';
3014 sprintf(descriptor + len, "%s", element_type);
3016 c = 7;
3017 if (fp != NULL)
3018 fwrite(&c, 1, 1, fp);
3019 write_short_int(fp, cp_add_class(descriptor));
3020 (*stack_map_size) += 3;
3022 break;
3024 case record_type:
3026 char descriptor[16];
3027 c = 7;
3028 if (fp != NULL)
3029 fwrite(&c, 1, 1, fp);
3030 sprintf(descriptor, "R_%d", it->data->unique_record_ID);
3031 write_short_int(fp, cp_add_class(descriptor));
3032 (*stack_map_size) += 3;
3034 break;
3038 it = it->next;