From 961fbb99dcba21ccb737db16c0cdb28d757a2de7 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sat, 29 Jul 2017 18:27:09 +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=D0=BE=20=D0=BA=D0=BE=D0=BF=D0=B8=D1=80=D0=BE=D0=B2?= =?utf8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B0=D1=81=D1=81=D0=B8=D0=B2?= =?utf8?q?=D0=BE=D0=B2=20=D0=B8=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B5?= =?utf8?q?=D0=B9=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B?= =?utf8?q?=D1=85=20=D0=B2=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83?= =?utf8?q?=D1=80=D1=8B=20=D1=81=D0=BE=20=D1=81=D1=82=D0=B0=D1=82=D0=B8?= =?utf8?q?=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=BC=D0=B8=20=D1=82=D0=B8=D0=BF?= =?utf8?q?=D0=B0=D0=BC=D0=B8=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82?= =?utf8?q?=D1=80=D0=BE=D0=B2=20(=D0=B2=20=D1=82=D0=BE=D0=BC=20=D1=87=D0=B8?= =?utf8?q?=D1=81=D0=BB=D0=B5=20=D0=B8=20=D0=BA=D0=BE=D0=BF=D0=B8=D1=80?= =?utf8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D0=BA=D1=80?= =?utf8?q?=D1=8B=D1=82=D1=8B=D1=85=20=D0=BC=D0=B0=D1=81=D1=81=D0=B8=D0=B2?= =?utf8?q?=D0=BE=D0=B2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/backends/jvm/generator-jvm-basic.c | 1 + src/backends/jvm/generator-jvm.c | 86 +++++++++++++++++++++++--- src/test.c | 23 +++++-- 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/src/backends/jvm/generator-jvm-basic.c b/src/backends/jvm/generator-jvm-basic.c index 5fabc31..d092f8e 100644 --- a/src/backends/jvm/generator-jvm-basic.c +++ b/src/backends/jvm/generator-jvm-basic.c @@ -190,6 +190,7 @@ jvm_get_field_full_name(oberon_object_t * x) switch(x -> class) { case OBERON_CLASS_VAR: + case OBERON_CLASS_PROC: return new_string("%s/%s", x -> module -> name, x -> name); case OBERON_CLASS_FIELD:; char * rec_name = jvm_get_class_full_name(x -> parent_type); diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c index 895a5ae..dc79ea1 100644 --- a/src/backends/jvm/generator-jvm.c +++ b/src/backends/jvm/generator-jvm.c @@ -349,7 +349,8 @@ jvm_generate_array_initialization(gen_proc_t * p, oberon_type_t * arr) jvm_generate_and_init_local_var(dst, p, false); jvm_generate_store(p, arr, dst); - /* Входящие параметры заграблены. + /* + * Входящие параметры заграблены. * Теперь генерируем эквивалентный код: * int i = 0; * int len = dst.length @@ -510,7 +511,8 @@ jvm_generate_copy_array(gen_proc_t * p, oberon_type_t * arr) jvm_generate_store(p, arr, src); jvm_generate_store(p, arr, dst); - /* Входящие параметры заграблены. + /* + * Входящие параметры заграблены. * Теперь генерируем эквивалентный код: * int i = 0; * int len = dst.length @@ -551,12 +553,7 @@ jvm_generate_copy_array(gen_proc_t * p, oberon_type_t * arr) jvm_generate(p, 2, 0, "if_icmpge L%i", loop[i].end); } - if(base -> class == OBERON_TYPE_ARRAY) - { - // Вся эта шляпа уже должна знать о всех размерностях - gen_error("jvm_generate_copy_array: wat"); - } - else if(base -> class == OBERON_TYPE_RECORD) + if(base -> class == OBERON_TYPE_RECORD) { /* Получаем записи по индексам ( -- dst src ) */ @@ -825,7 +822,7 @@ oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) /* смотри oberon_generator_init_record() */ break; case OBERON_CLASS_VAR: - /* Локальные заполняются при генерации функции */ + /* Локальные заполняются при генерации функции */ /* смотри jvm_init_local_object() */ if(var -> local == 0) { @@ -946,6 +943,57 @@ jvm_init_local_object(gen_proc_t * p, oberon_object_t * x) } } +/* + * Генерирует код для получения размера измерения массива + * Аналог Обероновского LEN(v, n); где n = 0 - первое измерение. + * ( aref -- int ) + */ + +static void +jvm_generate_array_len(gen_proc_t * p, int dim) +{ + while(dim > 0) + { + jvm_generate(p, 0, 1, "iconst_0"); + jvm_generate(p, 2, 1, "aaload"); + dim -= 1; + } + jvm_generate(p, 1, 1, "arraylength"); +} + +static void +jvm_generate_array_duplicate_and_replace(gen_proc_t * p, gen_var_t * v, oberon_type_t * arr) +{ + int dim = 0; + oberon_type_t * base = arr; + while(base -> class == OBERON_TYPE_ARRAY) + { + if(base -> size == 0) + { + jvm_generate_load(p, arr, v); + jvm_generate_array_len(p, dim); + dim += 1; + } + base = base -> base; + } + + jvm_generate_new(p, arr, dim); + jvm_generate(p, 1, 2, "dup"); + jvm_generate_load(p, arr, v); + jvm_generate_copy_array(p, arr); + jvm_generate_store(p, arr, v); +} + +static void +jvm_generate_record_duplicate_and_replace(gen_proc_t * p, gen_var_t * v, oberon_type_t * rec) +{ + jvm_generate_new(p, rec, 0); + jvm_generate(p, 1, 2, "dup"); + jvm_generate_load(p, rec, v); + jvm_generate_copy_record(p, rec); + jvm_generate_store(p, rec, v); +} + void oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc) { @@ -955,15 +1003,33 @@ oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc) p = proc -> gen_proc; signature = jvm_get_procedure_signature(proc -> type); - jvm_generate_function_header(p, "public static", proc -> name, signature); + /* Выделение регистров под параметры и переменные */ oberon_object_t * var = proc -> type -> decl; while(var) { jvm_init_local_object(p, var); var = var -> next; } + + /* Копирование статических/открытых массивов и записей */ + var = proc -> type -> decl; + while(var) + { + if(var -> class == OBERON_CLASS_PARAM || var -> class == OBERON_CLASS_VAR_PARAM) + { + if(var -> type -> class == OBERON_TYPE_ARRAY) + { + jvm_generate_array_duplicate_and_replace(p, var -> gen_var, var -> type); + } + else if(var -> type -> class == OBERON_TYPE_RECORD) + { + jvm_generate_record_duplicate_and_replace(p, var -> gen_var, var -> type); + } + } + var = var -> next; + } } void diff --git a/src/test.c b/src/test.c index 6282321..2b9fd06 100644 --- a/src/test.c +++ b/src/test.c @@ -8,11 +8,26 @@ static char source_test[] = "(* Main module *)" "MODULE Test;" "TYPE" - " RecDesc = RECORD a : ARRAY 3, 5 OF INTEGER; END;" + " Arr = ARRAY 32, 768 OF INTEGER;" + " RecDesc = RECORD x, y, z : INTEGER; END;" + "" "VAR" - " a, b : ARRAY 3, 6 OF RecDesc;" - "BEGIN" - " a := b;" + " z : Arr;" + " r : RecDesc;" + "" + "PROCEDURE TestRecordCopy(rrr : RecDesc);" + "END TestRecordCopy;" + "" + "PROCEDURE TestArrayCopy(aaa : Arr);" + "END TestArrayCopy;" + "" + "PROCEDURE TestOpenArrayCopy(ppp : ARRAY OF ARRAY OF INTEGER);" + "END TestOpenArrayCopy;" + "" + "BEGIN;" + " TestRecordCopy(r);" + " TestArrayCopy(z);" + " TestOpenArrayCopy(z);" "END Test." ; -- 2.29.2