From e8f94e8772c0eaa4fb7f0e6b9f892f014d3423df Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Fri, 28 Jul 2017 00:49:46 +0300 Subject: [PATCH] =?utf8?q?JVM:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?utf8?q?=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=B0=D1=81=D1=81=D0=B8=D0=B2=D1=8B?= =?utf8?q?=20=D0=B8=20=D0=B0=D0=BB=D0=BB=D0=BE=D0=BA=D0=B0=D1=86=D0=B8?= =?utf8?q?=D1=8F=20=D1=84=D0=B8=D0=BA=D1=81=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?utf8?q?=D0=BD=D0=BD=D0=BE=D0=B9=20=D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=80?= =?utf8?q?=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20(=D0=B1=D0=B5=D0=B7=20=D0=B8?= =?utf8?q?=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86?= =?utf8?q?=D0=B8=D0=B8,=20=D0=BD=D1=83=D0=B6=D0=BD=D1=8B=20=D1=86=D0=B8?= =?utf8?q?=D0=BA=D0=BB=D1=8B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- JTest.java | 9 +++ src/backends/jvm/generator-jvm-basic.c | 53 +++++++++++++++-- src/backends/jvm/generator-jvm-basic.h | 5 +- src/backends/jvm/generator-jvm.c | 81 +++++++++----------------- src/test.c | 18 +----- 5 files changed, 93 insertions(+), 73 deletions(-) create mode 100644 JTest.java diff --git a/JTest.java b/JTest.java new file mode 100644 index 0000000..1ce1766 --- /dev/null +++ b/JTest.java @@ -0,0 +1,9 @@ +class JTest +{ + boolean[] z; + + void x(boolean y) + { + z[666] = y; + } +} diff --git a/src/backends/jvm/generator-jvm-basic.c b/src/backends/jvm/generator-jvm-basic.c index d419abe..5fabc31 100644 --- a/src/backends/jvm/generator-jvm-basic.c +++ b/src/backends/jvm/generator-jvm-basic.c @@ -138,6 +138,52 @@ jvm_get_prefix(oberon_type_t * type) return '!'; } +char +jvm_get_postfix(oberon_type_t * type) +{ + int size = type -> size; + switch(type -> class) + { + case OBERON_TYPE_BOOLEAN: + return 'b'; + break; + case OBERON_TYPE_INTEGER: + switch(size) + { + case 1: + return 'b'; + break; + case 2: + return 's'; + break; + case 4: + return 'i'; + break; + case 8: + return 'l'; + break; + default: + gen_error("jvm_get_postfix: int wat"); + break; + } + break; + case OBERON_TYPE_PROCEDURE: + case OBERON_TYPE_ARRAY: + case OBERON_TYPE_RECORD: + case OBERON_TYPE_POINTER: + return 'a'; + break; + case OBERON_TYPE_REAL: + return (size <= 4) ? ('f') : ('d'); + break; + default: + gen_error("jvm_get_postfix: wat"); + break; + } + + return '!'; +} + char * jvm_get_field_full_name(oberon_object_t * x) { @@ -234,22 +280,21 @@ jvm_cell_size_for_type(oberon_type_t * type) } int -jvm_cell_size_for_prefix(char prefix) +jvm_cell_size_for_postfix(char postfix) { - switch(prefix) + switch(postfix) { case 'a': case 'b': case 's': case 'i': - case 'z': case 'f': return 1; case 'l': case 'd': return 2; default: - gen_error("jvm_cell_size_for_prefix: unk prefix %c", prefix); + gen_error("jvm_cell_size_for_postfix: unk postfix %c", postfix); } return -666; diff --git a/src/backends/jvm/generator-jvm-basic.h b/src/backends/jvm/generator-jvm-basic.h index 094d886..2d4312f 100644 --- a/src/backends/jvm/generator-jvm-basic.h +++ b/src/backends/jvm/generator-jvm-basic.h @@ -17,6 +17,9 @@ jvm_get_descriptor(oberon_type_t * type); char jvm_get_prefix(oberon_type_t * type); +char +jvm_get_postfix(oberon_type_t * type); + char * jvm_get_field_full_name(oberon_object_t * x); @@ -32,7 +35,7 @@ int jvm_cell_size_for_type(oberon_type_t * type); int -jvm_cell_size_for_prefix(char prefix); +jvm_cell_size_for_postfix(char postix); bool jvm_is_wide_type(oberon_type_t * type); diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index 99a4673..84ebe51 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -208,7 +208,9 @@ jvm_generate_label(gen_proc_t * p, int label_id) static void jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type) { + int dim; char * cname; + char * desc; switch(type -> class) { @@ -217,7 +219,7 @@ jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type) case OBERON_TYPE_PROCEDURE: case OBERON_TYPE_REAL: case OBERON_TYPE_POINTER: - /* ничего не надо делать при статической инициализации */ + gen_error("jvm_generate_new_static: static alocation not allowed"); break; case OBERON_TYPE_RECORD: cname = jvm_get_class_full_name(type); @@ -226,7 +228,15 @@ jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type) jvm_generate(p, 1, 0, "invokespecial %s/()V", cname); break; case OBERON_TYPE_ARRAY: - gen_error("jvm_generate_new_static: TODO array"); + dim = 0; + desc = jvm_get_descriptor(type); + while(type -> class == OBERON_TYPE_ARRAY) + { + dim += 1; + jvm_generate_push_int(p, type -> size); + type = type -> base; + } + jvm_generate(p, dim, 1, "multianewarray %s %i", desc, dim); break; default: gen_error("jvm_generate_new_static: unk type class %i", type -> class); @@ -723,7 +733,12 @@ push_item(gen_proc_t * p, oberon_item_t * item) jvm_generate_call_proc(p, (oberon_expr_t *) item); break; case MODE_INDEX: - gen_error("push_item: TODO index"); + ; + char postfix = jvm_get_postfix(item -> result); + int cell_size = jvm_cell_size_for_postfix(postfix); + push_item(p, item -> parent); + push_expr(p, item -> args); + jvm_generate(p, 1 + 1, cell_size, "%caload", postfix); break; case MODE_FIELD: push_item(p, item -> parent); @@ -770,7 +785,7 @@ static void jvm_generate_abs(gen_proc_t * p, char prefix) { char t = jvm_get_type_of_prefix(prefix); - int cell_size = jvm_cell_size_for_prefix(prefix); + int cell_size = jvm_cell_size_for_postfix(prefix); jvm_generate(p, cell_size, cell_size, "invokestatic java/lang/Math/abs(%c)%c", t, t); } @@ -781,7 +796,7 @@ jvm_generate_compare_op(gen_proc_t * p, char prefix, int op) int label_done = jvm_new_label_id(p); char * label_name_true = jvm_get_label_name(label_true); char * label_name_done = jvm_get_label_name(label_done); - int cell_size = 2 * jvm_cell_size_for_prefix(prefix); + int cell_size = 2 * jvm_cell_size_for_postfix(prefix); assert(prefix == 'i' || prefix == 'a'); @@ -822,7 +837,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) { - int cell_size = jvm_cell_size_for_prefix(prefix); + int cell_size = jvm_cell_size_for_postfix(prefix); switch(op) { case OP_UNARY_MINUS: @@ -989,7 +1004,13 @@ store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src) jvm_generate_store(p, src -> result, item -> var -> gen_var); break; case MODE_INDEX: - gen_error("store_expr: TODO index"); + ; + char postfix = jvm_get_postfix(src -> result); + int cell_size = jvm_cell_size_for_postfix(postfix); + push_item(p, item -> parent); + push_expr(p, item -> args); + push_expr(p, src); + jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", postfix); break; case MODE_FIELD: push_item(p, item -> parent); @@ -1002,52 +1023,6 @@ store_expr(gen_proc_t * p, oberon_expr_t * dst, oberon_expr_t * src) } } -/* -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; - - int cell_size = jvm_cell_size_for_type(src -> result); - - char prefix; - switch(item -> mode) - { - case MODE_VAR: - push_expr(p, src); - if(item -> var -> local) - { - int reg = item -> var -> gen_var -> reg; - prefix = jvm_get_prefix(item -> result); - jvm_generate(p, cell_size, 0, "%cstore %i", prefix, reg); - } - else - { - char * fullname = jvm_get_field_full_name(item -> var); - char * desc = jvm_get_descriptor(item -> result); - jvm_generate(p, cell_size, 0, "putstatic %s %s", fullname, desc); - } - break; - case MODE_INDEX: - gen_error("store_expr: TODO index"); - break; - case MODE_FIELD: - { - char * fullname = jvm_get_field_full_name(item -> var); - char * desc = jvm_get_descriptor(item -> result); - push_item(p, item -> parent); - push_expr(p, src); - jvm_generate(p, 1 + cell_size, 0, "putfield %s %s", fullname, desc); - } - break; - default: - gen_error("store_expr: unk mode %i", item -> mode); - break; - } -} -*/ - void oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst) { diff --git a/src/test.c b/src/test.c index 0edbdf4..69cfc99 100644 --- a/src/test.c +++ b/src/test.c @@ -7,23 +7,11 @@ static char source_test[] = "(* Main module *)" "MODULE Test;" - "TYPE" - " Rec = POINTER TO RecDesc;" - " RecDesc = RECORD" - " x, y, z : INTEGER;" - " r : RECORD xxx : INTEGER; END;" - " END;" "VAR" - " a : INTEGER;" - " r : Rec;" + " l : POINTER TO ARRAY 16 OF BOOLEAN;" "BEGIN" - " NEW(r);" - " a := 123;" - " a := -(3 * a + 456);" - " r.x := a;" - " r.y := r.x;" - " r.z := r.y * 3;" - " r.r.xxx := 666;" + " NEW(l);" + " l[0] := l[5];" "END Test." ; -- 2.29.2