From: DeaDDooMER <deaddoomer@deadsoftware.ru>
Date: Fri, 28 Jul 2017 18:22:25 +0000 (+0300)
Subject: JVM: Можно создавать динамические массивы
X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=fef434efd26d259ed8a857e28af092df93282880;p=dsw-obn.git

JVM: Можно создавать динамические массивы
---

diff --git a/src/backends/jvm/generator-jvm.c b/src/backends/jvm/generator-jvm.c
index 9408eca..cbc834e 100644
--- a/src/backends/jvm/generator-jvm.c
+++ b/src/backends/jvm/generator-jvm.c
@@ -256,7 +256,7 @@ jvm_generate_label(gen_proc_t * p, int label_id)
 }
 
 static void
-jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type);
+jvm_generate_new(gen_proc_t * p, oberon_type_t * type, int num);
 
 /*
  * Функция jvm_generate_static_array_initialization генерирует код для
@@ -322,7 +322,7 @@ jvm_generate_static_array_initialization(gen_proc_t * p, oberon_type_t * type)
 	{
 		jvm_generate(p, 0, 1, "aload %i", reg_a);
 		jvm_generate(p, 0, 1, "iload %i", reg_i);
-		jvm_generate_new_static(p, type -> base);
+		jvm_generate_new(p, type -> base, 0);
 		jvm_generate(p, 3, 0, "aastore");
 	}
 	else
@@ -344,7 +344,7 @@ jvm_generate_static_array_initialization(gen_proc_t * p, oberon_type_t * type)
 }
 
 static void
-jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type)
+jvm_generate_new(gen_proc_t * p, oberon_type_t * type, int num)
 {
 	int dim;
 	char * cname;
@@ -372,10 +372,21 @@ jvm_generate_new_static(gen_proc_t * p, oberon_type_t * type)
 			desc = jvm_get_descriptor(type);
 			while(base -> class == OBERON_TYPE_ARRAY)
 			{
+				if(num > 0)
+				{
+					assert(base -> size == 0);
+					num -= 1;
+				}
+				else
+				{
+					assert(base -> size > 0);
+					jvm_generate_push_int(p, base -> size);
+				}
 				dim += 1;
-				jvm_generate_push_int(p, base -> size);
 				base = base -> base;
 			}
+
+			assert(num == 0);
 			jvm_generate(p, dim, 1, "multianewarray %s %i", desc, dim);
 
 			if(base -> class == OBERON_TYPE_RECORD)
@@ -547,7 +558,7 @@ oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * rec)
 			|| field -> type -> class == OBERON_TYPE_ARRAY)
 		{
 			jvm_generate(p, 0, 1, "aload_0");
-			jvm_generate_new_static(p, field -> type);
+			jvm_generate_new(p, field -> type, 0);
 			jvm_generate_store(p, field -> type, field -> gen_var);
 		}
 		field = field -> next;
@@ -660,7 +671,7 @@ oberon_generate_begin_module(oberon_context_t * ctx)
 			if(x -> type -> class == OBERON_TYPE_ARRAY
 				|| x -> type -> class == OBERON_TYPE_RECORD)
 			{
-				jvm_generate_new_static(p, x -> type);
+				jvm_generate_new(p, x -> type, 0);
 				jvm_generate_store(p, x -> type, x -> gen_var);
 			}
 		}
@@ -817,18 +828,18 @@ jvm_push_var(gen_proc_t * p, oberon_object_t * var)
 	}
 }
 
-static void
-jvm_generate_expr_new_static(gen_proc_t * p, oberon_type_t * type, int num, oberon_expr_t * arg)
-{
-	assert(num == 0);
-	jvm_generate_new_static(p, type);
-}
-
 static void
 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_expr_new_static(p, type -> base, num, arg);
+
+	for(int i = 0; i < num; i++)
+	{
+		push_expr(p, arg);
+		arg = arg -> next;
+	}
+
+	jvm_generate_new(p, type -> base, num);
 }
 
 static void
diff --git a/src/test.c b/src/test.c
index 92223cd..51a1250 100644
--- a/src/test.c
+++ b/src/test.c
@@ -7,10 +7,16 @@
 static char source_test[] =
 	"(* Main module *)"
 	"MODULE Test;"
+	"TYPE"
+	"  Rec = POINTER TO RecDesc;"
+	"  RecDesc = RECORD x : INTEGER; END;"
 	"VAR"
 	"  g : ARRAY 4 OF INTEGER;"
 	"  r : RECORD x : INTEGER; END;"
+	"  a : POINTER TO ARRAY OF ARRAY OF RecDesc;"
 	"BEGIN"
+	"  NEW(a, 10, 10);"
+	"  a[9, 9].x := 666;"
 	"  g[3] := 4;"
 	"  r.x := 4546;"
 	"END Test."