File Coverage

lib/SPVM/Builder/src/spvm_basic_type.c
Criterion Covered Total %
statement 130 148 87.8
branch 51 64 79.6
condition n/a
subroutine n/a
pod n/a
total 181 212 85.3


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              
8             #include "spvm_compiler.h"
9             #include "spvm_basic_type.h"
10             #include "spvm_allocator.h"
11             #include "spvm_list.h"
12             #include "spvm_hash.h"
13             #include "spvm_method.h"
14             #include "spvm_string_buffer.h"
15             #include "spvm_string.h"
16             #include "spvm_op.h"
17             #include "spvm_type.h"
18             #include "spvm_var_decl.h"
19              
20 100921           const char* const* SPVM_BASIC_TYPE_C_ID_NAMES(void) {
21              
22             static const char* const id_names[] = {
23             "unknown",
24             "undef",
25             "void",
26             "byte",
27             "short",
28             "int",
29             "long",
30             "float",
31             "double",
32             "string",
33             "object",
34             "Byte",
35             "Short",
36             "Int",
37             "Long",
38             "Float",
39             "Double",
40             "Bool",
41             "Error",
42             "Error::System",
43             "Error::NotSupported",
44             "CommandInfo",
45             "Address",
46             };
47            
48 100921           return id_names;
49             }
50              
51 0           const char* const* SPVM_BASIC_TYPE_C_CATEGORY_NAMES(void) {
52              
53             static const char* const id_names[] = {
54             "unknown"
55             "undef"
56             "void"
57             "numeric"
58             "mulnum"
59             "string",
60             "class",
61             "interface",
62             "any_obejct",
63             };
64            
65 0           return id_names;
66             }
67              
68 59596           SPVM_BASIC_TYPE* SPVM_BASIC_TYPE_new(SPVM_COMPILER* compiler) {
69 59596           SPVM_BASIC_TYPE* basic_type = SPVM_ALLOCATOR_alloc_memory_block_permanent(compiler->current_each_compile_allocator, sizeof(SPVM_BASIC_TYPE));
70            
71 59596           basic_type->constant_strings = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 128);
72 59596           basic_type->constant_string_symtable = SPVM_HASH_new_hash_permanent(compiler->current_each_compile_allocator, 128);
73 59596           basic_type->string_pool = SPVM_STRING_BUFFER_new(compiler->current_each_compile_allocator, 8192, SPVM_ALLOCATOR_C_ALLOC_TYPE_PERMANENT);
74            
75             // Fields
76 59596           basic_type->unmerged_fields = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
77 59596           basic_type->unmerged_field_symtable = SPVM_HASH_new_hash_permanent(compiler->current_each_compile_allocator, 0);
78            
79 59596           basic_type->field_symtable = SPVM_HASH_new_hash_permanent(compiler->current_each_compile_allocator, 0);
80            
81             // Class variables
82 59596           basic_type->class_vars = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
83 59596           basic_type->class_var_symtable = SPVM_HASH_new_hash_permanent(compiler->current_each_compile_allocator, 0);
84            
85             // Methods
86 59596           basic_type->methods = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
87 59596           basic_type->method_symtable = SPVM_HASH_new_hash_permanent(compiler->current_each_compile_allocator, 0);
88            
89             // Interfaces
90 59596           basic_type->interface_basic_types = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
91 59596           basic_type->interface_basic_symtable = SPVM_HASH_new_hash_permanent(compiler->current_each_compile_allocator, 0);
92            
93 59596           basic_type->allows = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
94 59596           basic_type->interface_decls = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
95 59596           basic_type->anon_unresolved_basic_type_names = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
96 59596           basic_type->anon_basic_types = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
97 59596           basic_type->alias_symtable = SPVM_HASH_new_hash_permanent(compiler->current_each_compile_allocator, 0);
98            
99 59596           basic_type->use_basic_type_names = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
100            
101 59596           return basic_type;
102             }
103              
104 100921           const char* SPVM_BASIC_TYPE_get_basic_type_name(SPVM_COMPILER* compiler, int32_t basic_type_id) {
105 100921           return (SPVM_BASIC_TYPE_C_ID_NAMES())[basic_type_id];
106             }
107              
108 0           int32_t SPVM_BASIC_TYPE_is_void_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
109            
110 0 0         if (basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_VOID) {
111 0           return 1;
112             }
113             else {
114 0           return 0;
115             }
116            
117             return 1;
118             }
119              
120 18189904           int32_t SPVM_BASIC_TYPE_is_numeric_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
121            
122 18189904 100         if (basic_type_id >= SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE && basic_type_id <= SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE) {
    100          
123 15641824           return 1;
124             }
125             else {
126 2548080           return 0;
127             }
128            
129             return 1;
130             }
131              
132              
133 9081739           int32_t SPVM_BASIC_TYPE_is_mulnum_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
134            
135 9081739           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
136            
137 9081739           int32_t is_mulnum_type = (basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_MULNUM);
138            
139 9081739           return is_mulnum_type;
140             }
141              
142 156215           int32_t SPVM_BASIC_TYPE_is_string_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
143            
144 156215           return basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_STRING;
145             }
146              
147 8936579           int32_t SPVM_BASIC_TYPE_is_class_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
148            
149 8936579           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
150            
151 8936579           int32_t is_class_type = (basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS);
152            
153 8936579           return is_class_type;
154             }
155              
156 7454664           int32_t SPVM_BASIC_TYPE_is_interface_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
157 7454664           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
158            
159 7454664           int32_t is_interface_type = (basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_INTERFACE);
160            
161 7454664           return is_interface_type;
162             }
163              
164 0           int32_t SPVM_BASIC_TYPE_is_any_object_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
165            
166 0           return basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_ANY_OBJECT;
167             }
168              
169              
170 0           int32_t SPVM_BASIC_TYPE_is_undef_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
171            
172 0 0         if (basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_UNDEF) {
173 0           return 1;
174             }
175             else {
176 0           return 0;
177             }
178             }
179              
180              
181 0           int32_t SPVM_BASIC_TYPE_is_unknown_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
182            
183 0 0         if (basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_UNKNOWN) {
184 0           return 1;
185             }
186             else {
187 0           return 0;
188             }
189             }
190              
191              
192 540060           int32_t SPVM_BASIC_TYPE_is_numeric_object_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
193            
194 540060 100         if (basic_type_id >= SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE_CLASS && basic_type_id <= SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE_CLASS) {
    100          
195 73390           return 1;
196             }
197             else {
198 466670           return 0;
199             }
200             }
201              
202 7053           int32_t SPVM_BASIC_TYPE_is_integer_type(SPVM_COMPILER* compiler, int32_t basic_type_id) {
203            
204 7053 50         if (basic_type_id >= SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE && basic_type_id <= SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) {
    100          
205 7034           return 1;
206             }
207             else {
208 19           return 0;
209             }
210             }
211              
212 36258           int32_t SPVM_BASIC_TYPE_is_integer_type_within_int(SPVM_COMPILER* compiler, int32_t basic_type_id) {
213            
214 36258 50         if (basic_type_id >= SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE && basic_type_id <= SPVM_NATIVE_C_BASIC_TYPE_ID_INT) {
    100          
215 36253           return 1;
216             }
217             else {
218 5           return 0;
219             }
220             }
221              
222 8208           int32_t SPVM_BASIC_TYPE_has_interface(SPVM_COMPILER* compiler, int32_t basic_type_id, int32_t interface_basic_type_id) {
223            
224 8208           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
225            
226 8208           SPVM_BASIC_TYPE* interface_basic_type = SPVM_LIST_get(compiler->basic_types, interface_basic_type_id);
227            
228 8208 50         if (!(interface_basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_INTERFACE)) {
229 0           return 0;
230             }
231            
232 8208 100         if (!(basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS || basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_INTERFACE)) {
    50          
233 0           return 0;
234             }
235            
236 16518 100         for (int32_t interface_method_index = 0; interface_method_index < interface_basic_type->methods->length; interface_method_index++) {
237 8320           SPVM_METHOD* interface_method = SPVM_LIST_get(interface_basic_type->methods, interface_method_index);
238            
239 29843 100         for (int32_t method_index = 0; method_index < basic_type->methods->length; method_index++) {
240 21533           SPVM_METHOD* method = SPVM_HASH_get(basic_type->method_symtable, interface_method->name, strlen(interface_method->name));
241            
242 21533           int32_t method_compatibility = SPVM_BASIC_TYPE_check_method_compatibility(compiler, basic_type, method, interface_basic_type, interface_method, "interface");
243            
244 21533 100         if (method_compatibility == 0) {
245 10           return 0;
246             }
247             }
248             }
249            
250 8198           return 1;
251             }
252              
253 23736           int32_t SPVM_BASIC_TYPE_check_method_compatibility(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, SPVM_METHOD* method, SPVM_BASIC_TYPE* dist_basic_type, SPVM_METHOD* dist_method, const char* type_desc) {
254            
255 23736 100         if (dist_method->is_required && !method) {
    100          
256 10 50         if (!dist_method->is_class_method) {
257 10           SPVM_COMPILER_error(compiler, "The \"%s\" class must implement the \"%s\" method. This is defined as a required interface method in the \"%s\" %s.\n at %s line %d", basic_type->name, dist_method->name, dist_basic_type->name, type_desc, basic_type->op_class->file, basic_type->op_class->line);
258 10           return 0;
259             }
260             }
261            
262 23726 100         if (method) {
263 21007 100         if (method->is_class_method) {
264 1 50         if (!dist_method->is_class_method) {
265 1           SPVM_COMPILER_error(compiler, "The \"%s\" method in the \"%s\" class must be an instance method. This is defined as an interface method in the \"%s\" %s.\n at %s line %d", method->name, basic_type->name, dist_basic_type->name, type_desc, basic_type->op_class->file, basic_type->op_class->line);
266 1           return 0;
267             }
268             }
269            
270 21006           SPVM_LIST* method_var_decls = method->var_decls;
271            
272 21006           SPVM_LIST* dist_method_var_decls = dist_method->var_decls;
273            
274 21006 100         if (!(method->required_args_length == dist_method->required_args_length)) {
275            
276 4           SPVM_COMPILER_error(compiler, "The length of the required arguments of the \"%s\" method in the \"%s\" class must be equal to the length of the required arguments of the \"%s\" method in the \"%s\" %s.\n at %s line %d", method->name, basic_type->name, dist_method->name, dist_basic_type->name, type_desc, basic_type->op_class->file, basic_type->op_class->line);
277 4           return 0;
278             }
279              
280 21002 100         if (!(method->args_length >= dist_method->args_length)) {
281 1           SPVM_COMPILER_error(compiler, "The length of the arguments of the \"%s\" method in the \"%s\" class must be greather than or equal to the length of the arguments of the \"%s\" method in the \"%s\" %s.\n at %s line %d", method->name, basic_type->name, dist_method->name, dist_basic_type->name, type_desc, basic_type->op_class->file, basic_type->op_class->line);
282 1           return 0;
283             }
284            
285 54297 100         for (int32_t arg_index = 1; arg_index < dist_method->args_length; arg_index++) {
286 33298           SPVM_VAR_DECL* method_var_decl = SPVM_LIST_get(method_var_decls, arg_index);
287 33298           SPVM_VAR_DECL* dist_method_var_decl = SPVM_LIST_get(dist_method_var_decls, arg_index);
288            
289 33298           SPVM_TYPE* method_var_decl_type = method_var_decl->type;
290 33298           SPVM_TYPE* dist_method_var_decl_type = dist_method_var_decl->type;
291            
292 33298           int32_t assignability_for_method = SPVM_TYPE_can_assign_for_method_definition(compiler, dist_method_var_decl_type->basic_type->id, dist_method_var_decl_type->dimension, dist_method_var_decl_type->flag, method_var_decl_type->basic_type->id, method_var_decl_type->dimension, method_var_decl_type->flag);
293            
294 33298 100         if (!assignability_for_method) {
295 2           SPVM_COMPILER_error(compiler, "The type of the %dth argument of the \"%s\" method in the \"%s\" class must be able to be assigned to the type of the %dth argument of the \"%s\" method in the \"%s\" %s.\n at %s line %d", arg_index, method->name, basic_type->name, arg_index, dist_method->name, dist_basic_type->name, type_desc, basic_type->op_class->file, basic_type->op_class->line);
296 2           return 0;
297             }
298             }
299            
300 20999           SPVM_TYPE* method_return_type = method->return_type;
301 20999           SPVM_TYPE* dist_method_return_type = dist_method->return_type;
302            
303 20999           int32_t assignability_for_method_definition = SPVM_TYPE_can_assign_for_method_definition(
304             compiler,
305 20999           dist_method_return_type->basic_type->id, dist_method_return_type->dimension, dist_method_return_type->flag,
306 20999           method_return_type->basic_type->id, method_return_type->dimension, method_return_type->flag
307             );
308            
309 20999 100         if (!assignability_for_method_definition) {
310 3           SPVM_COMPILER_error(compiler, "The return type of the \"%s\" method in the \"%s\" class must be able to be assigned to the return type of the \"%s\" method in the \"%s\" %s.\n at %s line %d", method->name, basic_type->name, dist_method->name, dist_basic_type->name, type_desc, basic_type->op_class->file, basic_type->op_class->line);
311 3           return 0;
312             }
313             }
314            
315 23715           return 1;
316             }
317              
318 658           int32_t SPVM_BASIC_TYPE_is_super_class(SPVM_COMPILER* compiler, int32_t super_basic_type_id, int32_t child_basic_type_id) {
319            
320 658           SPVM_BASIC_TYPE* super_basic_type = SPVM_LIST_get(compiler->basic_types, super_basic_type_id);
321 658           SPVM_BASIC_TYPE* child_basic_type = SPVM_LIST_get(compiler->basic_types, child_basic_type_id);
322            
323 658           const char* current_parent_basic_type_name = child_basic_type->parent_name;
324             while (1) {
325 660 100         if (current_parent_basic_type_name) {
326 594 100         if (strcmp(super_basic_type->name, current_parent_basic_type_name) == 0) {
327 592           return 1;
328             }
329             else {
330 2           SPVM_BASIC_TYPE* current_parent_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, current_parent_basic_type_name, strlen(current_parent_basic_type_name));
331 2 50         assert(current_parent_basic_type);
332 2           current_parent_basic_type_name = current_parent_basic_type->parent_name;
333             }
334             }
335             else {
336 66           return 0;
337             }
338 2           }
339             }
340              
341 2459103           SPVM_STRING* SPVM_BASIC_TYPE_add_constant_string(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, const char* value, int32_t length) {
342            
343 2459103           SPVM_STRING* found_string = SPVM_HASH_get(basic_type->constant_string_symtable, value, length);
344 2459103 100         if (found_string) {
345 1667619           return found_string;
346             }
347             else {
348 791484           int32_t string_pool_index = basic_type->string_pool->length;
349            
350 791484           SPVM_STRING_BUFFER_add_len_nullstr(basic_type->string_pool, (char*)value, length);
351            
352 791484           SPVM_STRING* string = SPVM_ALLOCATOR_alloc_memory_block_permanent(compiler->current_each_compile_allocator, sizeof(SPVM_STRING));
353 791484           string->value = value;
354 791484           string->length = length;
355 791484           string->index = basic_type->constant_strings->length;
356 791484           string->string_pool_index = string_pool_index;
357            
358 791484           SPVM_LIST_push(basic_type->constant_strings, string);
359 791484           SPVM_HASH_set(basic_type->constant_string_symtable, string->value, length, string);
360            
361 791484           return string;
362             }
363             }