DEADSOFTWARE

JVM: Реализованы VAR-параметры
[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 * full_name = v -> full_name;
36 char * desc = v -> type -> desc;
38 switch(v -> storage)
39 {
40 case JVM_STORAGE_REGISTER:
41 break;
42 case JVM_STORAGE_STATIC:
43 jvm_generate(p, 0, 1, "getstatic %s [%s", full_name, desc);
44 jvm_generate(p, 0, 1, "iconst_0");
45 break;
46 case JVM_STORAGE_FIELD:
47 jvm_generate(p, 1, 1, "getfield %s [%s", full_name, desc);
48 jvm_generate(p, 0, 1, "iconst_0");
49 break;
50 case JVM_STORAGE_LOCAL:
51 jvm_generate(p, 0, 1, "aload %i", v -> reg);
52 jvm_generate(p, 0, 1, "iconst_0");
53 break;
54 case JVM_STORAGE_VARPTR:
55 jvm_generate(p, 0, 1, "aload %i", v -> reg);
56 jvm_generate(p, 0, 1, "iload %i", v -> reg + 1);
57 break;
58 default:
59 gen_error("jvm_abi_obn_generate_ldst_prepare: wat %i", v -> storage);
60 }
61 }
63 void
64 jvm_generate_load(gen_proc_t * p, gen_var_t * src)
65 {
66 char prefix = src -> type -> prefix;
67 int cell_size = src -> type -> cell_size;
69 switch(src -> storage)
70 {
71 case JVM_STORAGE_REGISTER:
72 jvm_generate(p, 0, cell_size, "%cload %i", prefix, src -> reg);
73 break;
74 case JVM_STORAGE_STATIC:
75 case JVM_STORAGE_FIELD:
76 case JVM_STORAGE_LOCAL:
77 case JVM_STORAGE_VARPTR:
78 jvm_generate_ldst_prepare(p, src);
79 jvm_generate(p, 1 + 1, cell_size, "%caload", prefix);
80 break;
81 default:
82 gen_error("jvm_generate_load: unknow storage type %i", src -> storage);
83 break;
84 }
85 }
87 void
88 jvm_generate_store(gen_proc_t * p, gen_var_t * dst)
89 {
90 char prefix = dst -> type -> prefix;
91 int cell_size = dst -> type -> cell_size;
93 switch(dst -> storage)
94 {
95 case JVM_STORAGE_REGISTER:
96 jvm_generate(p, cell_size, 0, "%cstore %i", prefix, dst -> reg);
97 break;
98 case JVM_STORAGE_STATIC:
99 case JVM_STORAGE_FIELD:
100 case JVM_STORAGE_LOCAL:
101 case JVM_STORAGE_VARPTR:
102 jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", prefix);
103 break;
104 default:
105 gen_error("jvm_generate_store: unknow storage type %i", dst -> storage);
106 break;
110 void
111 jvm_generate_and_init_global_var(struct gen_class * class, gen_var_t * v, char * name, gen_type_t * t)
113 assert(class -> p == NULL);
114 fprintf(class -> fp, ".field public static %s [%s\n\n", name, t -> desc);
116 v -> storage = JVM_STORAGE_STATIC;
117 v -> full_name = new_string("%s/%s", class -> full_name, name);
118 v -> type = t;
121 void
122 jvm_generate_and_init_field(struct gen_class * class, gen_var_t * v, char * name, gen_type_t * t)
124 assert(class -> p == NULL);
125 fprintf(class -> fp, ".field public %s [%s\n\n", name, t -> desc);
127 v -> storage = JVM_STORAGE_FIELD;
128 v -> full_name = new_string("%s/%s", class -> full_name, name);
129 v -> type = t;
132 void
133 jvm_generate_and_init_local_var(gen_proc_t * p, gen_var_t * v, gen_type_t * t)
135 v -> storage = JVM_STORAGE_REGISTER;
136 v -> reg = jvm_alloc_register_untyped(p -> rf, t -> wide);
137 v -> type = t;
140 void
141 jvm_generate_and_init_named_local_var(gen_proc_t * p, gen_var_t * v, char * name, gen_type_t * t)
143 jvm_generate_and_init_local_var(p, v, t);
144 jvm_generate(p, 0, 0, ".var %i is %s %s from start to end", v -> reg, name, t -> desc);
147 void
148 jvm_generate_and_init_var_param(gen_proc_t * p, gen_var_t * v, char * name, gen_type_t * t)
150 v -> storage = JVM_STORAGE_VARPTR;
151 v -> reg = jvm_alloc_register_untyped(p -> rf, true);
152 v -> type = t;
153 jvm_generate(p, 0, 0, ".var %i is %s [%s from start to end", v -> reg, name, t -> desc);
154 jvm_generate(p, 0, 0, ".var %i is __%s_offset I from start to end", v -> reg + 1, name);
157 void
158 jvm_generate_variable_initialization(gen_proc_t * p, gen_var_t * v)
160 if(v -> storage == JVM_STORAGE_STATIC)
162 jvm_generate(p, 0, 1, "iconst_1");
163 jvm_generate(p, 1, 1, "multianewarray [%s 1", v -> type -> desc);
164 jvm_generate(p, 1, 0, "putstatic %s [%s", v -> full_name, v -> type -> desc);
166 else if(v -> storage == JVM_STORAGE_FIELD)
168 jvm_generate(p, 0, 1, "iconst_1");
169 jvm_generate(p, 1, 1, "multianewarray [%s 1", v -> type -> desc);
170 jvm_generate(p, 1, 0, "putfield %s [%s", v -> full_name, v -> type -> desc);
174 void
175 jvm_generate_param_initialization(gen_proc_t * p, gen_var_t * v)
177 assert(v -> storage == JVM_STORAGE_REGISTER);
179 int old_reg = v -> reg;
180 bool wide = v -> type -> wide;
181 int cell_size = v -> type -> cell_size;
182 char prefix = v -> type -> prefix;
183 char * desc = v -> type -> desc;
185 v -> storage = JVM_STORAGE_LOCAL;
186 v -> reg = jvm_alloc_register_untyped(p -> rf, wide);
188 jvm_generate(p, 0, 1, "iconst_1");
189 jvm_generate(p, 1, 1, "multianewarray [%s 1", desc);
190 jvm_generate(p, 1, 2, "dup");
191 jvm_generate(p, 1, 0, "astore %i", v -> reg);
193 jvm_generate(p, 0, 1, "iconst_0");
194 jvm_generate(p, 0, cell_size, "%cload %i", prefix, old_reg);
195 jvm_generate(p, 1 + 1 + cell_size, 0, "%castore", prefix);