File Coverage

lib/SPVM/Builder/src/spvm_api_type.c
Criterion Covered Total %
statement 57 86 66.2
branch 32 50 64.0
condition n/a
subroutine n/a
pod n/a
total 89 136 65.4


line stmt bran cond sub pod time code
1             // Copyright (c) 2023 Yuki Kimoto
2             // MIT License
3              
4             #include
5             #include
6              
7             #include "spvm_native.h"
8              
9             #include "spvm_api_type.h"
10             #include "spvm_api_basic_type.h"
11              
12             #include "spvm_allocator.h"
13             #include "spvm_runtime.h"
14             #include "spvm_runtime_basic_type.h"
15             #include "spvm_runtime_field.h"
16             #include "spvm_hash.h"
17             #include "spvm_mutex.h"
18              
19 119195           SPVM_API_TYPE* SPVM_API_TYPE_new_api() {
20            
21 119195           void* native_apis_init[] = {
22             SPVM_API_TYPE_can_assign,
23             SPVM_API_TYPE_get_type_width,
24             SPVM_API_TYPE_is_object_type,
25             SPVM_API_TYPE_is_any_object_type,
26             SPVM_API_TYPE_is_object_array_type,
27             SPVM_API_TYPE_is_any_object_array_type,
28             };
29            
30 119195           SPVM_API_TYPE* native_apis = calloc(1, sizeof(native_apis_init));
31            
32 119195           memcpy(native_apis, native_apis_init, sizeof(native_apis_init));
33            
34 119195           return native_apis;
35             }
36              
37 119195           void SPVM_API_TYPE_free_api(SPVM_API_TYPE* api) {
38            
39 119195           free(api);
40 119195           }
41              
42 4764164           int32_t SPVM_API_TYPE_is_object_type(SPVM_RUNTIME* runtime, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension, int32_t flag) {
43            
44             int32_t is_object_type;
45 4764164 100         if (type_dimension == 0) {
46 4681525           int32_t basic_type_category = basic_type->category;
47            
48 4681525 100         switch (basic_type_category) {
49             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_STRING:
50             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS:
51             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_INTERFACE:
52             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_ANY_OBJECT:
53             {
54 798603           is_object_type = 1;
55 798603           break;
56             }
57             default: {
58 4681525           is_object_type = 0;
59             }
60             }
61             }
62 82639 50         else if (type_dimension >= 1) {
63 82639           is_object_type = 1;
64             }
65             else {
66 0           assert(0);
67             }
68            
69 4764164           return is_object_type;
70             }
71              
72 0           int32_t SPVM_API_TYPE_is_any_object_type(SPVM_RUNTIME* runtime, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension, int32_t flag) {
73            
74             int32_t is_any_object_type;
75 0 0         if (type_dimension == 0) {
76 0           int32_t basic_type_category = basic_type->category;
77            
78 0 0         switch (basic_type_category) {
79             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_ANY_OBJECT:
80             {
81 0           is_any_object_type = 1;
82 0           break;
83             }
84             default: {
85 0           is_any_object_type = 0;
86             }
87             }
88             }
89 0 0         else if (type_dimension >= 1) {
90 0           is_any_object_type = 1;
91             }
92             else {
93 0           assert(0);
94             }
95            
96 0           return is_any_object_type;
97             }
98              
99 0           int32_t SPVM_API_TYPE_is_object_array_type(SPVM_RUNTIME* runtime, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t dimension, int32_t flag) {
100            
101 0 0         if (dimension > 0) {
102 0 0         if (SPVM_API_TYPE_is_object_type(runtime, basic_type, dimension - 1, flag)) {
103 0           return 1;
104             }
105             else {
106 0           return 0;
107             }
108             }
109             else {
110 0           return 0;
111             }
112             }
113              
114 0           int32_t SPVM_API_TYPE_is_any_object_array_type(SPVM_RUNTIME* runtime, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension, int32_t flag) {
115            
116             int32_t is_any_object_array_type;
117 0 0         if (type_dimension == 1) {
118 0           int32_t basic_type_category = basic_type->category;
119            
120 0 0         switch (basic_type_category) {
121             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_ANY_OBJECT:
122             {
123 0           is_any_object_array_type = 1;
124 0           break;
125             }
126             default: {
127 0           is_any_object_array_type = 0;
128             }
129             }
130             }
131             else {
132 0           is_any_object_array_type = 0;
133             }
134            
135 0           return is_any_object_array_type;
136             }
137              
138 72           int32_t SPVM_API_TYPE_get_type_width(SPVM_RUNTIME* runtime, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t dimension, int32_t flag) {
139            
140 72           int32_t basic_type_category = basic_type->category;
141            
142 72           int32_t type_width = -1;
143 72 50         if (basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_MULNUM) {
144 72           type_width = basic_type->fields_length;
145             }
146             else {
147 0           type_width = 1;
148             }
149            
150 72           return type_width;
151             }
152              
153 312355           int32_t SPVM_API_TYPE_can_assign(SPVM_RUNTIME* runtime, SPVM_RUNTIME_BASIC_TYPE* dist_basic_type, int32_t dist_type_dimension, int32_t dist_type_flag, SPVM_RUNTIME_BASIC_TYPE* src_basic_type, int32_t src_type_dimension, int32_t src_type_flag) {
154            
155 312355           int32_t isa = 0;
156            
157 312355           char assinability_key[256] = {0};
158 312355           snprintf(assinability_key, 255, "%d-%d-%d-%d-%d-%d", dist_basic_type->id, dist_type_dimension, dist_type_flag, src_basic_type->id, src_type_dimension, src_type_flag);
159            
160            
161 312355           SPVM_MUTEX* mutex_assignability_symtable = runtime->mutex_assignability_symtable;
162            
163 312355           SPVM_MUTEX_reader_lock(mutex_assignability_symtable);
164            
165 312355           int32_t assignability = (intptr_t)SPVM_HASH_get(runtime->assignability_symtable, assinability_key, strlen(assinability_key));
166            
167 312355           SPVM_MUTEX_reader_unlock(mutex_assignability_symtable);
168            
169 312355 100         if (assignability > 0) {
170 308549           isa = 1;
171             }
172 3806 100         else if (assignability < 0) {
173 88           isa = 0;
174             }
175             else {
176            
177 3718           int32_t dist_basic_type_category = dist_basic_type->category;
178 3718           int32_t src_basic_type_category = src_basic_type->category;
179            
180 3718 100         if (dist_basic_type->id == src_basic_type->id && dist_type_dimension == src_type_dimension) {
    100          
181 2868           isa = 1;
182             }
183 850 100         else if (dist_type_dimension == 0 && dist_basic_type_category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_ANY_OBJECT) {
    100          
184 758 50         assert(src_type_dimension >= 0);
185 758           isa = 1;
186             }
187 92 100         else if (dist_type_dimension == 1 && dist_basic_type_category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_ANY_OBJECT) {
    100          
188 8 50         if (src_type_dimension >= 1) {
189 4           isa = 1;
190             }
191             else {
192 0           isa = 0;
193             }
194             }
195 88 100         else if (dist_type_dimension == src_type_dimension) {
196 84 100         if (dist_basic_type_category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_INTERFACE) {
197 18           isa = SPVM_API_BASIC_TYPE_has_interface(runtime, src_basic_type, dist_basic_type);
198             }
199 66 100         else if (dist_basic_type_category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS) {
200 56           isa = SPVM_API_BASIC_TYPE_is_super_class(runtime, dist_basic_type, src_basic_type);
201             }
202             else {
203 84           isa = 0;
204             }
205             }
206             else {
207 4           isa = 0;
208             }
209            
210 3718           SPVM_MUTEX_lock(mutex_assignability_symtable);
211            
212 3718 100         SPVM_HASH_set(runtime->assignability_symtable, assinability_key, strlen(assinability_key), (void*)(intptr_t)(isa ? 1 : -1));
213            
214 3718           SPVM_MUTEX_unlock(mutex_assignability_symtable);
215             }
216            
217 312355           return isa;
218             }
219