File Coverage

lib/SPVM/Builder/src/spvm_compiler.c
Criterion Covered Total %
statement 602 620 97.1
branch 123 148 83.1
condition n/a
subroutine n/a
pod n/a
total 725 768 94.4


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              
9             #include "spvm_compiler.h"
10             #include "spvm_type.h"
11             #include "spvm_op.h"
12             #include "spvm_hash.h"
13             #include "spvm_list.h"
14             #include "spvm_allocator.h"
15             #include "spvm_yacc_util.h"
16             #include "spvm_list.h"
17             #include "spvm_opcode_list.h"
18             #include "spvm_method.h"
19             #include "spvm_field.h"
20             #include "spvm_class_var.h"
21             #include "spvm_native.h"
22             #include "spvm_opcode.h"
23             #include "spvm_basic_type.h"
24             #include "spvm_use.h"
25             #include "spvm_check.h"
26             #include "spvm_opcode_builder.h"
27             #include "spvm_object.h"
28             #include "spvm_var_decl.h"
29             #include "spvm_string_buffer.h"
30             #include "spvm_allow.h"
31             #include "spvm_interface.h"
32             #include "spvm_class_var_access.h"
33             #include "spvm_constant.h"
34             #include "spvm_array_field_access.h"
35             #include "spvm_field_access.h"
36             #include "spvm_call_method.h"
37             #include "spvm_var.h"
38             #include "spvm_string.h"
39             #include "spvm_class_file.h"
40             #include "spvm_mutex.h"
41              
42             #include "spvm_api.h"
43             #include "spvm_api_runtime.h"
44             #include "spvm_runtime.h"
45             #include "spvm_runtime_basic_type.h"
46             #include "spvm_runtime_class_var.h"
47             #include "spvm_runtime_field.h"
48             #include "spvm_runtime_arg.h"
49             #include "spvm_runtime.h"
50             #include "spvm_runtime_method.h"
51             #include "spvm_runtime_string.h"
52             #include "spvm_runtime_arg.h"
53              
54 1501           SPVM_COMPILER* SPVM_COMPILER_new() {
55 1501           SPVM_COMPILER* compiler = SPVM_ALLOCATOR_alloc_memory_block_unmanaged(sizeof(SPVM_COMPILER));
56            
57 1501           compiler->global_allocator = SPVM_ALLOCATOR_new();
58 1501           compiler->each_compile_allocators = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
59 1501           compiler->error_message_allocator = SPVM_ALLOCATOR_new();
60 1501           compiler->class_file_allocator = SPVM_ALLOCATOR_new();
61            
62 1501           compiler->ch_ptr = "";
63            
64 1501           compiler->constant_strings = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
65 1501           compiler->constant_string_symtable = SPVM_HASH_new_hash_permanent(compiler->global_allocator, 0);
66            
67 1501           compiler->global_strings = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
68 1501           compiler->global_string_symtable = SPVM_HASH_new_hash_permanent(compiler->global_allocator, 0);
69            
70 1501           compiler->basic_types = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
71 1501           compiler->basic_type_symtable = SPVM_HASH_new_hash_permanent(compiler->global_allocator, 0);
72            
73 1501           compiler->class_files = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
74 1501           compiler->class_file_class_names = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
75            
76 1501           compiler->include_dirs = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
77            
78 1501           compiler->error_messages = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
79            
80 1501           compiler->ops = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
81 1501           compiler->op_use_stack = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
82 1501           compiler->op_types = SPVM_LIST_new_list_permanent(compiler->global_allocator, 0);
83            
84 1501           compiler->runtime = SPVM_RUNTIME_new();
85            
86 1501           int32_t compiler_mutex_compile_size = SPVM_MUTEX_size();
87 1501           void* compiler_mutex_compile = SPVM_ALLOCATOR_alloc_memory_block_permanent(compiler->global_allocator, compiler_mutex_compile_size);
88            
89 1501           SPVM_MUTEX_init(compiler_mutex_compile);
90            
91 1501           compiler->mutex_compile = compiler_mutex_compile;
92            
93 1501           return compiler;
94             }
95              
96 1155           void SPVM_COMPILER_free(SPVM_COMPILER* compiler) {
97            
98 1155           SPVM_COMPILER_clear_error_messages(compiler);
99            
100 1155           SPVM_COMPILER_set_start_file(compiler, NULL);
101            
102 1155           SPVM_COMPILER_clear_include_dirs(compiler);
103            
104 1155 50         if (compiler->runtime) {
105 1155           SPVM_RUNTIME_free(compiler->runtime);
106 1155           compiler->runtime = NULL;
107             }
108            
109 3442 100         for (int32_t i = 0; i < compiler->each_compile_allocators->length; i++) {
110 2287           SPVM_ALLOCATOR* each_compile_allocator = SPVM_LIST_get(compiler->each_compile_allocators, i);
111 2287           SPVM_ALLOCATOR_free(each_compile_allocator);
112             }
113            
114 1155           SPVM_ALLOCATOR_free(compiler->error_message_allocator);
115 1155           compiler->error_message_allocator = NULL;
116            
117 1155           int32_t found = 0;
118 19569 100         for (int32_t i = 0; i < compiler->class_file_class_names->length; i++) {
119 18414           SPVM_CLASS_FILE* class_file_class_name = SPVM_LIST_get(compiler->class_file_class_names, i);
120 18414 50         if (class_file_class_name) {
121 18414           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->class_file_allocator, compiler->class_file_class_names->values[i]);
122 18414           compiler->class_file_class_names->values[i] = NULL;
123             }
124             }
125 19569 100         for (int32_t i = 0; i < compiler->class_files->length; i++) {
126 18414           SPVM_CLASS_FILE* class_file = SPVM_LIST_get(compiler->class_files, i);
127 18414 50         if (class_file) {
128 18414           SPVM_COMPILER_free_class_file(compiler, compiler->class_files->values[i]);
129 18414           compiler->class_files->values[i] = NULL;
130             }
131             }
132            
133 1155           SPVM_ALLOCATOR_free(compiler->class_file_allocator);
134 1155           compiler->class_file_allocator = NULL;
135            
136 1155           SPVM_MUTEX_destroy(compiler->mutex_compile);
137            
138 1155           SPVM_ALLOCATOR_free(compiler->global_allocator);
139 1155           compiler->global_allocator = NULL;
140 1155           }
141              
142 3670           int32_t SPVM_COMPILER_compile(SPVM_COMPILER* compiler, const char* basic_type_name) {
143            
144 3670           SPVM_MUTEX* compiler_mutex_compile = compiler->mutex_compile;
145            
146 3670           SPVM_MUTEX_lock(compiler_mutex_compile);
147            
148 3670           compiler->current_each_compile_allocator = SPVM_ALLOCATOR_new();
149            
150 3670           SPVM_COMPILER_clear_error_messages(compiler);
151            
152 3670           int32_t compile_start_memory_blocks_count_tmp = compiler->current_each_compile_allocator->memory_blocks_count_tmp;
153            
154 3670           compiler->if_require_not_found_basic_type_name_symtable = SPVM_HASH_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
155            
156 3670           int32_t compiler_basic_types_base_id = compiler->basic_types->length;
157            
158 3670           compiler->basic_types_base_id = compiler_basic_types_base_id;
159            
160 3670           int32_t compiler_constant_strings_base_id = compiler->constant_strings->length;
161            
162 3670           compiler->constant_strings_base_id = compiler_constant_strings_base_id;
163            
164 3670 100         if (compiler->basic_types->length == 0) {
165 1501           SPVM_COMPILER_add_basic_types(compiler);
166            
167 1501           SPVM_COMPILER_set_default_loaded_class_files(compiler);
168             }
169            
170 3670           SPVM_COMPILER_use_default_loaded_classes(compiler);
171            
172 3670 100         if (basic_type_name) {
173 3334           SPVM_STRING* basic_type_name_string = SPVM_STRING_new(compiler, basic_type_name, strlen(basic_type_name));
174 3334           basic_type_name = basic_type_name_string->value;
175 3334           const char* start_file = SPVM_COMPILER_get_start_file(compiler);
176 3334           int32_t start_line = SPVM_COMPILER_get_start_line(compiler);
177            
178 3334           SPVM_COMPILER_use(compiler, basic_type_name, start_file, start_line);
179             }
180            
181             #ifdef SPVM_DEBUG_YACC
182             SPVM_yydebug = 1;
183             #else
184 3670           SPVM_yydebug = 0;
185             #endif
186              
187 3670           compiler->end_of_file = 1;
188            
189 3670           int32_t yyparse_error_id = SPVM_yyparse(compiler);
190            
191 3670           SPVM_COMPILER_assert_check_basic_type_ids(compiler);
192            
193 3670           int32_t error_id = 0;
194            
195 3670 100         if (yyparse_error_id) {
196 63           error_id = SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_CLASS;
197             }
198             else {
199 3607 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
200 115           error_id = SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_CLASS;
201             }
202             else {
203 3492           SPVM_CHECK_check(compiler);
204 3492 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
205 373           error_id = SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_CLASS;
206             }
207             else {
208 3119           int32_t build_opcode_list_start_memory_blocks_count_tmp = compiler->current_each_compile_allocator->memory_blocks_count_tmp;
209 3119           SPVM_OPCODE_BUILDER_build_opcode_list(compiler);
210 3119 50         assert(compiler->current_each_compile_allocator->memory_blocks_count_tmp == build_opcode_list_start_memory_blocks_count_tmp);
211 3119 50         assert(SPVM_COMPILER_get_error_messages_length(compiler) == 0);
212             }
213             }
214             }
215            
216 3670           SPVM_COMPILER_free_memory_tmp_each_compile(compiler);
217            
218 3670 50         assert(compiler->current_each_compile_allocator->memory_blocks_count_tmp == compile_start_memory_blocks_count_tmp);
219            
220 3670 100         if (error_id) {
221 14285 100         for (int32_t basic_type_id = compiler_basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
222 13734           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
223            
224 13734           SPVM_CLASS_FILE* found_class_file = SPVM_COMPILER_get_class_file(compiler, basic_type->name);
225 13734 100         if (found_class_file) {
226 7545           SPVM_COMPILER_delete_class_file(compiler, basic_type->name);
227             }
228            
229 13734           SPVM_HASH_set(compiler->basic_type_symtable, basic_type->name, strlen(basic_type->name), NULL);
230             }
231 551           compiler->basic_types->length = compiler_basic_types_base_id;
232            
233 41407 100         for (int32_t constant_string_id = compiler_constant_strings_base_id; constant_string_id < compiler->constant_strings->length; constant_string_id++) {
234 40856           SPVM_BASIC_TYPE* constant_string = SPVM_LIST_get(compiler->constant_strings, constant_string_id);
235 40856           SPVM_HASH_set(compiler->constant_string_symtable, constant_string->name, strlen(constant_string->name), NULL);
236             }
237 551           compiler->constant_strings->length = compiler_constant_strings_base_id;
238            
239 551           SPVM_ALLOCATOR_free(compiler->current_each_compile_allocator);
240 551           compiler->current_each_compile_allocator = NULL;
241             }
242             else {
243 3119           SPVM_LIST_push(compiler->each_compile_allocators, compiler->current_each_compile_allocator);
244 3119           compiler->current_each_compile_allocator = NULL;
245            
246 3119           SPVM_COMPILER_build_runtime(compiler);
247             }
248            
249 3670           SPVM_MUTEX_unlock(compiler_mutex_compile);
250            
251 3670           return error_id;
252             }
253              
254 4825           void SPVM_COMPILER_clear_error_messages(SPVM_COMPILER* compiler) {
255            
256 4825           SPVM_LIST* error_messages = compiler->error_messages;
257            
258 5440 100         for (int32_t i = 0; i < error_messages->length; i++) {
259 615           const char* error_message = SPVM_LIST_get(error_messages, i);
260            
261 615           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->error_message_allocator, (void*)error_message);
262 615           error_message = NULL;
263             }
264            
265 4825           error_messages->length = 0;
266 4825           }
267              
268 34935           void SPVM_COMPILER_add_class_file(SPVM_COMPILER* compiler, const char* class_name) {
269            
270 34935           SPVM_CLASS_FILE* class_file = SPVM_COMPILER_get_class_file(compiler, class_name);
271            
272 34935 50         if (!class_file) {
273 34935           class_file = SPVM_ALLOCATOR_alloc_memory_block_tmp(compiler->class_file_allocator, sizeof(SPVM_CLASS_FILE));
274 34935           class_file->class_name = class_name;
275 34935           SPVM_COMPILER_set_class_file(compiler, class_name, class_file);
276             }
277 34935           }
278              
279 7545           void SPVM_COMPILER_delete_class_file(SPVM_COMPILER* compiler, const char* class_name) {
280            
281 7545           int32_t found = 0;
282 7545           int32_t found_index = -1;
283 20745 50         for (int32_t i = 0; i < compiler->class_file_class_names->length; i++) {
284 20745           const char* class_file_class_name = SPVM_LIST_get(compiler->class_file_class_names, i);
285 20745 100         if (strcmp(class_name, class_file_class_name) == 0) {
286 7545 50         if (compiler->class_files->values[i]) {
287            
288 7545           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->class_file_allocator, compiler->class_file_class_names->values[i]);
289 7545           compiler->class_file_class_names->values[i] = NULL;
290            
291 7545           SPVM_COMPILER_free_class_file(compiler, compiler->class_files->values[i]);
292 7545           compiler->class_files->values[i] = NULL;
293             }
294 7545           found_index = i;
295 7545           found = 1;
296 7545           break;
297             }
298             }
299            
300 7545 50         if (found_index >= 0) {
301 7545 100         if (found_index < compiler->class_file_class_names->length - 1) {
302 7059           int32_t move_length = compiler->class_file_class_names->length - 1 - found_index;
303 7059           memmove(compiler->class_file_class_names->values + found_index, compiler->class_file_class_names->values + found_index + 1, sizeof(void*) * move_length);
304 7059           memmove(compiler->class_files->values + found_index, compiler->class_files->values + found_index + 1, sizeof(void*) * move_length);
305             }
306            
307 7545           compiler->class_file_class_names->length--;
308 7545           compiler->class_files->length--;
309             }
310 7545           }
311              
312 34935           void SPVM_COMPILER_set_class_file(SPVM_COMPILER* compiler, const char* class_name, SPVM_CLASS_FILE* class_file) {
313            
314 34935           int32_t found = 0;
315 553130 100         for (int32_t i = 0; i < compiler->class_file_class_names->length; i++) {
316 518195           const char* class_file_class_name = SPVM_LIST_get(compiler->class_file_class_names, i);
317 518195 50         if (strcmp(class_name, class_file_class_name) == 0) {
318 0 0         if (compiler->class_files->values[i]) {
319            
320 0           SPVM_COMPILER_free_class_file(compiler, compiler->class_files->values[i]);
321 0           compiler->class_files->values[i] = NULL;
322             }
323 0           compiler->class_files->values[i] = class_file;
324 0           found = 1;
325 0           break;
326             }
327             }
328            
329 34935 50         if (!found) {
330 34935           const char* class_name_clone = SPVM_ALLOCATOR_alloc_memory_block_tmp(compiler->class_file_allocator, strlen(class_name) + 1);
331 34935           memcpy((void*)class_name_clone, class_name, strlen(class_name));
332 34935           SPVM_LIST_push(compiler->class_file_class_names, (void*)class_name_clone);
333 34935           SPVM_LIST_push(compiler->class_files, (void*)class_file);
334             }
335 34935           }
336              
337 170512           SPVM_CLASS_FILE* SPVM_COMPILER_get_class_file(SPVM_COMPILER* compiler, const char* class_name) {
338            
339 170512           SPVM_CLASS_FILE* found_class_file = NULL;
340 2762742 100         for (int32_t i = 0; i < compiler->class_file_class_names->length; i++) {
341 2687758           const char* class_file_class_name = SPVM_LIST_get(compiler->class_file_class_names, i);
342            
343 2687758 100         if (strcmp(class_name, class_file_class_name) == 0) {
344 95528           found_class_file = SPVM_LIST_get(compiler->class_files, i);
345 95528           break;
346             }
347             }
348            
349 170512           return found_class_file;
350             }
351              
352 25959           void SPVM_COMPILER_free_class_file(SPVM_COMPILER* compiler, SPVM_CLASS_FILE* class_file) {
353            
354 25959 50         assert(class_file);
355            
356 25959           SPVM_CLASS_FILE_set_file(compiler, class_file, NULL);
357            
358 25959           SPVM_CLASS_FILE_set_dir(compiler, class_file, NULL);
359            
360 25959           SPVM_CLASS_FILE_set_rel_file(compiler, class_file, NULL);
361            
362 25959           SPVM_CLASS_FILE_set_content(compiler, class_file, NULL);
363            
364 25959           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->class_file_allocator, class_file);
365 25959           }
366              
367 16511           void SPVM_COMPILER_add_basic_type_core(SPVM_COMPILER* compiler, int32_t basic_type_id, int32_t basic_type_category) {
368 16511           const char* basic_type_name = SPVM_BASIC_TYPE_get_basic_type_name(compiler, basic_type_id);
369 16511           SPVM_BASIC_TYPE* basic_type = SPVM_COMPILER_add_basic_type(compiler, basic_type_name);
370 16511 50         assert(basic_type->id == basic_type_id);
371 16511           basic_type->category = basic_type_category;
372 16511           }
373              
374 59596           SPVM_BASIC_TYPE* SPVM_COMPILER_add_basic_type(SPVM_COMPILER* compiler, const char* basic_type_name) {
375            
376 59596           SPVM_BASIC_TYPE* basic_type = SPVM_HASH_get(compiler->basic_type_symtable, basic_type_name, strlen(basic_type_name));
377            
378 59596 50         if (!basic_type) {
379 59596           basic_type = SPVM_BASIC_TYPE_new(compiler);
380 59596           basic_type->id = compiler->basic_types->length;
381 59596           SPVM_STRING* basic_type_name_string = SPVM_STRING_new(compiler, basic_type_name, strlen(basic_type_name));
382 59596           basic_type->name = basic_type_name_string->value;
383 59596           SPVM_LIST_push(compiler->basic_types, basic_type);
384 59596           SPVM_HASH_set(compiler->basic_type_symtable, basic_type->name, strlen(basic_type->name), basic_type);
385             }
386            
387 59596           return basic_type;
388             }
389              
390 1501           void SPVM_COMPILER_add_basic_types(SPVM_COMPILER* compiler) {
391             // Add basic_types
392 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_UNKNOWN, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_UNKNOWN);
393 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_UNDEF, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_UNDEF);
394 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_VOID, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_VOID);
395 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_NUMERIC);
396 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_NUMERIC);
397 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_INT, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_NUMERIC);
398 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_LONG, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_NUMERIC);
399 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_NUMERIC);
400 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_NUMERIC);
401 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_STRING, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_STRING);
402 1501           SPVM_COMPILER_add_basic_type_core(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_ANY_OBJECT, SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_ANY_OBJECT);
403 1501           }
404              
405 6499174           int32_t SPVM_COMPILER_get_error_messages_length(SPVM_COMPILER* compiler) {
406            
407 6499174           return compiler->error_messages->length;
408             }
409              
410 618           const char* SPVM_COMPILER_get_error_message(SPVM_COMPILER* compiler, int32_t index) {
411            
412 618           const char* error_message = (const char*)SPVM_LIST_get(compiler->error_messages, index);
413            
414 618           return error_message;
415             }
416              
417 0           void SPVM_COMPILER_print_error_messages(SPVM_COMPILER* compiler, FILE* fh) {
418            
419 0 0         for (int32_t i = 0; i < compiler->error_messages->length; i++) {
420 0           const char* error_message = (const char*)SPVM_LIST_get(compiler->error_messages, i);
421 0           fprintf(fh, "[CompileError]%s\n", error_message);
422             }
423 0           }
424              
425 47374           void SPVM_COMPILER_use(SPVM_COMPILER* compiler, const char* basic_type_name, const char* file, int32_t line) {
426 47374           SPVM_OP* op_name_basic_type = SPVM_OP_new_op_name(compiler, basic_type_name, file, line);
427 47374           SPVM_OP* op_type_class = SPVM_OP_build_basic_type(compiler, op_name_basic_type);
428 47374           SPVM_OP* op_use = SPVM_OP_new_op_use(compiler, op_name_basic_type->file, op_name_basic_type->line);
429 47374           SPVM_OP* op_name_alias = NULL;
430 47374           int32_t is_require = 0;
431 47374           SPVM_OP_build_use(compiler, op_use, op_type_class, op_name_alias, is_require);
432 47374           SPVM_LIST_push(compiler->op_use_stack, op_use);
433 47374           }
434              
435 0           const char* SPVM_COMPILER_get_runtime_name(SPVM_HASH* runtime_constant_string_symtable, const char* name) {
436            
437 0           SPVM_RUNTIME_STRING* string = SPVM_HASH_get(runtime_constant_string_symtable, name, strlen(name));
438            
439 0           const char* new_name = string->value;
440            
441 0           return new_name;
442             }
443              
444 3670           void SPVM_COMPILER_use_default_loaded_classes(SPVM_COMPILER* compiler) {
445             // Use automatically loaded classes
446 3670           SPVM_COMPILER_use(compiler, "Byte", "Byte", 0);
447 3670           SPVM_COMPILER_use(compiler, "Short", "Short", 0);
448 3670           SPVM_COMPILER_use(compiler, "Int", "Int", 0);
449 3670           SPVM_COMPILER_use(compiler, "Long", "Long", 0);
450 3670           SPVM_COMPILER_use(compiler, "Float", "Float", 0);
451 3670           SPVM_COMPILER_use(compiler, "Double", "Double", 0);
452 3670           SPVM_COMPILER_use(compiler, "Bool", "Bool", 0);
453 3670           SPVM_COMPILER_use(compiler, "Error", "Error", 0);
454 3670           SPVM_COMPILER_use(compiler, "Error::System", "Error::System", 0);
455 3670           SPVM_COMPILER_use(compiler, "Error::NotSupported", "Error::NotSupported", 0);
456 3670           SPVM_COMPILER_use(compiler, "CommandInfo", "CommandInfo", 0);
457 3670           SPVM_COMPILER_use(compiler, "Address", "Address", 0);
458 3670           }
459              
460 1501           void SPVM_COMPILER_set_default_loaded_class_files(SPVM_COMPILER* compiler) {
461             // Add Bool class file
462             {
463 1501           const char* class_name = "Bool";
464 1501           const char* rel_file = "Bool.spvm";
465 1501           const char* content = "class Bool {\n INIT {\n $TRUE = new Bool;\n $TRUE->{value} = 1;\n $FALSE = new Bool;\n $FALSE->{value} = 0;\n }\n \n our $TRUE : ro Bool;\n our $FALSE : ro Bool;\n has value : ro int;\n}";
466 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
467             }
468            
469             // Add Error class file
470             {
471 1501           const char* class_name = "Error";
472 1501           const char* rel_file = "Error.spvm";
473 1501           const char* content = "class Error;";
474 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
475             }
476            
477             // Add Error::System class file
478             {
479 1501           const char* class_name = "Error::System";
480 1501           const char* rel_file = "Error/System.spvm";
481 1501           const char* content = "class Error::System extends Error;";
482 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
483             }
484            
485             // Add Error::NotSupported class file
486             {
487 1501           const char* class_name = "Error::NotSupported";
488 1501           const char* rel_file = "Error/NotSupported.spvm";
489 1501           const char* content = "class Error::NotSupported extends Error;";
490 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
491             }
492            
493             // Add Byte class file
494             {
495 1501           const char* class_name = "Byte";
496 1501           const char* rel_file = "Byte.spvm";
497 1501           const char* content = "class Byte {\n has value : ro byte;\n static method new : Byte ($value : int) {\n my $self = new Byte;\n $self->{value} = (byte)$value;\n return $self;\n }\n}";
498 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
499             }
500            
501             // Add Short class file
502             {
503 1501           const char* class_name = "Short";
504 1501           const char* rel_file = "Short.spvm";
505 1501           const char* content = "class Short {\n has value : ro short;\n static method new : Short ($value : int) {\n my $self = new Short;\n $self->{value} = (short)$value;\n return $self;\n }\n}";
506 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
507             }
508            
509             // Add Int class file
510             {
511 1501           const char* class_name = "Int";
512 1501           const char* rel_file = "Int.spvm";
513 1501           const char* content = "class Int {\n has value : ro int;\n static method new : Int ($value : int) {\n my $self = new Int;\n $self->{value} = $value;\n return $self;\n }\n}";
514 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
515             }
516            
517             // Add Long class file
518             {
519 1501           const char* class_name = "Long";
520 1501           const char* rel_file = "Long.spvm";
521 1501           const char* content = "class Long {\n has value : ro long;\n static method new : Long ($value : long) {\n my $self = new Long;\n $self->{value} = $value;\n return $self;\n }\n}";
522 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
523             }
524            
525             // Add Float class file
526             {
527 1501           const char* class_name = "Float";
528 1501           const char* rel_file = "Float.spvm";
529 1501           const char* content = "class Float {\n has value : ro float;\n static method new : Float ($value : float) {\n my $self = new Float;\n $self->{value} = $value;\n return $self;\n }\n}";
530 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
531             }
532            
533             // Add Double class file
534             {
535 1501           const char* class_name = "Double";
536 1501           const char* rel_file = "Double.spvm";
537 1501           const char* content = "class Double {\n has value : ro double;\n static method new : Double ($value : double) {\n my $self = new Double;\n $self->{value} = $value;\n return $self;\n }\n}";
538 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
539             }
540            
541             // Add CommandInfo class file
542             {
543 1501           const char* class_name = "CommandInfo";
544 1501           const char* rel_file = "CommandInfo.spvm";
545 1501           const char* content = "class CommandInfo {\n our $PROGRAM_NAME : ro string;\n our $ARGV : ro string[];\n our $BASE_TIME : ro long;\n }";
546 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
547             }
548            
549             // Add Address class file
550             {
551 1501           const char* class_name = "Address";
552 1501           const char* rel_file = "Address.spvm";
553 1501           const char* content = "class Address : pointer {\n static method new : Address () {\n my $self = new Address;\n return $self;\n }\n}";
554 1501           SPVM_COMPILER_set_default_loaded_class_file(compiler, class_name, rel_file, content);
555             }
556 1501           }
557              
558 18012           void SPVM_COMPILER_set_default_loaded_class_file(SPVM_COMPILER* compiler, const char* class_name, const char* rel_file, const char* content) {
559 18012           SPVM_COMPILER_add_class_file(compiler, class_name);
560            
561 18012           SPVM_CLASS_FILE* class_file = SPVM_COMPILER_get_class_file(compiler, class_name);
562 18012           SPVM_CLASS_FILE_set_rel_file(compiler, class_file, rel_file);
563 18012           SPVM_CLASS_FILE_set_content(compiler, class_file, content);
564 18012           SPVM_CLASS_FILE_set_content_length(compiler, class_file, strlen(content));
565 18012           }
566              
567 3670           void SPVM_COMPILER_assert_check_basic_type_ids(SPVM_COMPILER* compiler) {
568            
569 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_UNKNOWN);
570 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_UNDEF);
571 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_VOID);
572 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE);
573 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT);
574 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_INT);
575 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_LONG);
576 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT);
577 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE);
578 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_STRING);
579 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_ANY_OBJECT);
580 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE_CLASS);
581 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT_CLASS);
582 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_INT_CLASS);
583 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_LONG_CLASS);
584 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT_CLASS);
585 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE_CLASS);
586 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_BOOL_CLASS);
587 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_CLASS);
588 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_SYSTEM_CLASS);
589 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_NOT_SUPPORTED_CLASS);
590 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_COMMAND_INFO_CLASS);
591 3670           SPVM_COMPILER_assert_check_basic_type_id(compiler, SPVM_NATIVE_C_BASIC_TYPE_ID_ADDRESS_CLASS);
592 3670           }
593              
594 84410           void SPVM_COMPILER_assert_check_basic_type_id(SPVM_COMPILER* compiler, int32_t basic_type_id) {
595 84410           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
596 84410           const char* basic_type_name_expected = SPVM_BASIC_TYPE_get_basic_type_name(compiler, basic_type_id);
597            
598 84410 50         if (strcmp(basic_type->name, basic_type_name_expected) != 0) {
599 0           fprintf(stderr, "[Unexpected Error]Basic Type ID:%d, Basic Type Name:%s, Expected Basic Type Name: %s\n", basic_type_id, basic_type->name, basic_type_name_expected);
600 0           assert(0);
601             }
602 84410           }
603              
604 3670           void SPVM_COMPILER_free_memory_tmp_each_compile(SPVM_COMPILER* compiler) {
605 54065550 100         for (int32_t i = 0; i < compiler->ops->length; i++) {
606 54061880           SPVM_OP* op = SPVM_LIST_get(compiler->ops, i);
607 54061880           int32_t op_id = op->id;
608 54061880           switch(op_id) {
609             case SPVM_OP_C_ID_BLOCK: {
610 1584182           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, op->uv.block);
611 1584182           break;
612             }
613             case SPVM_OP_C_ID_ATTRIBUTE: {
614 358080           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, op->uv.attribute);
615 358080           break;
616             }
617             case SPVM_OP_C_ID_USE: {
618 81851           SPVM_USE* use = op->uv.use;
619 81851           use->alias_name = NULL;
620 81851           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, use);
621 81851           break;
622             }
623             case SPVM_OP_C_ID_ALLOW: {
624 533           SPVM_ALLOW* allow = op->uv.allow;
625 533           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, allow);
626 533           break;
627             }
628             case SPVM_OP_C_ID_INTERFACE: {
629 1386           SPVM_INTERFACE* interface = op->uv.interface;
630 1386           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, interface);
631 1386           break;
632             }
633             case SPVM_OP_C_ID_CLASS_VAR_ACCESS: {
634 13072           SPVM_CLASS_VAR_ACCESS* class_var_access = op->uv.class_var_access;
635 13072           class_var_access->op_name = NULL;
636 13072           class_var_access->class_var = NULL;
637 13072           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, class_var_access);
638 13072           break;
639             }
640             case SPVM_OP_C_ID_CONSTANT: {
641 1015383           SPVM_CONSTANT* constant = op->uv.constant;
642 1015383           constant->op_constant = NULL;
643 1015383           constant->type = NULL;
644 1015383           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, constant);
645 1015383           break;
646             }
647             case SPVM_OP_C_ID_ARRAY_FIELD_ACCESS: {
648 2283           SPVM_ARRAY_FIELD_ACCESS* array_field_access = op->uv.array_field_access;
649 2283           array_field_access->field = NULL;
650 2283           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, array_field_access);
651 2283           break;
652             }
653             case SPVM_OP_C_ID_FIELD_ACCESS: {
654 189224           SPVM_FIELD_ACCESS* field_access = op->uv.field_access;
655 189224           field_access->op_name = NULL;
656 189224           field_access->field = NULL;
657 189224           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, field_access);
658 189224           break;
659             }
660             case SPVM_OP_C_ID_CALL_METHOD: {
661 255949           SPVM_CALL_METHOD* call_method = op->uv.call_method;
662 255949           call_method->op_name = NULL;
663 255949           call_method->method = NULL;
664 255949           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, call_method);
665 255949           break;
666             }
667             case SPVM_OP_C_ID_VAR: {
668 6955610           SPVM_VAR* var = op->uv.var;
669 6955610           var->op_name = NULL;
670 6955610           var->name = NULL;
671 6955610           var->var_decl = NULL;
672 6955610           var->call_method = NULL;
673 6955610           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, var);
674 6955610           break;
675             }
676             case SPVM_OP_C_ID_VAR_DECL: {
677 2881447           SPVM_VAR_DECL* var_decl = op->uv.var_decl;
678 2881447 100         if (!var_decl->is_arg) {
679 2353327           var_decl->op_var_decl = NULL;
680 2353327           var_decl->type = NULL;
681 2353327           var_decl->var = NULL;
682 2353327           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, var_decl);
683             }
684 2881447           break;
685             }
686             }
687 54061880           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->current_each_compile_allocator, op);
688             }
689            
690 63266 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
691 59596           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
692            
693 59596           SPVM_LIST* methods = basic_type->methods;
694             {
695             int32_t method_index;
696 370550 100         for (method_index = 0; method_index < methods->length; method_index++) {
697 310954           SPVM_METHOD* method = SPVM_LIST_get(methods, method_index);
698 310954           method->op_method = NULL;
699 310954           method->op_name = NULL;
700 310954           method->op_block = NULL;
701             }
702             }
703             }
704            
705 3670           compiler->op_use_stack->length = 0;
706            
707 3670           compiler->op_types->length = 0;
708            
709 3670           compiler->ops->length = 0;
710            
711 3670           SPVM_HASH_free(compiler->if_require_not_found_basic_type_name_symtable);
712 3670           }
713              
714 3119           SPVM_RUNTIME* SPVM_COMPILER_build_runtime(SPVM_COMPILER* compiler) {
715            
716 3119           SPVM_RUNTIME* current_runtime = compiler->runtime;
717            
718 3119           int32_t current_runtime_basic_types_length = current_runtime->basic_types_length;
719            
720 3119           SPVM_RUNTIME* runtime = current_runtime;
721            
722 3119           SPVM_RUNTIME_BASIC_TYPE** current_runtime_basic_types = current_runtime->basic_types;
723            
724 3119           runtime->basic_types = SPVM_ALLOCATOR_alloc_memory_block_tmp(runtime->allocator, sizeof(SPVM_RUNTIME_BASIC_TYPE*) * compiler->basic_types->length);
725 3119 100         if (current_runtime_basic_types_length > 0) {
726 2168           memcpy(runtime->basic_types, current_runtime_basic_types, sizeof(SPVM_RUNTIME_BASIC_TYPE*) * current_runtime_basic_types_length);
727 2168           SPVM_ALLOCATOR_free_memory_block_tmp(runtime->allocator, current_runtime_basic_types);
728             }
729            
730 3119           runtime->basic_types_length = compiler->basic_types->length;
731            
732 48981 100         for (int32_t basic_type_id = current_runtime_basic_types_length; basic_type_id < compiler->basic_types->length; basic_type_id++) {
733 45862           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
734 45862           SPVM_RUNTIME_BASIC_TYPE* runtime_basic_type = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, sizeof(SPVM_RUNTIME_BASIC_TYPE));
735            
736 45862           runtime->basic_types[basic_type_id] = runtime_basic_type;
737             }
738            
739 3119 50         assert(runtime->basic_types[0]);
740            
741 48981 100         for (int32_t basic_type_id = current_runtime_basic_types_length; basic_type_id < compiler->basic_types->length; basic_type_id++) {
742            
743 45862           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
744 45862           SPVM_RUNTIME_BASIC_TYPE* runtime_basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, basic_type_id);
745            
746 45862           SPVM_HASH_set(runtime->basic_type_symtable, basic_type->name, strlen(basic_type->name), runtime_basic_type);
747            
748 45862           const char* runtime_string_pool = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, basic_type->string_pool->length);
749 45862           memcpy((char*)runtime_string_pool, basic_type->string_pool->string, basic_type->string_pool->length);
750 45862           runtime_basic_type->string_pool = runtime_string_pool;
751 45862           runtime_basic_type->string_pool_length = basic_type->string_pool->length;
752            
753 45862           SPVM_RUNTIME_STRING* runtime_constant_strings = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, sizeof(SPVM_RUNTIME_STRING) * basic_type->constant_strings->length);
754 795254 100         for (int32_t constant_string_index = 0; constant_string_index < basic_type->constant_strings->length; constant_string_index++) {
755 749392           SPVM_STRING* constant_string = SPVM_LIST_get(basic_type->constant_strings, constant_string_index);
756 749392           SPVM_RUNTIME_STRING* runtime_constant_string = &runtime_constant_strings[constant_string_index];
757 749392           runtime_constant_string->value = &runtime_basic_type->string_pool[constant_string->string_pool_index];
758 749392           runtime_constant_string->length = constant_string->length;
759             }
760 45862           runtime_basic_type->constant_strings = runtime_constant_strings;
761 45862           runtime_basic_type->constant_strings_length = basic_type->constant_strings->length;
762            
763 45862 100         if (basic_type->class_vars->length > 0) {
764 2061           SPVM_RUNTIME_CLASS_VAR* runtime_class_vars = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, sizeof(SPVM_RUNTIME_CLASS_VAR) * basic_type->class_vars->length);
765 7467 100         for (int32_t class_var_index = 0; class_var_index < basic_type->class_vars->length; class_var_index++) {
766 5406           SPVM_CLASS_VAR* class_var = SPVM_LIST_get(basic_type->class_vars, class_var_index);
767 5406           SPVM_RUNTIME_CLASS_VAR* runtime_class_var = &runtime_class_vars[class_var_index];
768            
769 5406           runtime_class_var->index = class_var->index;
770 5406           runtime_class_var->basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, class_var->type->basic_type->id);
771 5406           runtime_class_var->type_dimension = class_var->type->dimension;
772 5406           runtime_class_var->type_flag = class_var->type->flag;
773 5406           runtime_class_var->current_basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, class_var->current_basic_type->id);
774            
775 5406           SPVM_STRING* class_var_name_string = SPVM_HASH_get(basic_type->constant_string_symtable, class_var->name, strlen(class_var->name));
776 5406           runtime_class_var->name = runtime_basic_type->constant_strings[class_var_name_string->index].value;
777             }
778 2061           runtime_basic_type->class_vars = runtime_class_vars;
779 2061           runtime_basic_type->class_vars_length = basic_type->class_vars->length;
780             }
781            
782 45862 100         if (basic_type->fields->length > 0) {
783 14124           SPVM_RUNTIME_FIELD* runtime_fields = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, sizeof(SPVM_RUNTIME_FIELD) * basic_type->fields->length);
784 37459 100         for (int32_t field_index = 0; field_index < basic_type->fields->length; field_index++) {
785 23335           SPVM_FIELD* field = SPVM_LIST_get(basic_type->fields, field_index);
786 23335           SPVM_RUNTIME_FIELD* runtime_field = &runtime_fields[field_index];
787            
788 23335           runtime_field->index = field->index;
789 23335           runtime_field->offset = field->offset;
790 23335           runtime_field->basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, field->type->basic_type->id);
791 23335           runtime_field->type_dimension = field->type->dimension;
792 23335           runtime_field->type_flag = field->type->flag;
793 23335           runtime_field->current_basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, field->current_basic_type->id);
794            
795 23335           SPVM_STRING* field_name_string = SPVM_HASH_get(basic_type->constant_string_symtable, field->name, strlen(field->name));
796 23335           runtime_field->name = runtime_basic_type->constant_strings[field_name_string->index].value;
797             }
798 14124           runtime_basic_type->fields = runtime_fields;
799 14124           runtime_basic_type->fields_length = basic_type->fields->length;
800             }
801            
802 45862 100         if (basic_type->methods->length > 0) {
803 35172           SPVM_RUNTIME_METHOD* runtime_methods = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, sizeof(SPVM_RUNTIME_METHOD) * basic_type->methods->length);
804 323715 100         for (int32_t method_index = 0; method_index < basic_type->methods->length; method_index++) {
805            
806 288543           SPVM_METHOD* method = SPVM_LIST_get(basic_type->methods, method_index);
807 288543           SPVM_RUNTIME_METHOD* runtime_method = &runtime_methods[method_index];
808            
809 288543 50         assert(method->opcode_list->length > 0);
810            
811 288543           runtime_method->opcodes = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, sizeof(SPVM_OPCODE) * method->opcode_list->length);
812 288543           memcpy(runtime_method->opcodes, method->opcode_list->values, sizeof(SPVM_OPCODE) * method->opcode_list->length);
813 288543           runtime_method->opcodes_length = method->opcode_list->length;
814            
815 288543           runtime_method->index = method->index;
816 288543           runtime_method->current_basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, method->current_basic_type->id);
817 288543           runtime_method->is_class_method = method->is_class_method;
818 288543           runtime_method->is_init = method->is_init;
819 288543           runtime_method->is_anon = method->is_anon;
820 288543           runtime_method->byte_vars_width = method->byte_vars_width;
821 288543           runtime_method->short_vars_width = method->short_vars_width;
822 288543           runtime_method->int_vars_width = method->int_vars_width;
823 288543           runtime_method->long_vars_width = method->long_vars_width;
824 288543           runtime_method->float_vars_width = method->float_vars_width;
825 288543           runtime_method->double_vars_width = method->double_vars_width;
826 288543           runtime_method->object_vars_width = method->object_vars_width;
827 288543           runtime_method->ref_vars_width = method->ref_vars_width;
828 288543           runtime_method->mortal_stack_length = method->mortal_stack_length;
829 288543           runtime_method->return_basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, method->return_type->basic_type->id);
830 288543           runtime_method->return_type_dimension = method->return_type->dimension;
831 288543           runtime_method->return_type_flag = method->return_type->flag;
832 288543           runtime_method->is_native = method->is_native;
833 288543           runtime_method->is_precompile = method->is_precompile;
834 288543           runtime_method->is_destructor = method->is_destructor;
835 288543           runtime_method->is_required = method->is_required;
836 288543           runtime_method->is_enum = method->is_enum;
837            
838 288543           SPVM_STRING* method_name_string = SPVM_HASH_get(basic_type->constant_string_symtable, method->name, strlen(method->name));
839 288543           runtime_method->name = runtime_basic_type->constant_strings[method_name_string->index].value;
840            
841 288543 100         if (method->args_length > 0) {
842 220701           runtime_method->args = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, sizeof(SPVM_RUNTIME_ARG) * method->args_length);
843 220701           runtime_method->args_length = method->args_length;
844 714930 100         for (int32_t arg_index = 0; arg_index < method->args_length; arg_index++) {
845 494229           SPVM_VAR_DECL* arg_var_decl = SPVM_LIST_get(method->var_decls, arg_index);
846 494229           SPVM_RUNTIME_ARG* runtime_arg = &runtime_method->args[arg_index];
847            
848 494229           SPVM_STRING* arg_name_string = SPVM_HASH_get(basic_type->constant_string_symtable, arg_var_decl->name, strlen(arg_var_decl->name));
849            
850 494229           runtime_arg->name = runtime_basic_type->constant_strings[arg_name_string->index].value;
851 494229           runtime_arg->index = arg_index;
852 494229           runtime_arg->basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, arg_var_decl->type->basic_type->id);
853 494229           runtime_arg->type_dimension = arg_var_decl->type->dimension;
854 494229           runtime_arg->type_flag = arg_var_decl->type->flag;
855 494229           runtime_arg->stack_index = arg_var_decl->arg_stack_index;
856             }
857             }
858            
859 288543           runtime_method->required_args_length = method->required_args_length;
860             }
861 35172           runtime_basic_type->methods = runtime_methods;
862 35172           runtime_basic_type->methods_length = basic_type->methods->length;
863             }
864            
865 45862 100         if (basic_type->anon_basic_types->length > 0) {
866 557           SPVM_RUNTIME_BASIC_TYPE** runtime_anon_basic_types = SPVM_ALLOCATOR_alloc_memory_block_permanent(runtime->allocator, sizeof(SPVM_RUNTIME_BASIC_TYPE*) * basic_type->anon_basic_types->length);
867 8632 100         for (int32_t anon_basic_type_index = 0; anon_basic_type_index < basic_type->anon_basic_types->length; anon_basic_type_index++) {
868 8075           SPVM_BASIC_TYPE* anon_basic_type = SPVM_LIST_get(basic_type->anon_basic_types, anon_basic_type_index);
869 8075           runtime_anon_basic_types[anon_basic_type_index] = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, anon_basic_type->id);
870             }
871 557           runtime_basic_type->anon_basic_types = runtime_anon_basic_types;
872 557           runtime_basic_type->anon_basic_types_length = basic_type->anon_basic_types->length;
873             }
874            
875 45862           runtime_basic_type->id = basic_type->id;
876 45862           runtime_basic_type->category = basic_type->category;
877            
878 45862           SPVM_STRING* basic_type_string = SPVM_HASH_get(basic_type->constant_string_symtable, basic_type->name, strlen(basic_type->name));
879 45862 50         assert(basic_type_string->index >= 0);
880 45862           runtime_basic_type->name = runtime_basic_type->constant_strings[basic_type_string->index].value;
881            
882 45862 100         if (basic_type->class_rel_file) {
883 35401           SPVM_STRING* basic_type_rel_file_string = SPVM_HASH_get(basic_type->constant_string_symtable, basic_type->class_rel_file, strlen(basic_type->class_rel_file));
884 35401           runtime_basic_type->class_rel_file = runtime_basic_type->constant_strings[basic_type_rel_file_string->index].value;
885             }
886            
887 45862 100         if (basic_type->class_dir) {
888 23989           SPVM_STRING* basic_type_dir_string = SPVM_HASH_get(basic_type->constant_string_symtable, basic_type->class_dir, strlen(basic_type->class_dir));
889 23989           runtime_basic_type->class_dir = runtime_basic_type->constant_strings[basic_type_dir_string->index].value;
890             }
891            
892 45862 100         if (basic_type->version_string) {
893 167           SPVM_STRING* basic_type_version_string = SPVM_HASH_get(basic_type->constant_string_symtable, basic_type->version_string, strlen(basic_type->version_string));
894 167           runtime_basic_type->version_string = runtime_basic_type->constant_strings[basic_type_version_string->index].value;
895             }
896            
897 45862           runtime_basic_type->is_anon = basic_type->is_anon;
898            
899 45862           runtime_basic_type->is_pointer = basic_type->is_pointer;
900            
901 45862 100         if (basic_type->parent) {
902 1992           SPVM_BASIC_TYPE* parent_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, basic_type->parent->name, strlen(basic_type->parent->name));
903 1992           runtime_basic_type->parent = SPVM_API_RUNTIME_get_basic_type_by_id(runtime, parent_basic_type->id);
904             }
905            
906 45862           runtime_basic_type->fields_size = basic_type->fields_size;
907            
908 45862 100         if (basic_type->init_method) {
909 29552           runtime_basic_type->init_method = &runtime_basic_type->methods[basic_type->init_method->index];
910             }
911            
912 45862 100         if (basic_type->destructor_method) {
913 757           runtime_basic_type->destructor_method = &runtime_basic_type->methods[basic_type->destructor_method->index];
914             }
915             }
916            
917 3119           compiler->runtime = runtime;
918            
919 3119           return runtime;
920             }
921              
922 1837           SPVM_RUNTIME* SPVM_COMPILER_get_runtime(SPVM_COMPILER* compiler) {
923 1837           return compiler->runtime;
924             }
925              
926 618           void SPVM_COMPILER_error(SPVM_COMPILER* compiler, const char* error_message_template, ...) {
927            
928 618           int32_t error_message_length = 0;
929            
930             // Message template
931 618           int32_t error_message_template_length = (int32_t)strlen(error_message_template);
932            
933             va_list args;
934 618           va_start(args, error_message_template);
935            
936 618           error_message_length += error_message_template_length;
937            
938             // Argument count
939 618           char* found_ptr = (char*)error_message_template;
940             while (1) {
941 2617           found_ptr = strchr(found_ptr, '%');
942 2617 100         if (found_ptr) {
943 1999 100         if (*(found_ptr + 1) == 'c') {
944 3 50         int arg = va_arg(args, int);
945 3           error_message_length++;
946             }
947 1996 100         else if (*(found_ptr + 1) == 's') {
948 1302 100         char* arg = va_arg(args, char*);
949 1302           error_message_length += strlen(arg);
950             }
951 694 100         else if (*(found_ptr + 1) == 'd') {
952 688 100         (void) va_arg(args, int);
953 688           error_message_length += 30;
954             }
955 6 50         else if (*(found_ptr + 1) == '%') {
956             // Nothing
957 6           found_ptr++;
958             }
959             else {
960 0           assert(0);
961             }
962 1999           found_ptr++;
963             }
964             else {
965 618           break;
966             }
967 1999           }
968 618           va_end(args);
969            
970 618           char* error_message = SPVM_ALLOCATOR_alloc_memory_block_tmp(compiler->error_message_allocator, error_message_length + 1);
971            
972 618           va_start(args, error_message_template);
973 618           vsprintf(error_message, error_message_template, args);
974 618           va_end(args);
975            
976 618           SPVM_LIST_push(compiler->error_messages, error_message);
977 618           }
978              
979 3334           const char* SPVM_COMPILER_get_start_file(SPVM_COMPILER* compiler) {
980 3334           return compiler->start_file;
981             }
982              
983 4489           void SPVM_COMPILER_set_start_file(SPVM_COMPILER* compiler, const char* start_file) {
984 4489 100         if (compiler->start_file) {
985 2996           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->global_allocator, (void*)compiler->start_file);
986 2996           compiler->start_file = NULL;
987             }
988            
989 4489 100         if (start_file) {
990 3334           int32_t start_file_length = strlen(start_file);
991 3334           compiler->start_file = SPVM_ALLOCATOR_alloc_memory_block_tmp(compiler->global_allocator, start_file_length + 1);
992 3334           memcpy((void*)compiler->start_file, start_file, start_file_length);
993             }
994 4489           }
995              
996 3334           int32_t SPVM_COMPILER_get_start_line(SPVM_COMPILER* compiler) {
997 3334           return compiler->start_line;
998             }
999              
1000 3334           void SPVM_COMPILER_set_start_line(SPVM_COMPILER* compiler, int32_t start_line) {
1001 3334           compiler->start_line = start_line;
1002 3334           }
1003              
1004 18087           int32_t SPVM_COMPILER_get_include_dirs_length(SPVM_COMPILER* compiler) {
1005 18087           SPVM_LIST* include_dirs = compiler->include_dirs;
1006 18087           int32_t include_dirs_length = include_dirs->length;
1007 18087           return include_dirs_length;
1008             }
1009              
1010 35499           void SPVM_COMPILER_add_include_dir(SPVM_COMPILER* compiler, const char* include_dir) {
1011 35499           int32_t include_dir_length = strlen(include_dir);
1012 35499           char* compiler_include_dir = SPVM_ALLOCATOR_alloc_memory_block_tmp(compiler->global_allocator, include_dir_length + 1);
1013 35499           memcpy(compiler_include_dir, include_dir, include_dir_length);
1014 35499           SPVM_LIST_push(compiler->include_dirs, (void*)compiler_include_dir);
1015 35499           }
1016              
1017 1155           void SPVM_COMPILER_clear_include_dirs(SPVM_COMPILER* compiler) {
1018 1155           int32_t include_dirs_length = SPVM_COMPILER_get_include_dirs_length(compiler);
1019            
1020 32980 100         for (int32_t i = 0; i < include_dirs_length; i++) {
1021 31825           const char* include_dir = SPVM_COMPILER_get_include_dir(compiler, i);
1022 31825           SPVM_ALLOCATOR_free_memory_block_tmp(compiler->global_allocator, (void*)include_dir);
1023 31825           include_dir = NULL;
1024             }
1025            
1026 1155           SPVM_LIST_clear(compiler->include_dirs);
1027 1155           }
1028              
1029 93153           const char* SPVM_COMPILER_get_include_dir (SPVM_COMPILER* compiler, int32_t include_dir_id) {
1030 93153           const char* include_dir = SPVM_LIST_get(compiler->include_dirs, include_dir_id);
1031 93153           return include_dir;
1032             }