X-Git-Url: http://deadsoftware.ru/gitweb?p=dsw-obn.git;a=blobdiff_plain;f=src%2Fbackends%2Fjvm%2Fgenerator-jvm-abi.c;h=2889ae3c718437b3220ae308ba0e446a9fec55bc;hp=0db2cc88b29bf3454d99b390ea5ff4bc151e0804;hb=023ef0d8349acdfe751bba1b50749361682f72ff;hpb=1ef429eea9ba6825395446aac0b5980454ac0383 diff --git a/src/backends/jvm/generator-jvm-abi.c b/src/backends/jvm/generator-jvm-abi.c index 0db2cc8..2889ae3 100644 --- a/src/backends/jvm/generator-jvm-abi.c +++ b/src/backends/jvm/generator-jvm-abi.c @@ -15,20 +15,6 @@ #include "generator-jvm-asm.h" #include "generator-jvm-basic.h" -/* - * --- Каждый модуль является объектом. - * Импортируемые модули представляются полями. - * Каждая глобальная переменная представляется не статическим полем. - * Каждая процедура представляется не статическим метеодом. - * Процедура инициализации модуля имеет название BEGIN. - * Процедура финализации модуля имеет название END. - * Это позволит сделать динамическую загрузку и выгрузку. - * +++ всем переменным и полям в дескриптор добавляется "[" - * Это позволит делать ссылки на переменные в VAR-параметрах. - * --- Каждая процедура снабжается параметром-фреймом. - * Это позволит реализовать локальные процедуры и средства рефлекции над стеком. - */ - void jvm_generate_ldst_prepare(gen_proc_t * p, gen_var_t * v) { @@ -60,18 +46,18 @@ jvm_generate_ldst_prepare(gen_proc_t * p, gen_var_t * v) break; case JVM_STORAGE_FRAME: case JVM_STORAGE_FRAME_PARAM: - jvm_generate_load(p, p -> frame_v); + jvm_generate(p, 0, 1, "aload %i", p -> reg_frame[v -> level]); break; case JVM_STORAGE_FRAME_VAR: case JVM_STORAGE_FRAME_PARAM_VAR: - jvm_generate_load(p, p -> frame_v); + jvm_generate(p, 0, 1, "aload %i", p -> reg_frame[v -> level]); jvm_generate(p, 1, 1, "getfield %s [%s", full_name, desc); jvm_generate(p, 0, 1, "iconst_0"); break; case JVM_STORAGE_FRAME_PARAM_VARPTR: - jvm_generate_load(p, p -> frame_v); + jvm_generate(p, 0, 1, "aload %i", p -> reg_frame[v -> level]); jvm_generate(p, 1, 1, "getfield %s [%s", full_name, desc); - jvm_generate_load(p, p -> frame_v); + jvm_generate(p, 0, 1, "aload %i", p -> reg_frame[v -> level]); jvm_generate(p, 1, 1, "getfield %s$offset I", full_name); break; default: @@ -83,6 +69,7 @@ void jvm_generate_load(gen_proc_t * p, gen_var_t * src) { char prefix = src -> type -> prefix; + char postfix = src -> type -> postfix; int cell_size = src -> type -> cell_size; char * full_name = src -> full_name; char * desc = src -> type -> desc; @@ -108,7 +95,7 @@ jvm_generate_load(gen_proc_t * p, gen_var_t * src) case JVM_STORAGE_FRAME_PARAM_VAR: case JVM_STORAGE_FRAME_PARAM_VARPTR: jvm_generate_ldst_prepare(p, src); - jvm_generate(p, 1 + 1, cell_size, "%caload", prefix); + jvm_generate(p, 1 + 1, cell_size, "%caload", postfix); break; case JVM_STORAGE_FRAME: case JVM_STORAGE_FRAME_PARAM: @@ -125,6 +112,7 @@ void jvm_generate_store(gen_proc_t * p, gen_var_t * dst) { char prefix = dst -> type -> prefix; + char postfix = dst -> type -> postfix; int cell_size = dst -> type -> cell_size; char * full_name = dst -> full_name; char * desc = dst -> type -> desc; @@ -149,7 +137,7 @@ jvm_generate_store(gen_proc_t * p, gen_var_t * dst) case JVM_STORAGE_FRAME_VAR: case JVM_STORAGE_FRAME_PARAM_VAR: case JVM_STORAGE_FRAME_PARAM_VARPTR: - jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", prefix); + jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", postfix); break; case JVM_STORAGE_FRAME: case JVM_STORAGE_FRAME_PARAM: @@ -203,6 +191,7 @@ jvm_create_function_var(gen_proc_t * p, enum gen_storage storage, char * name, g v -> name = new_string(name); v -> type = t; v -> p = p; + v -> level = p -> level; switch(storage) { @@ -250,6 +239,7 @@ jvm_create_function_temp_var(gen_proc_t * p, gen_type_t * t) v -> name = new_string("$TEMP_%i$", v -> reg); v -> type = t; v -> p = p; + v -> level = p -> level; return v; } @@ -267,33 +257,31 @@ jvm_generate_var(gen_var_t * v) case JVM_STORAGE_REGISTER: case JVM_STORAGE_PARAM: case JVM_STORAGE_PARAM_VAR: - jvm_generate(p, 0, 0, ".var %i is %s %s from start to end", reg, name, desc); + case JVM_STORAGE_FRAME: + case JVM_STORAGE_FRAME_VAR: + case JVM_STORAGE_FRAME_PARAM: + case JVM_STORAGE_FRAME_PARAM_VAR: + jvm_generate(p, 0, 0, ".var %i is '%s' %s from start to end", reg, name, desc); break; case JVM_STORAGE_REGISTER_VAR: - jvm_generate(p, 0, 0, ".var %i is %s [%s from start to end", reg, name, desc); + jvm_generate(p, 0, 0, ".var %i is '%s' [%s from start to end", reg, name, desc); break; case JVM_STORAGE_PARAM_VARPTR: - jvm_generate(p, 0, 0, ".var %i is %s [%s from start to end", reg, name, desc); - jvm_generate(p, 0, 0, ".var %i is %s$offset I from start to end", reg + 1, name); + case JVM_STORAGE_FRAME_PARAM_VARPTR: + jvm_generate(p, 0, 0, ".var %i is '%s' [%s from start to end", reg, name, desc); + jvm_generate(p, 0, 0, ".var %i is '%s$offset' I from start to end", reg + 1, name); break; case JVM_STORAGE_STATIC: - fprintf(v -> class -> fp, ".field public static %s %s\n\n", name, desc); + fprintf(v -> class -> fp, ".field public static '%s' %s\n\n", name, desc); break; case JVM_STORAGE_STATIC_VAR: - fprintf(v -> class -> fp, ".field public static %s [%s\n\n", name, desc); + fprintf(v -> class -> fp, ".field public static '%s' [%s\n\n", name, desc); break; case JVM_STORAGE_FIELD: - fprintf(v -> class -> fp, ".field public %s %s\n\n", name, desc); + fprintf(v -> class -> fp, ".field public '%s' %s\n\n", name, desc); break; case JVM_STORAGE_FIELD_VAR: - fprintf(v -> class -> fp, ".field public %s [%s\n\n", name, desc); - break; - case JVM_STORAGE_FRAME: - case JVM_STORAGE_FRAME_VAR: - case JVM_STORAGE_FRAME_PARAM: - case JVM_STORAGE_FRAME_PARAM_VAR: - case JVM_STORAGE_FRAME_PARAM_VARPTR: - /* См. ниже jvm_generate_frame_class() */ + fprintf(v -> class -> fp, ".field public '%s' [%s\n\n", name, desc); break; default: gen_error("jvm_generate_var: invalid storage %i", storage); @@ -307,6 +295,7 @@ jvm_generate_param_initialization(gen_proc_t * p, gen_var_t * v) int old_reg = v -> reg; int cell_size = v -> type -> cell_size; char prefix = v -> type -> prefix; + char postfix = v -> type -> postfix; char * name = v -> name; char * desc = v -> type -> desc; @@ -320,7 +309,7 @@ jvm_generate_param_initialization(gen_proc_t * p, gen_var_t * v) jvm_generate(p, 0, 1, "iconst_0"); jvm_generate(p, 0, cell_size, "%cload %i", prefix, old_reg); - jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", prefix); + jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", postfix); } void @@ -357,16 +346,17 @@ jvm_generate_var_initialization(gen_proc_t * p, gen_var_t * v) } else if(v -> storage == JVM_STORAGE_FRAME_PARAM_VARPTR) { - jvm_generate_load(p, p -> frame_v); + jvm_generate(p, 0, 1, "aload %i", p -> reg_frame[v -> level]); jvm_generate(p, 0, 1, "aload %i", v -> reg); jvm_generate(p, 1, 0, "putfield %s [%s", v -> full_name, v -> type -> desc); - jvm_generate_load(p, p -> frame_v); + jvm_generate(p, 0, 1, "aload %i", p -> reg_frame[v -> level]); jvm_generate(p, 0, 1, "iload %i", v -> reg + 1); jvm_generate(p, 1, 0, "putfield %s$offset I", v -> full_name); } } +/* static void jvm_generate_abstract_frame_class() { @@ -392,6 +382,7 @@ jvm_generate_abstract_frame_class() jvm_destroy_class(class); } +*/ static struct gen_class * jvm_generate_frame_class(oberon_object_t * proc) @@ -405,7 +396,7 @@ jvm_generate_frame_class(oberon_object_t * proc) abscname = "SYSTEM$FRAME"; cname = jvm_get_field_full_name_safe(proc); cname = new_string("%s$FRAME", cname); - class = jvm_create_class(cname); + class = jvm_create_class(proc -> gen_proc -> class -> dir, cname); fp = class -> fp; class -> full_name = cname; @@ -425,17 +416,20 @@ jvm_generate_frame_class(oberon_object_t * proc) if(v -> storage == JVM_STORAGE_FRAME || v -> storage == JVM_STORAGE_FRAME_PARAM) { - fprintf(fp, ".field public %s %s\n\n", v -> name, v -> type -> desc); + fprintf(fp, "; LEVEL %i\n", v -> level); + fprintf(fp, ".field public '%s' %s\n\n", v -> name, v -> type -> desc); } else if(v -> storage == JVM_STORAGE_FRAME_VAR || v -> storage == JVM_STORAGE_FRAME_PARAM_VAR) { - fprintf(fp, ".field public %s [%s\n\n", v -> name, v -> type -> desc); + fprintf(fp, "; LEVEL %i\n", v -> level); + fprintf(fp, ".field public '%s' [%s\n\n", v -> name, v -> type -> desc); } else if(v -> storage == JVM_STORAGE_FRAME_PARAM_VARPTR) { - fprintf(fp, ".field public %s [%s\n", v -> name, v -> type -> desc); - fprintf(fp, ".field public %s$offset I\n\n", v -> name); + fprintf(fp, "; LEVEL %i\n", v -> level); + fprintf(fp, ".field public '%s' [%s\n", v -> name, v -> type -> desc); + fprintf(fp, ".field public '%s$offset' I\n\n", v -> name); } } var = var -> next; @@ -484,7 +478,8 @@ jvm_generate_procedure_frame(oberon_object_t * proc) p = proc -> gen_proc; - jvm_generate_abstract_frame_class(); +// jvm_generate_abstract_frame_class(); + class = jvm_generate_frame_class(proc); t = GC_MALLOC(sizeof *t); @@ -497,9 +492,8 @@ jvm_generate_procedure_frame(oberon_object_t * proc) t -> desc = new_string("L%s;", class -> full_name); v = jvm_create_function_var(p, JVM_STORAGE_REGISTER, "$FP$", t); - p -> frame_v = v; - p -> frame_t = t; + p -> reg_frame[p -> level] = v -> reg; } void @@ -507,8 +501,181 @@ jvm_generate_frame_initialization(gen_proc_t * p) { jvm_generate_var(p -> frame_v); jvm_generate_ldst_prepare(p, p -> frame_v); - jvm_generate(p, 0, 1, "new %s", p -> frame_t -> class -> full_name); + jvm_generate(p, 0, 1, "new %s", p -> frame_v -> type -> class -> full_name); jvm_generate(p, 1, 2, "dup"); - jvm_generate(p, 1, 0, "invokespecial %s/()V", p -> frame_t -> class -> full_name); + jvm_generate(p, 1, 0, "invokespecial %s/()V", p -> frame_v -> type -> class -> full_name); jvm_generate_store(p, p -> frame_v); } + +char * +jvm_get_procedure_signature(oberon_type_t * ps) +{ + char * signature; + char * desc; + int num; + oberon_object_t * arg; + + signature = new_string("("); + + num = ps -> num_decl; + arg = ps -> decl; + for(int i = 0; i < num; i++) + { + desc = jvm_get_descriptor(arg -> type); + if(arg -> class == OBERON_CLASS_VAR_PARAM) + { + signature = new_string("%s[%sI", signature, desc); + } + else + { + signature = new_string("%s%s", signature, desc); + } + arg = arg -> next; + } + + desc = jvm_get_descriptor(ps -> base); + signature = new_string("%s)%s", signature, desc); + + return signature; +} + +static char * +jvm_get_frame_descriptor(oberon_object_t * proc) +{ + char * full_name = jvm_get_field_full_name_safe(proc); + return new_string("L%s$FRAME;", full_name); +} + +static char * +jvm_get_oberon_signature_static_links(oberon_object_t * parent) +{ + if(parent == NULL) + { + return ""; + } + + char * up = jvm_get_oberon_signature_static_links(parent -> parent); + char * desc = jvm_get_frame_descriptor(parent); + return new_string("%s%s", up, desc); +} + +char * +jvm_get_local_procedure_signature(oberon_object_t * proc) +{ + char * stlinks; + char * signature; + char * desc; + int num; + oberon_object_t * arg; + oberon_type_t * ps; + + ps = proc -> type; + + signature = new_string("("); + + if(proc -> local) + { + stlinks = jvm_get_oberon_signature_static_links(proc -> parent); + signature = new_string("%s%s", signature, stlinks); + } + + num = ps -> num_decl; + arg = ps -> decl; + for(int i = 0; i < num; i++) + { + desc = jvm_get_descriptor(arg -> type); + if(arg -> class == OBERON_CLASS_VAR_PARAM) + { + signature = new_string("%s[%sI", signature, desc); + } + else + { + signature = new_string("%s%s", signature, desc); + } + arg = arg -> next; + } + + desc = jvm_get_descriptor(ps -> base); + signature = new_string("%s)%s", signature, desc); + + return signature; +} + + +static void +jvm_generate_staticlinks_recursive(gen_proc_t * p, oberon_object_t * parent, int level) +{ + if(parent == NULL) + { + return; + } + + jvm_generate_staticlinks_recursive(p, parent -> parent, level - 1); + int reg = p -> reg_frame[level]; + char * desc = jvm_get_frame_descriptor(parent); + jvm_generate(p, 0, 0, ".var %i is SL$%i %s from start to end", reg, level, desc); +} + +void +jvm_generate_staticlinks(oberon_object_t * proc) +{ + gen_proc_t * p; + + p = proc -> gen_proc; + + jvm_generate_staticlinks_recursive(p, proc -> parent, p -> level); +} + +static void +jvm_create_staticlinks_recursive(gen_proc_t * p, oberon_object_t * parent, int level) +{ + if(parent == NULL) + { + return; + } + + jvm_create_staticlinks_recursive(p, parent -> parent, level - 1); + p -> reg_frame[level] = jvm_alloc_register_untyped(p -> rf, false); +} + +void +jvm_create_static_links(oberon_object_t * proc) +{ + gen_proc_t * p; + p = proc -> gen_proc; + + int max_frames = 0; + oberon_object_t * prc = proc; + while(prc) + { + max_frames += 1; + prc = prc -> parent; + } + + size_t sz = sizeof(*p -> reg_frame) * max_frames; + p -> max_frames = max_frames; + p -> reg_frame = GC_MALLOC(sz); + memset(p -> reg_frame, 0, sz); + + p -> level = max_frames - 1; + jvm_create_staticlinks_recursive(p, proc -> parent, p -> level); +} + +static void +jvm_generate_push_static_links_recursive(gen_proc_t * p, oberon_object_t * parent) +{ + if(parent == NULL) + { + return; + } + + jvm_generate_push_static_links_recursive(p, parent -> parent); + int level = parent -> gen_proc -> level; + jvm_generate(p, 0, 1, "aload %i", p -> reg_frame[level]); +} + +void +jvm_generate_push_static_links(gen_proc_t * p, oberon_object_t * proc) +{ + jvm_generate_push_static_links_recursive(p, proc -> parent); +}