DEADSOFTWARE

JVM: Реализованы локальные процедуры (без доступа к локальным переменным уровнем...
[dsw-obn.git] / src / backends / jvm / generator-jvm-abi.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <string.h>
7 #include <assert.h>
9 #include <gc.h>
11 #include "../../../include/oberon.h"
12 #include "../../oberon-internals.h"
13 #include "generator-jvm.h"
14 #include "generator-jvm-abi.h"
15 #include "generator-jvm-asm.h"
16 #include "generator-jvm-basic.h"
18 /*
19 * --- Каждый модуль является объектом.
20 * Импортируемые модули представляются полями.
21 * Каждая глобальная переменная представляется не статическим полем.
22 * Каждая процедура представляется не статическим метеодом.
23 * Процедура инициализации модуля имеет название BEGIN.
24 * Процедура финализации модуля имеет название END.
25 * Это позволит сделать динамическую загрузку и выгрузку.
26 * +++ всем переменным и полям в дескриптор добавляется "["
27 * Это позволит делать ссылки на переменные в VAR-параметрах.
28 * --- Каждая процедура снабжается параметром-фреймом.
29 * Это позволит реализовать локальные процедуры и средства рефлекции над стеком.
30 */
32 void
33 jvm_generate_ldst_prepare(gen_proc_t * p, gen_var_t * v)
34 {
35 char * desc;
36 char * full_name;
37 switch(v -> storage)
38 {
39 case JVM_STORAGE_REGISTER:
40 break;
41 case JVM_STORAGE_STATIC:
42 full_name = v -> full_name;
43 desc = v -> type -> desc;
44 jvm_generate(p, 0, 1, "getstatic %s [%s", full_name, desc);
45 jvm_generate(p, 0, 1, "iconst_0");
46 break;
47 case JVM_STORAGE_FIELD:
48 full_name = v -> full_name;
49 desc = v -> type -> desc;
50 jvm_generate(p, 1, 1, "getfield %s [%s", full_name, desc);
51 jvm_generate(p, 0, 1, "iconst_0");
52 break;
53 case JVM_STORAGE_LOCAL:
54 jvm_generate(p, 0, 1, "aload %i", v -> reg);
55 jvm_generate(p, 0, 1, "iconst_0");
56 break;
57 case JVM_STORAGE_VARPTR:
58 jvm_generate(p, 0, 1, "aload %i", v -> reg);
59 jvm_generate(p, 0, 1, "iload %i", v -> reg + 1);
60 break;
61 default:
62 gen_error("jvm_abi_obn_generate_ldst_prepare: wat %i", v -> storage);
63 }
64 }
66 void
67 jvm_generate_load(gen_proc_t * p, gen_var_t * src)
68 {
69 char prefix = src -> type -> prefix;
70 int cell_size = src -> type -> cell_size;
72 switch(src -> storage)
73 {
74 case JVM_STORAGE_REGISTER:
75 jvm_generate(p, 0, cell_size, "%cload %i", prefix, src -> reg);
76 break;
77 case JVM_STORAGE_STATIC:
78 case JVM_STORAGE_FIELD:
79 case JVM_STORAGE_LOCAL:
80 case JVM_STORAGE_VARPTR:
81 jvm_generate_ldst_prepare(p, src);
82 jvm_generate(p, 1 + 1, cell_size, "%caload", prefix);
83 break;
84 default:
85 gen_error("jvm_generate_load: unknow storage type %i", src -> storage);
86 break;
87 }
88 }
90 void
91 jvm_generate_store(gen_proc_t * p, gen_var_t * dst)
92 {
93 char prefix = dst -> type -> prefix;
94 int cell_size = dst -> type -> cell_size;
96 switch(dst -> storage)
97 {
98 case JVM_STORAGE_REGISTER:
99 jvm_generate(p, cell_size, 0, "%cstore %i", prefix, dst -> reg);
100 break;
101 case JVM_STORAGE_STATIC:
102 case JVM_STORAGE_FIELD:
103 case JVM_STORAGE_LOCAL:
104 case JVM_STORAGE_VARPTR:
105 jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", prefix);
106 break;
107 default:
108 gen_error("jvm_generate_store: unknow storage type %i", dst -> storage);
109 break;
113 void
114 jvm_generate_and_init_global_var(struct gen_class * class, gen_var_t * v, char * name, gen_type_t * t)
116 assert(class -> p == NULL);
117 fprintf(class -> fp, ".field public static %s [%s\n\n", name, t -> desc);
119 v -> storage = JVM_STORAGE_STATIC;
120 v -> full_name = new_string("%s/%s", class -> full_name, name);
121 v -> type = t;
124 void
125 jvm_generate_and_init_field(struct gen_class * class, gen_var_t * v, char * name, gen_type_t * t)
127 assert(class -> p == NULL);
128 fprintf(class -> fp, ".field public %s [%s\n\n", name, t -> desc);
130 v -> storage = JVM_STORAGE_FIELD;
131 v -> full_name = new_string("%s/%s", class -> full_name, name);
132 v -> type = t;
135 void
136 jvm_generate_and_init_local_var(gen_proc_t * p, gen_var_t * v, gen_type_t * t)
138 v -> storage = JVM_STORAGE_REGISTER;
139 v -> reg = jvm_alloc_register_untyped(p -> rf, t -> wide);
140 v -> type = t;
143 void
144 jvm_init_named_local_var(gen_proc_t * p, gen_var_t * v, gen_type_t * t)
146 v -> storage = JVM_STORAGE_REGISTER;
147 v -> reg = jvm_alloc_register_untyped(p -> rf, t -> wide);
148 v -> type = t;
151 void
152 jvm_init_param(gen_proc_t * p, gen_var_t * v, gen_type_t * t)
154 v -> storage = JVM_STORAGE_LOCAL;
155 v -> reg = jvm_alloc_register_untyped(p -> rf, t -> wide);
156 v -> type = t;
159 void
160 jvm_init_var_param(gen_proc_t * p, gen_var_t * v, gen_type_t * t)
162 v -> storage = JVM_STORAGE_VARPTR;
163 v -> reg = jvm_alloc_register_untyped(p -> rf, true);
164 v -> type = t;
167 void
168 jvm_generate_variable_initialization(gen_proc_t * p, gen_var_t * v)
170 if(v -> storage == JVM_STORAGE_STATIC)
172 jvm_generate(p, 0, 1, "iconst_1");
173 jvm_generate(p, 1, 1, "multianewarray [%s 1", v -> type -> desc);
174 jvm_generate(p, 1, 0, "putstatic %s [%s", v -> full_name, v -> type -> desc);
176 else if(v -> storage == JVM_STORAGE_FIELD)
178 jvm_generate(p, 0, 1, "iconst_1");
179 jvm_generate(p, 1, 1, "multianewarray [%s 1", v -> type -> desc);
180 jvm_generate(p, 1, 0, "putfield %s [%s", v -> full_name, v -> type -> desc);
184 void
185 jvm_generate_named_local_var_initialization(gen_proc_t * p, gen_var_t * v, char * name)
187 jvm_generate(p, 0, 0, ".var %i is %s %s from start to end", v -> reg, name, v -> type -> desc);
190 void
191 jvm_generate_param_initialization(gen_proc_t * p, gen_var_t * v, char * name)
193 int old_reg = v -> reg;
194 bool wide = v -> type -> wide;
195 int cell_size = v -> type -> cell_size;
196 char prefix = v -> type -> prefix;
197 char * desc = v -> type -> desc;
199 jvm_generate(p, 0, 0, ".var %i is %s %s from start to end", old_reg, name, desc);
200 v -> reg = jvm_alloc_register_untyped(p -> rf, wide);
202 jvm_generate(p, 0, 1, "iconst_1");
203 jvm_generate(p, 1, 1, "multianewarray [%s 1", desc);
204 jvm_generate(p, 1, 2, "dup");
205 jvm_generate(p, 1, 0, "astore %i", v -> reg);
207 jvm_generate(p, 0, 1, "iconst_0");
208 jvm_generate(p, 0, cell_size, "%cload %i", prefix, old_reg);
209 jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", prefix);
212 void
213 jvm_generate_var_param_initialization(gen_proc_t * p, gen_var_t * v, char * name)
215 jvm_generate(p, 0, 0, ".var %i is %s [%s from start to end", v -> reg, name, v -> type -> desc);
216 jvm_generate(p, 0, 0, ".var %i is __%s_offset I from start to end", v -> reg + 1, name);