File Coverage

lib/SPVM/Builder/src/spvm_dumper.c
Criterion Covered Total %
statement 0 244 0.0
branch 0 108 0.0
condition n/a
subroutine n/a
pod n/a
total 0 352 0.0


line stmt bran cond sub pod time code
1             // Copyright (c) 2023 Yuki Kimoto
2             // MIT License
3              
4             #include
5             #include
6             #include
7             #include
8             #include
9              
10              
11             #include "spvm_compiler.h"
12             #include "spvm_dumper.h"
13             #include "spvm_list.h"
14             #include "spvm_hash.h"
15             #include "spvm_constant.h"
16             #include "spvm_field.h"
17             #include "spvm_method.h"
18             #include "spvm_var_decl.h"
19             #include "spvm_var.h"
20             #include "spvm_op.h"
21             #include "spvm_check.h"
22             #include "spvm_type.h"
23             #include "spvm_type.h"
24             #include "spvm_opcode.h"
25             #include "spvm_class_var.h"
26             #include "spvm_class_var_access.h"
27             #include "spvm_opcode_list.h"
28             #include "spvm_block.h"
29             #include "spvm_basic_type.h"
30             #include "spvm_field_access.h"
31              
32 0           void SPVM_DUMPER_dump_ast(SPVM_COMPILER* compiler, SPVM_OP* op_base) {
33 0           int32_t indent = 8;
34            
35             // Run OPs
36 0           SPVM_OP* op_cur = op_base;
37 0           int32_t finish = 0;
38 0 0         while (op_cur) {
39             // [START]Preorder traversal position
40             {
41             int32_t i;
42 0 0         for (i = 0; i < indent; i++) {
43 0           fprintf(stderr, " ");
44             }
45             }
46 0           int32_t id = op_cur->id;
47 0           fprintf(stderr, "%s", (SPVM_OP_C_ID_NAMES())[id]);
48 0 0         if (op_cur->id == SPVM_OP_C_ID_CONSTANT) {
49 0           SPVM_CONSTANT* constant = op_cur->uv.constant;
50 0 0         if (constant->type->dimension == 0) {
51 0           fprintf(stderr, " %s", (SPVM_BASIC_TYPE_C_ID_NAMES())[constant->type->basic_type->id]);
52 0           switch (constant->type->basic_type->id) {
53             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE:
54 0           fprintf(stderr, " %" PRId8, constant->value.bval);
55 0           break;
56             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT:
57 0           fprintf(stderr, " %" PRId16, constant->value.sval);
58 0           break;
59             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT:
60 0           fprintf(stderr, " %" PRId32, constant->value.ival);
61 0           break;
62             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG:
63 0           fprintf(stderr, " %" PRId64, constant->value.lval);
64 0           break;
65             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT:
66 0           fprintf(stderr, " %f", constant->value.fval);
67 0           break;
68             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE:
69 0           fprintf(stderr, " %f", constant->value.dval);
70 0           break;
71             }
72             }
73 0 0         else if (constant->type->dimension == 1 && constant->type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE) {
    0          
74 0           fprintf(stderr, " string \"%s\"\n", (char*)constant->value.oval);
75 0           break;
76             }
77             }
78 0 0         else if (id == SPVM_OP_C_ID_CLASS_VAR) {
79 0           SPVM_CLASS_VAR* class_var = op_cur->uv.class_var;
80 0           fprintf(stderr, " \"%s\"", class_var->name);
81 0           fprintf(stderr, " (index :%d)", class_var->index);
82             }
83 0 0         else if (id == SPVM_OP_C_ID_VAR) {
84 0           SPVM_VAR* var = op_cur->uv.var;
85 0           fprintf(stderr, " \"%s\"", var->name);
86 0 0         if (var->var_decl) {
87 0           fprintf(stderr, " (var_decl->index:%d) declaration : %d", var->var_decl->index, op_cur->uv.var->is_declaration);
88             }
89             else {
90 0           fprintf(stderr, " (var_decl->index:not yet resolved)");
91             }
92             }
93 0 0         else if (id == SPVM_OP_C_ID_CLASS_VAR_ACCESS) {
94 0           SPVM_CLASS_VAR_ACCESS* class_var_access = op_cur->uv.class_var_access;
95 0           fprintf(stderr, " \"%s\"", class_var_access->op_name->uv.name);
96 0           fprintf(stderr, " (index :%d)", class_var_access->class_var->index);
97             }
98 0 0         else if (id == SPVM_OP_C_ID_FIELD_ACCESS) {
99 0           SPVM_FIELD_ACCESS* field_access = op_cur->uv.field_access;
100 0 0         if (field_access->op_name) {
101 0           fprintf(stderr, " \"%s\"", field_access->op_name->uv.name);
102             }
103 0 0         if (field_access->field) {
104 0           fprintf(stderr, " (index :%d)", field_access->field->index);
105             }
106             }
107 0 0         else if (id == SPVM_OP_C_ID_NAME) {
108 0           fprintf(stderr, " \"%s\"", op_cur->uv.name);
109             }
110 0 0         else if (id == SPVM_OP_C_ID_TYPE) {
111 0 0         if (op_cur->uv.type) {
112 0           fprintf(stderr, " ");
113 0           fprintf(stderr, "%s", SPVM_TYPE_new_type_name(compiler, op_cur->uv.type->basic_type->id, op_cur->uv.type->dimension, op_cur->uv.type->flag));
114             }
115             else {
116 0           fprintf(stderr, " \"Unknown\"");
117             }
118             }
119 0 0         else if (id == SPVM_OP_C_ID_BLOCK) {
120 0 0         if (op_cur->uv.block->id == SPVM_BLOCK_C_ID_IF) {
121 0           fprintf(stderr, " IF");
122             }
123 0 0         else if (op_cur->uv.block->id == SPVM_BLOCK_C_ID_ELSE) {
124 0           fprintf(stderr, " ELSE");
125             }
126 0 0         else if (op_cur->uv.block->id == SPVM_BLOCK_C_ID_LOOP_INIT) {
127 0           fprintf(stderr, " LOOP_INIT");
128             }
129 0 0         else if (op_cur->uv.block->id == SPVM_BLOCK_C_ID_LOOP_STATEMENTS) {
130 0           fprintf(stderr, " LOOP_STATEMENTS");
131             }
132 0 0         else if (op_cur->uv.block->id == SPVM_BLOCK_C_ID_SWITCH) {
133 0           fprintf(stderr, " SWITCH");
134             }
135 0 0         else if (op_cur->uv.block->id == SPVM_BLOCK_C_ID_METHOD) {
136 0           fprintf(stderr, " METHOD");
137             }
138 0 0         else if (op_cur->uv.block->id == SPVM_BLOCK_C_ID_EVAL) {
139 0           fprintf(stderr, " EVAL");
140             }
141             }
142 0           fprintf(stderr, "\n");
143            
144             // [END]Preorder traversal position
145            
146 0 0         if (op_cur->first) {
147 0           op_cur = op_cur->first;
148 0           indent++;
149             }
150             else {
151             while (1) {
152             // [START]Postorder traversal position
153            
154             // [END]Postorder traversal position
155            
156 0 0         if (op_cur == op_base) {
157 0           finish = 1;
158 0           break;
159             }
160            
161             // Next sibling
162 0 0         if (op_cur->moresib) {
163 0           op_cur = SPVM_OP_sibling(compiler, op_cur);
164 0           break;
165             }
166             // Next is parent
167             else {
168 0           op_cur = op_cur->sibparent;
169 0           indent--;
170             }
171 0           }
172 0 0         if (finish) {
173 0           break;
174             }
175             }
176             }
177 0           }
178              
179 0           void SPVM_DUMPER_dump_basic_types(SPVM_COMPILER* compiler, SPVM_LIST* basic_types) {
180 0 0         for (int32_t i = 0; i < basic_types->length; i++) {
181 0           fprintf(stderr, "basic_types[%" PRId32 "]\n", i);
182 0           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(basic_types, i);
183            
184 0           fprintf(stderr, " name => \"%s\"\n", basic_type->name);
185            
186 0 0         if (strncmp(basic_type->name, "SPVM", 4) == 0) {
187 0           fprintf(stderr, " (omit)\n");
188 0           continue;
189             }
190            
191             // Field information
192 0           fprintf(stderr, " fields\n");
193 0           SPVM_LIST* fields = basic_type->unmerged_fields;
194             {
195             int32_t j;
196 0 0         for (j = 0; j < fields->length; j++) {
197 0           SPVM_FIELD* field = SPVM_LIST_get(fields, j);
198 0           fprintf(stderr, " fields[%" PRId32 "]\n", j);
199 0           SPVM_DUMPER_dump_field(compiler, field);
200             }
201             }
202             {
203             int32_t j;
204 0 0         for (j = 0; j < basic_type->methods->length; j++) {
205 0           SPVM_METHOD* method = SPVM_LIST_get(basic_type->methods, j);
206 0           fprintf(stderr, " methods[%" PRId32 "]\n", j);
207 0           SPVM_DUMPER_dump_method(compiler, method);
208             }
209             }
210             }
211 0           }
212              
213 0           void SPVM_DUMPER_dump_basic_types_opcode_list(SPVM_COMPILER* compiler, SPVM_LIST* basic_types) {
214 0 0         for (int32_t i = 0; i < basic_types->length; i++) {
215 0           fprintf(stderr, "basic_types[%" PRId32 "]\n", i);
216 0           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(basic_types, i);
217            
218 0           fprintf(stderr, " name => \"%s\"\n", basic_type->name);
219            
220 0 0         if (strncmp(basic_type->name, "SPVM", 4) == 0) {
221 0           fprintf(stderr, " (omit)\n");
222 0           continue;
223             }
224            
225             {
226             int32_t j;
227 0 0         for (j = 0; j < basic_type->methods->length; j++) {
228 0           SPVM_METHOD* method = SPVM_LIST_get(basic_type->methods, j);
229 0           fprintf(stderr, " methods[%" PRId32 "]\n", j);
230 0           SPVM_DUMPER_dump_method_opcode_list(compiler, method);
231             }
232             }
233             }
234 0           }
235              
236 0           void SPVM_DUMPER_dump_opcode_list(SPVM_COMPILER* compiler, SPVM_OPCODE_LIST* opcode_list) {
237            
238 0 0         for (int32_t i = 0; i <= opcode_list->length; i++) {
239            
240 0           SPVM_OPCODE opcode = opcode_list->values[i];
241 0           fprintf(stderr, " [%" PRId32 "] %-20s", i, (SPVM_OPCODE_C_ID_NAMES())[opcode.id]);
242 0           fprintf(stderr, " %d %d %d %d\n", opcode.operand0, opcode.operand1, opcode.operand2, opcode.operand3);
243             }
244 0           }
245              
246 0           void SPVM_DUMPER_dump_constant(SPVM_COMPILER* compiler, SPVM_CONSTANT* constant) {
247            
248 0 0         if (constant->type->dimension == 0) {
249 0           switch(constant->type->basic_type->id) {
250             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE:
251 0           fprintf(stderr, " int %" PRId8 "\n", constant->value.bval);
252 0           break;
253             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT:
254 0           fprintf(stderr, " int %" PRId16 "\n", constant->value.sval);
255 0           break;
256             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT:
257 0           fprintf(stderr, " int %" PRId32 "\n", constant->value.ival);
258 0           break;
259             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG:
260 0           fprintf(stderr, " long %" PRId64 "\n", constant->value.lval);
261 0           break;
262             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT:
263 0           fprintf(stderr, " float %f\n", constant->value.fval);
264 0           break;
265             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE:
266 0           fprintf(stderr, " double %f\n", constant->value.dval);
267 0           break;
268             }
269             }
270 0 0         else if (constant->type->dimension == 1) {
271 0 0         if (constant->type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE) {
272 0           fprintf(stderr, " String \"%s\"\n", (char*)constant->value.oval);
273             }
274             }
275 0           }
276              
277 0           void SPVM_DUMPER_dump_method(SPVM_COMPILER* compiler, SPVM_METHOD* method) {
278            
279 0 0         if (method) {
280            
281 0           const char* name = "";
282 0 0         if (method->op_name) {
283 0           name = method->op_name->uv.name;
284             }
285            
286 0           fprintf(stderr, " name => \"%s\"\n", name);
287 0           fprintf(stderr, " return_type => ");
288 0           fprintf(stderr, "%s", SPVM_TYPE_new_type_name(compiler, method->return_type->basic_type->id, method->return_type->dimension, method->return_type->flag));
289 0           fprintf(stderr, "\n");
290 0           fprintf(stderr, " is_enum => %d\n", method->is_enum);
291 0           fprintf(stderr, " is_native => %d\n", method->is_native);
292 0           fprintf(stderr, " is_precompile => %d\n", method->is_precompile);
293 0 0         if (method->op_block) {
294 0           fprintf(stderr, " var_decls\n");
295 0           SPVM_LIST* var_decls = method->var_decls;
296             {
297             int32_t i;
298 0 0         for (i = 0; i < var_decls->length; i++) {
299 0           SPVM_VAR_DECL* var_decl = SPVM_LIST_get(method->var_decls, i);
300 0           fprintf(stderr, " var_decls[%" PRId32 "] ", i);
301 0           SPVM_DUMPER_dump_var_decl(compiler, var_decl);
302             }
303             }
304            
305 0           fprintf(stderr, " AST\n");
306 0           SPVM_DUMPER_dump_ast(compiler, method->op_block);
307 0           fprintf(stderr, "\n");
308             }
309             }
310             else {
311 0           fprintf(stderr, " None\n");
312             }
313 0           }
314              
315 0           void SPVM_DUMPER_dump_method_opcode_list(SPVM_COMPILER* compiler, SPVM_METHOD* method) {
316            
317 0 0         if (method) {
318 0           fprintf(stderr, " name => \"%s\"\n", method->name);
319 0 0         if (method->op_block) {
320 0           fprintf(stderr, " var_decls\n");
321 0           SPVM_LIST* var_decls = method->var_decls;
322             {
323             int32_t i;
324 0 0         for (i = 0; i < var_decls->length; i++) {
325 0           SPVM_VAR_DECL* var_decl = SPVM_LIST_get(method->var_decls, i);
326 0           fprintf(stderr, " var_decls[%" PRId32 "] ", i);
327 0           SPVM_DUMPER_dump_var_decl(compiler, var_decl);
328             }
329             }
330            
331 0           fprintf(stderr, " opcode_list\n");
332 0           SPVM_DUMPER_dump_opcode_list(compiler, method->opcode_list);
333             }
334             }
335             else {
336 0           fprintf(stderr, " None\n");
337             }
338 0           }
339              
340 0           void SPVM_DUMPER_dump_field(SPVM_COMPILER* compiler, SPVM_FIELD* field) {
341            
342 0 0         if (field) {
343 0           fprintf(stderr, " name => \"%s\"\n", field->name);
344            
345 0           fprintf(stderr, " index => \"%" PRId32 "\"\n", field->index);
346            
347 0           SPVM_TYPE* type = field->type;
348 0           fprintf(stderr, " type => ");
349 0           fprintf(stderr, "%s", SPVM_TYPE_new_type_name(compiler, type->basic_type->id, type->dimension, type->flag));
350 0           fprintf(stderr, "\n");
351 0           fprintf(stderr, " offset => \"%" PRId32 "\"\n", field->offset);
352             }
353             else {
354 0           fprintf(stderr, " None\n");
355             }
356 0           }
357              
358              
359 0           void SPVM_DUMPER_dump_var_decl(SPVM_COMPILER* compiler, SPVM_VAR_DECL* var_decl) {
360            
361 0 0         if (var_decl) {
362 0           fprintf(stderr, "\n");
363 0           fprintf(stderr, " name => %s\n", var_decl->var->name);
364 0           fprintf(stderr, " type => ");
365 0           SPVM_TYPE* type = var_decl->type;
366 0           fprintf(stderr, "%s", SPVM_TYPE_new_type_name(compiler, type->basic_type->id, type->dimension, type->flag));
367 0           fprintf(stderr, "\n");
368 0           fprintf(stderr, " id => %d\n", var_decl->index);
369 0           fprintf(stderr, " call_stack_index => ");
370            
371 0 0         if (SPVM_TYPE_is_numeric_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
372 0           SPVM_TYPE* numeric_type = SPVM_CHECK_get_type(compiler, var_decl->op_var_decl);
373 0           switch(numeric_type->basic_type->id) {
374             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
375 0           fprintf(stderr, "byte");
376 0           break;
377             }
378             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
379 0           fprintf(stderr, "short");
380 0           break;
381             }
382             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
383 0           fprintf(stderr, "int");
384 0           break;
385             }
386             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
387 0           fprintf(stderr, "long");
388 0           break;
389             }
390             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
391 0           fprintf(stderr, "float");
392 0           break;
393             }
394             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
395 0           fprintf(stderr, "double");
396 0           break;
397             }
398             }
399             }
400 0 0         else if (SPVM_TYPE_is_object_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
401 0           fprintf(stderr, "object");
402             }
403 0 0         else if (SPVM_TYPE_is_ref_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
404 0           fprintf(stderr, "ref");
405             }
406 0 0         else if (SPVM_TYPE_is_mulnum_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
407 0           SPVM_FIELD* first_field = SPVM_LIST_get(type->basic_type->unmerged_fields, 0);
408 0 0         assert(first_field);
409            
410 0           SPVM_TYPE* field_type = SPVM_CHECK_get_type(compiler, first_field->op_field);
411 0 0         assert(SPVM_TYPE_is_numeric_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag));
412            
413 0           switch (field_type->basic_type->id) {
414             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
415 0           fprintf(stderr, "byte");
416 0           break;
417             }
418             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
419 0           fprintf(stderr, "short");
420 0           break;
421             }
422             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
423 0           fprintf(stderr, "int");
424 0           break;
425             }
426             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
427 0           fprintf(stderr, "long");
428 0           break;
429             }
430             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
431 0           fprintf(stderr, "float");
432 0           break;
433             }
434             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
435 0           fprintf(stderr, "double");
436 0           break;
437             }
438             default: {
439 0           assert(0);
440             }
441             }
442             }
443            
444 0           fprintf(stderr, " %d\n", var_decl->runtime_var_index);
445             }
446             else {
447 0           fprintf(stderr, " (Unexpected)\n");
448             }
449 0           }