X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fbackends%2Fjvm%2Fgenerator-jvm.c;h=b17711bd5627d68a54b5dd06c4a475023a1a204a;hb=51a1ab2543ec5c221d4a3a9ab89968ae7dd39981;hp=e4c70b1c23d312e580c24f1a2d2348963548ecc1;hpb=36c1947b3e98abab25f16a0f1c2679125651fe95;p=dsw-obn.git diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index e4c70b1..b17711b 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -263,6 +263,24 @@ jvm_generate_push_float(gen_proc_t * p, double f, int size) } } +static void +jvm_generate_push_string(gen_proc_t * p, char * str, int char_size) +{ + assert(char_size == 1); + int len = strlen(str); + + jvm_generate_push_int(p, len + 1); + jvm_generate(p, 1, 1, "newarray byte"); + + for(int i = 0; i < len; i++) + { + jvm_generate(p, 1, 2, "dup"); + jvm_generate_push_int(p, i); + jvm_generate_push_int(p, str[i]); + jvm_generate(p, 3, 0, "bastore"); + } +} + static gen_var_t * oberon_generator_new_var() { @@ -582,7 +600,7 @@ jvm_generate_copy_array(gen_proc_t * p, oberon_type_t * arr) * Входящие параметры заграблены. * Теперь генерируем эквивалентный код: * int i = 0; - * int len = dst.length + * int len = src.length * while(i < len) * { * ... @@ -609,7 +627,7 @@ jvm_generate_copy_array(gen_proc_t * p, oberon_type_t * arr) jvm_generate(p, 0, 1, "iconst_0"); jvm_generate(p, 1, 0, "istore %i", loop[i].index -> reg); - jvm_generate_load(p, arr, dst); + jvm_generate_load(p, arr, src); jvm_generate(p, 1, 1, "arraylength"); jvm_generate(p, 1, 0, "istore %i", loop[i].length -> reg); @@ -761,7 +779,14 @@ oberon_generate_procedure_pointer_class(oberon_object_t * proc) fprintf(fp, ".method ()V\n"); fprintf(fp, " aload_0\n"); fprintf(fp, " invokespecial %s/()V\n", abscname); - fprintf(fp, " aload_0\n"); + fprintf(fp, " return\n"); + fprintf(fp, ".end method\n\n"); + + fprintf(fp, ".method static ()V\n"); + fprintf(fp, " .limit stack 2\n"); + fprintf(fp, " new %s\n", cname); + fprintf(fp, " dup\n"); + fprintf(fp, " invokespecial %s/()V\n", cname); fprintf(fp, " putstatic %s/pointer %s\n", cname, absdesc); fprintf(fp, " return\n"); fprintf(fp, ".end method\n\n"); @@ -859,6 +884,7 @@ oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type) case OBERON_TYPE_ARRAY: case OBERON_TYPE_REAL: case OBERON_TYPE_CHAR: + case OBERON_TYPE_STRING: break; case OBERON_TYPE_RECORD: ; @@ -1076,12 +1102,6 @@ oberon_generate_begin_module(oberon_context_t * ctx) jvm_generate_store(p, x -> type, x -> gen_var); } } - else if(x -> class == OBERON_CLASS_PROC) - { - char * cname = jvm_get_field_full_name_safe(x); - jvm_generate(p, 0, 1, "new %s", cname); - jvm_generate(p, 1, 0, "invokespecial %s/()V", cname); - } x = x -> next; } @@ -1227,6 +1247,70 @@ oberon_generate_end_proc(oberon_context_t * ctx) jvm_generate_function_end(p); } +gen_label_t * +oberon_generator_reserve_label(oberon_context_t * ctx) +{ + gen_module_t * m; + gen_proc_t * p; + gen_label_t * l; + + m = ctx -> mod -> gen_mod; + p = m -> class -> p; + + l = GC_MALLOC(sizeof *l); + memset(l, 0, sizeof *l); + + l -> id = jvm_new_label_id(p); + return l; +} + +void +oberon_generate_label(oberon_context_t * ctx, gen_label_t * l) +{ + gen_module_t * m; + gen_proc_t * p; + + m = ctx -> mod -> gen_mod; + p = m -> class -> p; + + jvm_generate_label(p, l -> id); +} + +void +oberon_generate_goto(oberon_context_t * ctx, gen_label_t * l) +{ + gen_module_t * m; + gen_proc_t * p; + + m = ctx -> mod -> gen_mod; + p = m -> class -> p; + + jvm_generate(p, 0, 0, "goto L%i", l -> id); +} + +void +oberon_generate_branch(oberon_context_t * ctx, oberon_expr_t * cond, bool gotoif, gen_label_t * l) +{ + gen_module_t * m; + gen_proc_t * p; + + m = ctx -> mod -> gen_mod; + p = m -> class -> p; + + push_expr(p, cond); + + if(gotoif == false) + { + /* переход если false */ + jvm_generate(p, 1, 0, "ifeq L%i", l -> id); + } + else + { + /* переход если true */ + jvm_generate(p, 1, 0, "ifne L%i", l -> id); + } +} + static void jvm_generate_call_proc(gen_proc_t * p, oberon_item_t * desig) { @@ -1404,6 +1488,9 @@ push_item(gen_proc_t * p, oberon_item_t * item) case MODE_REAL: jvm_generate_push_float(p, item -> real, item -> result -> size); break; + case MODE_STRING: + jvm_generate_push_string(p, item -> string, item -> result -> size); + break; default: gen_error("push_item: unk mode %i", item -> mode); break; @@ -1435,7 +1522,7 @@ jvm_generate_abs(gen_proc_t * p, char prefix) } static void -jvm_generate_compare_op(gen_proc_t * p, char prefix, int op) +jvm_generate_compare_op(gen_proc_t * p, oberon_type_t * t, char prefix, int op) { int label_true = jvm_new_label_id(p); int label_done = jvm_new_label_id(p); @@ -1480,7 +1567,7 @@ jvm_generate_compare_op(gen_proc_t * p, char prefix, int op) } static void -jvm_generate_operator(gen_proc_t * p, char prefix, int op) +jvm_generate_operator(gen_proc_t * p, oberon_type_t * t, char prefix, int op) { int cell_size = jvm_cell_size_for_postfix(prefix); switch(op) @@ -1530,7 +1617,7 @@ jvm_generate_operator(gen_proc_t * p, char prefix, int op) case OP_LEQ: case OP_GRT: case OP_GEQ: - jvm_generate_compare_op(p, prefix, op); + jvm_generate_compare_op(p, t, prefix, op); break; default: gen_error("jvm_generate_operator: unk op %i", op); @@ -1579,6 +1666,7 @@ jvm_generate_logical_and(gen_proc_t * p, oberon_expr_t * a, oberon_expr_t * b) static void push_operator(gen_proc_t * p, oberon_oper_t * oper) { + oberon_type_t * preq = oper -> left -> result; char prefix = jvm_get_prefix(oper -> result); int op = oper -> op; switch(op) @@ -1592,7 +1680,7 @@ push_operator(gen_proc_t * p, oberon_oper_t * oper) case OP_LOGIC_NOT: case OP_ABS: push_expr(p, oper -> left); - jvm_generate_operator(p, prefix, op); + jvm_generate_operator(p, preq, prefix, op); break; case OP_ADD: @@ -1612,7 +1700,7 @@ push_operator(gen_proc_t * p, oberon_oper_t * oper) case OP_GEQ: push_expr(p, oper -> left); push_expr(p, oper -> right); - jvm_generate_operator(p, prefix, op); + jvm_generate_operator(p, preq, prefix, op); break; case OP_LOGIC_OR: