X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fbackends%2Fjvm%2Fgenerator-jvm.c;h=99a4673199d8e432ddb0c98c4e0f397426625cff;hb=3c5fc198fb0f72bd8ec70aef8f2b4987bb702f79;hp=7c426d546c7bdf190f3594e7b5bda31293f89543;hpb=f89bbec89e4dd5c7cd15954f0c02370fb9127518;p=dsw-obn.git diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index 7c426d5..99a4673 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -71,6 +71,7 @@ jvm_create_class(char * full_name) memset(class, 0, sizeof *class); char * fname = new_string("%s.j", full_name); + class -> full_name = new_string(full_name); class -> fp = fopen(fname, "w"); assert(class -> fp); @@ -84,13 +85,6 @@ jvm_destroy_class(struct gen_class * class) fclose(class -> fp); } -static void -jvm_generate_field(struct gen_class * class, char * access, char * name, char * desc) -{ - assert(class -> p == NULL); - fprintf(class -> fp, ".field %s %s %s\n\n", access, name, desc); -} - static void jvm_stack_push(gen_proc_t * p, unsigned size) { @@ -211,6 +205,106 @@ jvm_generate_label(gen_proc_t * p, int label_id) jvm_generate(p, 0, 0, "L%i:", label_id); } +static void +jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type) +{ + char * cname; + + switch(type -> class) + { + case OBERON_TYPE_INTEGER: + case OBERON_TYPE_BOOLEAN: + case OBERON_TYPE_PROCEDURE: + case OBERON_TYPE_REAL: + case OBERON_TYPE_POINTER: + /* ничего не надо делать при статической инициализации */ + break; + case OBERON_TYPE_RECORD: + cname = jvm_get_class_full_name(type); + jvm_generate(p, 0, 1, "new %s", cname); + jvm_generate(p, 1, 2, "dup"); + jvm_generate(p, 1, 0, "invokespecial %s/()V", cname); + break; + case OBERON_TYPE_ARRAY: + gen_error("jvm_generate_new_static: TODO array"); + break; + default: + gen_error("jvm_generate_new_static: unk type class %i", type -> class); + break; + } +} + +static void +jvm_generate_store(gen_proc_t * p, oberon_type_t * src_type, gen_var_t * dst) +{ + char prefix; + int cell_size; + + cell_size = jvm_cell_size_for_type(src_type); + + switch(dst -> storage) + { + case JVM_STORAGE_REGISTER: + prefix = jvm_get_prefix(src_type); + jvm_generate(p, cell_size, 0, "%cstore %i", prefix, dst -> reg); + break; + case JVM_STORAGE_STATIC: + jvm_generate(p, cell_size, 0, "putstatic %s %s", dst -> full_name, dst -> desc); + break; + case JVM_STORAGE_FIELD: + jvm_generate(p, 1 + cell_size, 0, "putfield %s %s", dst -> full_name, dst -> desc); + break; + default: + gen_error("jvm_generate_store: unknow storage type %i", dst -> storage); + break; + } +} + +static gen_var_t * +oberon_generator_new_var() +{ + gen_var_t * v = GC_MALLOC(sizeof *v); + memset(v, 0, sizeof *v); + return v; +} + +static void +jvm_generate_and_init_global_var(gen_var_t * v, struct gen_class * class, char * access, char * name, char * desc) +{ + assert(class -> p == NULL); + fprintf(class -> fp, ".field %s static %s %s\n\n", access, name, desc); + + v -> storage = JVM_STORAGE_STATIC; + v -> full_name = new_string("%s/%s", class -> full_name, name); + v -> desc = new_string(desc); +} + +static void +jvm_generate_and_init_field(gen_var_t * v, struct gen_class * class, char * access, char * name, char * desc) +{ + assert(class -> p == NULL); + fprintf(class -> fp, ".field %s %s %s\n\n", access, name, desc); + + v -> storage = JVM_STORAGE_FIELD; + v -> full_name = new_string("%s/%s", class -> full_name, name); + v -> desc = new_string(desc); +} + +static void +jvm_generate_and_init_local_var(gen_var_t * v, gen_proc_t * p, bool wide) +{ + v -> storage = JVM_STORAGE_REGISTER; + v -> reg = jvm_alloc_register_untyped(p -> rf, wide); +} + +static void +jvm_generate_and_init_named_local_var(gen_var_t * v, gen_proc_t * p, bool wide, char * name, char * desc) +{ + jvm_generate_and_init_local_var(v, p, wide); + v -> desc = new_string(desc); + jvm_generate(p, 0, 0, ".var %i is %s %s from start to end", v -> reg, name, desc); +} + // ========================================== // ========================================== // ========================================== @@ -311,35 +405,6 @@ oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type) } } -static void -jvm_generate_object(struct gen_class * class, oberon_object_t * x) -{ - char * name; - char * desc; - - name = x -> name; - desc = jvm_get_descriptor(x -> type); - switch(x -> class) - { - case OBERON_CLASS_VAR: - if(x -> local == 0) - { - jvm_generate_field(class, "public static", name, desc); - } - else - { - gen_error("jvm_generate_object: local variable as class field? wat"); - } - break; - case OBERON_CLASS_FIELD: - jvm_generate_field(class, "public", name, desc); - break; - default: - gen_error("jvm_generate_object: unk class %i", x -> class); - break; - } -} - void oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * rec) { @@ -350,15 +415,36 @@ oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * rec) oberon_object_t * field = rec -> decl; for(int i = 0; i < num; i++) { - jvm_generate_object(class, field); + gen_var_t * v = field -> gen_var; + char * name = field -> name; + char * desc = jvm_get_descriptor(field -> type); + jvm_generate_and_init_field(v, class, "public", name, desc); field = field -> next; } - fprintf(class -> fp, ".method public ()V\n"); - fprintf(class -> fp, " aload_0\n"); - fprintf(class -> fp, " invokespecial java/lang/Object/()V\n"); - fprintf(class -> fp, " return\n"); - fprintf(class -> fp, ".end method\n"); + gen_proc_t * p = jvm_create_proc(class); + + jvm_generate_function_header(p, "public", "", "()V"); + jvm_alloc_register_untyped(p -> rf, false); + jvm_generate(p, 0, 1, "aload_0"); + jvm_generate(p, 1, 0, "invokespecial java/lang/Object/()V"); + + num = rec -> num_decl; + field = rec -> decl; + for(int i = 0; i < num; i++) + { + if(field -> type -> class == OBERON_TYPE_RECORD + || field -> type -> class == OBERON_TYPE_ARRAY) + { + jvm_generate(p, 0, 1, "aload_0"); + jvm_generate_new_static(p, field -> type); + jvm_generate_store(p, field -> type, field -> gen_var); + } + field = field -> next; + } + + jvm_generate(p, 0, 0, "return"); + jvm_generate_function_end(p); jvm_destroy_class(class); } @@ -366,8 +452,7 @@ oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * rec) void oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) { - gen_var_t * v = GC_MALLOC(sizeof *v); - memset(v, 0, sizeof *v); + gen_var_t * v = oberon_generator_new_var(); var -> gen_var = v; gen_module_t * m; @@ -376,16 +461,28 @@ oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) struct gen_class * class; class = m -> class; + char * desc; switch(var -> class) { case OBERON_CLASS_VAR_PARAM: gen_error("generator: VAR-parameters not implemented"); break; case OBERON_CLASS_PARAM: + /* Заполняется при генерации функции */ + /* смотри jvm_init_local_object() */ + break; case OBERON_CLASS_FIELD: + /* Заполняются при инициализации структуры */ + /* смотри oberon_generator_init_record() */ break; case OBERON_CLASS_VAR: - jvm_generate_object(class, var); + /* Локальные заполняются при генерации функции */ + /* смотри jvm_init_local_object() */ + if(var -> local == 0) + { + desc = jvm_get_descriptor(var -> type); + jvm_generate_and_init_global_var(v, class, "public", var -> name, desc); + } break; default: gen_error("oberon_generator_init_var: unk var class %i", var -> class); @@ -459,11 +556,13 @@ static void jvm_init_local_object(gen_proc_t * p, oberon_object_t * x) { gen_var_t * v; + bool wide; char * desc; struct gen_class * class; v = x -> gen_var; class = p -> class; + wide = jvm_is_wide_type(x -> type); desc = jvm_get_descriptor(x -> type); // Убеждаемся что сейчас находимся в функции @@ -474,8 +573,7 @@ jvm_init_local_object(gen_proc_t * p, oberon_object_t * x) { case OBERON_CLASS_VAR: case OBERON_CLASS_PARAM: - v -> reg = jvm_alloc_register(p -> rf, x -> type); - fprintf(class -> fp, ".var %i is %s %s from start to end\n", v -> reg, x -> name, desc); + jvm_generate_and_init_named_local_var(v, p, wide, x -> name, desc); break; default: gen_error("jvm_init_local_object: wat"); @@ -594,41 +692,17 @@ jvm_push_var(gen_proc_t * p, oberon_object_t * var) } static void -jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type, int num, oberon_expr_t * arg) +jvm_generate_expr_new_static(gen_proc_t * p, oberon_type_t * type, int num, oberon_expr_t * arg) { - //char * desc; - char * cname; - //desc = jvm_get_descriptor(type); - cname = jvm_get_class_full_name(type); - - switch(type -> class) - { - case OBERON_TYPE_INTEGER: - case OBERON_TYPE_BOOLEAN: - case OBERON_TYPE_PROCEDURE: - case OBERON_TYPE_REAL: - case OBERON_TYPE_POINTER: - /* ничего не надо делать при статической инициализации */ - break; - case OBERON_TYPE_RECORD: - jvm_generate(p, 0, 1, "new %s", cname); - jvm_generate(p, 1, 2, "dup"); - jvm_generate(p, 1, 0, "invokespecial %s/()V", cname); - break; - case OBERON_TYPE_ARRAY: - gen_error("jvm_generate_new_static: TODO array"); - break; - default: - gen_error("jvm_generate_new_static: unk type class %i", type -> class); - break; - } + assert(num == 0); + jvm_generate_new_static(p, type); } static void -jvm_generate_new_pointer(gen_proc_t * p, oberon_type_t * type, int num, oberon_expr_t * arg) +jvm_generate_expr_new_pointer(gen_proc_t * p, oberon_type_t * type, int num, oberon_expr_t * arg) { assert(type -> class == OBERON_TYPE_POINTER); - jvm_generate_new_static(p, type -> base, num, arg); + jvm_generate_expr_new_static(p, type -> base, num, arg); } static void @@ -665,7 +739,7 @@ push_item(gen_proc_t * p, oberon_item_t * item) jvm_generate(p, 0, 1, "aconst_null"); break; case MODE_NEW: - jvm_generate_new_pointer(p, item -> result, item -> num_args, item -> args); + jvm_generate_expr_new_pointer(p, item -> result, item -> num_args, item -> args); break; case MODE_REAL: jvm_generate_push_float(p, item -> real, item -> result -> size); @@ -902,6 +976,33 @@ push_expr(gen_proc_t * p, oberon_expr_t * expr) } } +static void +store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src) +{ + assert(dst -> is_item); + oberon_item_t * item = (oberon_item_t *) dst; + + switch(item -> mode) + { + case MODE_VAR: + push_expr(p, src); + jvm_generate_store(p, src -> result, item -> var -> gen_var); + break; + case MODE_INDEX: + gen_error("store_expr: TODO index"); + break; + case MODE_FIELD: + push_item(p, item -> parent); + push_expr(p, src); + jvm_generate_store(p, src -> result, item -> var -> gen_var); + break; + default: + gen_error("store_expr: unk mode %i", item -> mode); + break; + } +} + +/* static void store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src) { @@ -945,6 +1046,7 @@ store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src) break; } } +*/ void oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)