File Coverage

lib/SPVM/Builder/src/spvm_api.c
Criterion Covered Total %
statement 1821 2127 85.6
branch 546 784 69.6
condition n/a
subroutine n/a
pod n/a
total 2367 2911 81.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             #include
8              
9             #include "spvm_native.h"
10              
11             #include "spvm_api.h"
12             #include "spvm_vm.h"
13             #include "spvm_api_runtime.h"
14             #include "spvm_api_allocator.h"
15             #include "spvm_api_string_buffer.h"
16             #include "spvm_opcode.h"
17              
18             #include "spvm_strerror.h"
19             #include "spvm_object.h"
20             #include "spvm_allocator.h"
21             #include "spvm_weaken_backref.h"
22             #include "spvm_hash.h"
23             #include "spvm_string_buffer.h"
24              
25             #include "spvm_runtime.h"
26             #include "spvm_runtime_string.h"
27             #include "spvm_runtime_basic_type.h"
28             #include "spvm_runtime_class_var.h"
29             #include "spvm_runtime_field.h"
30             #include "spvm_runtime_method.h"
31              
32             #include "spvm_implement.h"
33              
34             #include "spvm_api_string_buffer.h"
35             #include "spvm_api_compiler.h"
36             #include "spvm_api_runtime.h"
37             #include "spvm_api_class_file.h"
38             #include "spvm_api_basic_type.h"
39             #include "spvm_api_class_var.h"
40             #include "spvm_api_field.h"
41             #include "spvm_api_method.h"
42             #include "spvm_api_arg.h"
43             #include "spvm_api_type.h"
44             #include "spvm_api_internal.h"
45              
46             #include "spvm_mutex.h"
47              
48             static const char* FILE_NAME = "spvm_api.c";
49              
50 119195           SPVM_ENV* SPVM_API_new_env(void) {
51              
52 119195           SPVM_API_ALLOCATOR* api_allocator = SPVM_API_ALLOCATOR_new_api();
53            
54 119195           SPVM_API_STRING_BUFFER* api_string_buffer = SPVM_API_STRING_BUFFER_new_api();
55            
56 119195           SPVM_API_COMPILER* api_compiler = SPVM_API_COMPILER_new_api();
57            
58 119195           SPVM_API_RUNTIME* api_runtime = SPVM_API_RUNTIME_new_api();
59            
60 119195           SPVM_API_CLASS_FILE* api_class_file = SPVM_API_CLASS_FILE_new_api();
61            
62 119195           SPVM_API_BASIC_TYPE* api_basic_type = SPVM_API_BASIC_TYPE_new_api();
63            
64 119195           SPVM_API_CLASS_VAR* api_class_var = SPVM_API_CLASS_VAR_new_api();
65            
66 119195           SPVM_API_FIELD* api_field = SPVM_API_FIELD_new_api();
67            
68 119195           SPVM_API_TYPE* api_type = SPVM_API_TYPE_new_api();
69            
70 119195           SPVM_API_METHOD* api_method = SPVM_API_METHOD_new_api();
71            
72 119195           SPVM_API_ARG* api_arg = SPVM_API_ARG_new_api();
73            
74 119195           SPVM_API_INTERNAL* api_internal = SPVM_API_INTERNAL_new_api();
75            
76 119195           void* env_api_init[] = {
77             api_allocator,
78             api_string_buffer,
79             api_compiler,
80             api_class_file,
81             api_runtime,
82             api_basic_type,
83             api_class_var,
84             api_field,
85             api_method,
86             api_arg,
87             api_type,
88             api_internal,
89             };
90 119195           SPVM_ENV_API* env_api = calloc(1, sizeof(env_api_init));
91 119195           memcpy(env_api, env_api_init, sizeof(env_api_init));
92              
93              
94              
95              
96              
97              
98             // Native APIs
99 119195           void* env_init[] = {
100             NULL, // compiler
101             NULL, // runtime
102             env_api, // api
103             SPVM_API_new_env,
104             SPVM_API_free_env,
105             SPVM_API_call_init_methods,
106             SPVM_API_set_command_info_program_name,
107             SPVM_API_set_command_info_argv,
108             SPVM_API_set_command_info_base_time,
109             SPVM_API_destroy_class_vars,
110             SPVM_API_args_width,
111             SPVM_API_get_object_basic_type,
112             SPVM_API_get_object_basic_type_id,
113             SPVM_API_get_object_basic_type_name,
114             SPVM_API_get_object_type_dimension,
115             SPVM_API_get_basic_type,
116             SPVM_API_get_basic_type_by_name,
117             SPVM_API_get_basic_type_by_id,
118             SPVM_API_get_basic_type_id,
119             SPVM_API_get_basic_type_id_by_name,
120             SPVM_API_get_class_var,
121             SPVM_API_get_class_var_byte,
122             SPVM_API_get_class_var_short,
123             SPVM_API_get_class_var_int,
124             SPVM_API_get_class_var_long,
125             SPVM_API_get_class_var_float,
126             SPVM_API_get_class_var_double,
127             SPVM_API_get_class_var_object,
128             SPVM_API_get_class_var_string,
129             SPVM_API_set_class_var_byte,
130             SPVM_API_set_class_var_short,
131             SPVM_API_set_class_var_int,
132             SPVM_API_set_class_var_long,
133             SPVM_API_set_class_var_float,
134             SPVM_API_set_class_var_double,
135             SPVM_API_set_class_var_object,
136             SPVM_API_set_class_var_string,
137             SPVM_API_get_class_var_object_ref,
138             SPVM_API_get_class_var_byte_by_name,
139             SPVM_API_get_class_var_short_by_name,
140             SPVM_API_get_class_var_int_by_name,
141             SPVM_API_get_class_var_long_by_name,
142             SPVM_API_get_class_var_float_by_name,
143             SPVM_API_get_class_var_double_by_name,
144             SPVM_API_get_class_var_object_by_name,
145             SPVM_API_get_class_var_string_by_name,
146             SPVM_API_set_class_var_byte_by_name,
147             SPVM_API_set_class_var_short_by_name,
148             SPVM_API_set_class_var_int_by_name,
149             SPVM_API_set_class_var_long_by_name,
150             SPVM_API_set_class_var_float_by_name,
151             SPVM_API_set_class_var_double_by_name,
152             SPVM_API_set_class_var_object_by_name,
153             SPVM_API_set_class_var_string_by_name,
154             SPVM_API_get_field,
155             SPVM_API_get_field_static,
156             SPVM_API_get_field_byte,
157             SPVM_API_get_field_short,
158             SPVM_API_get_field_int,
159             SPVM_API_get_field_long,
160             SPVM_API_get_field_float,
161             SPVM_API_get_field_double,
162             SPVM_API_get_field_object,
163             SPVM_API_get_field_string,
164             SPVM_API_set_field_byte,
165             SPVM_API_set_field_short,
166             SPVM_API_set_field_int,
167             SPVM_API_set_field_long,
168             SPVM_API_set_field_float,
169             SPVM_API_set_field_double,
170             SPVM_API_set_field_object,
171             SPVM_API_set_field_string,
172             SPVM_API_get_field_byte_by_name,
173             SPVM_API_get_field_short_by_name,
174             SPVM_API_get_field_int_by_name,
175             SPVM_API_get_field_long_by_name,
176             SPVM_API_get_field_float_by_name,
177             SPVM_API_get_field_double_by_name,
178             SPVM_API_get_field_object_by_name,
179             SPVM_API_get_field_string_by_name,
180             SPVM_API_set_field_byte_by_name,
181             SPVM_API_set_field_short_by_name,
182             SPVM_API_set_field_int_by_name,
183             SPVM_API_set_field_long_by_name,
184             SPVM_API_set_field_float_by_name,
185             SPVM_API_set_field_double_by_name,
186             SPVM_API_set_field_object_by_name,
187             SPVM_API_set_field_string_by_name,
188             SPVM_API_get_field_string_chars_by_name,
189             SPVM_API_get_method,
190             SPVM_API_get_class_method,
191             SPVM_API_get_instance_method_static,
192             SPVM_API_get_instance_method,
193             SPVM_API_call_method_no_mortal,
194             SPVM_API_call_method,
195             SPVM_API_call_class_method_by_name,
196             SPVM_API_call_instance_method_static_by_name,
197             SPVM_API_call_instance_method_by_name,
198             SPVM_API_new_object_no_mortal,
199             SPVM_API_new_object,
200             SPVM_API_new_object_by_name,
201             SPVM_API_new_pointer_object_no_mortal,
202             SPVM_API_new_pointer_object,
203             SPVM_API_new_pointer_object_by_name,
204             SPVM_API_get_pointer,
205             SPVM_API_set_pointer,
206             SPVM_API_new_string_nolen_no_mortal,
207             SPVM_API_new_string_nolen,
208             SPVM_API_new_string_no_mortal,
209             SPVM_API_new_string,
210             SPVM_API_new_byte_array_no_mortal,
211             SPVM_API_new_byte_array,
212             SPVM_API_new_short_array_no_mortal,
213             SPVM_API_new_short_array,
214             SPVM_API_new_int_array_no_mortal,
215             SPVM_API_new_int_array,
216             SPVM_API_new_long_array_no_mortal,
217             SPVM_API_new_long_array,
218             SPVM_API_new_float_array_no_mortal,
219             SPVM_API_new_float_array,
220             SPVM_API_new_double_array_no_mortal,
221             SPVM_API_new_double_array,
222             SPVM_API_new_object_array_no_mortal,
223             SPVM_API_new_object_array,
224             SPVM_API_new_object_array_by_name,
225             SPVM_API_new_string_array,
226             SPVM_API_new_muldim_array_no_mortal,
227             SPVM_API_new_muldim_array,
228             SPVM_API_new_muldim_array_by_name,
229             SPVM_API_new_mulnum_array_no_mortal,
230             SPVM_API_new_mulnum_array,
231             SPVM_API_new_mulnum_array_by_name,
232             SPVM_API_new_array_proto_no_mortal,
233             SPVM_API_new_array_proto,
234             SPVM_API_length,
235             SPVM_API_get_elems_byte,
236             SPVM_API_get_elems_short,
237             SPVM_API_get_elems_int,
238             SPVM_API_get_elems_long,
239             SPVM_API_get_elems_float,
240             SPVM_API_get_elems_double,
241             SPVM_API_get_elem_object,
242             SPVM_API_get_elem_string,
243             SPVM_API_set_elem_object,
244             SPVM_API_set_elem_string,
245             SPVM_API_get_chars,
246             SPVM_API_get_bool_object_value,
247             SPVM_API_concat_no_mortal,
248             SPVM_API_concat,
249             SPVM_API_shorten,
250             SPVM_API_make_read_only,
251             SPVM_API_is_read_only,
252             SPVM_API_print,
253             SPVM_API_print_stderr,
254             SPVM_API_dump_no_mortal,
255             SPVM_API_dump,
256             SPVM_API_dumpc,
257             SPVM_API_copy_no_mortal,
258             SPVM_API_copy,
259             SPVM_API_get_spvm_version_string,
260             SPVM_API_get_spvm_version_number,
261             SPVM_API_get_version_string,
262             SPVM_API_get_version_number,
263             SPVM_API_die,
264             SPVM_API_get_exception,
265             SPVM_API_set_exception,
266             SPVM_API_new_stack_trace_no_mortal,
267             SPVM_API_new_stack_trace,
268             SPVM_API_is_string,
269             SPVM_API_is_class,
270             SPVM_API_is_pointer_class,
271             SPVM_API_is_array,
272             SPVM_API_is_object_array,
273             SPVM_API_is_numeric_array,
274             SPVM_API_is_mulnum_array,
275             SPVM_API_isa,
276             SPVM_API_isa_by_name,
277             SPVM_API_is_type,
278             SPVM_API_is_type_by_name,
279             SPVM_API_elem_isa,
280             SPVM_API_get_elem_size,
281             SPVM_API_get_type_name_no_mortal,
282             SPVM_API_get_type_name,
283             SPVM_API_get_compile_type_name_no_mortal,
284             SPVM_API_get_compile_type_name,
285             SPVM_API_enter_scope,
286             SPVM_API_leave_scope,
287             SPVM_API_push_mortal,
288             NULL,
289             SPVM_API_weaken,
290             SPVM_API_isweak,
291             SPVM_API_unweaken,
292             SPVM_API_strerror_string,
293             SPVM_API_strerror_string_nolen,
294             SPVM_API_strerror,
295             SPVM_API_strerror_nolen,
296             NULL,
297             NULL,
298             NULL,
299             NULL,
300             SPVM_API_new_memory_stack,
301             SPVM_API_free_memory_stack,
302             SPVM_API_get_memory_blocks_count_stack,
303             SPVM_API_new_stack,
304             SPVM_API_free_stack,
305             SPVM_API_get_ref_count,
306             NULL,
307             NULL,
308             SPVM_API_get_field_object_defined_and_has_pointer_by_name,
309             SPVM_API_get_field_object_ref,
310             SPVM_API_get_field_object_ref_by_name,
311             SPVM_API_check_stack_env,
312             NULL,
313             NULL,
314             SPVM_API_assign_object,
315             SPVM_API_new_string_array_no_mortal,
316             SPVM_API_new_memory_block,
317             SPVM_API_free_memory_block,
318             SPVM_API_get_memory_blocks_count,
319             };
320 119195           SPVM_ENV* env = calloc(1, sizeof(env_init));
321 119195 50         if (env == NULL) {
322 0           return NULL;
323             }
324 119195           memcpy(env, env_init, sizeof(env_init));
325            
326 119195           return env;
327             }
328              
329 119195           void SPVM_API_free_env(SPVM_ENV* env) {
330              
331             // Free env api
332 119195           SPVM_API_ALLOCATOR_free_api(env->api->allocator);
333 119195           SPVM_API_STRING_BUFFER_free_api(env->api->string_buffer);
334 119195           SPVM_API_COMPILER_free_api(env->api->compiler);
335 119195           SPVM_API_RUNTIME_free_api(env->api->runtime);
336 119195           SPVM_API_CLASS_FILE_free_api(env->api->class_file);
337 119195           SPVM_API_BASIC_TYPE_free_api(env->api->basic_type);
338 119195           SPVM_API_CLASS_VAR_free_api(env->api->class_var);
339 119195           SPVM_API_FIELD_free_api(env->api->field);
340 119195           SPVM_API_TYPE_free_api(env->api->type);
341 119195           SPVM_API_METHOD_free_api(env->api->method);
342 119195           SPVM_API_ARG_free_api(env->api->arg);
343 119195           SPVM_API_INTERNAL_free_api(env->api->internal);
344            
345 119195           free(env->api);
346            
347             // Free env
348 119195           free(env);
349 119195           env = NULL;
350 119195           }
351              
352 488           int32_t SPVM_API_call_init_methods(SPVM_ENV* env, SPVM_VALUE* stack) {
353            
354 488           int32_t error_id = 0;
355            
356             // Runtime
357 488           SPVM_RUNTIME* runtime = env->runtime;
358            
359             // Call INIT blocks
360 488           int32_t basic_types_length = runtime->basic_types_length;
361 25260 100         for (int32_t basic_type_id = 0; basic_type_id < basic_types_length; basic_type_id++) {
362 24772           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(env->runtime, basic_type_id);
363 24772 100         if (basic_type->init_method) {
364 15304           SPVM_RUNTIME_METHOD* init_method = SPVM_API_BASIC_TYPE_get_method_by_index(env->runtime, basic_type, basic_type->init_method->index);
365 15304           int32_t args_width = 0;
366 15304           error_id = SPVM_API_call_method_no_mortal(env, stack, init_method, args_width);
367 15304 50         if (error_id) { break; }
368             }
369             }
370            
371 488           return error_id;
372             }
373              
374 336           int32_t SPVM_API_set_command_info_program_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* obj_program_name) {
375            
376 336           int32_t error_id = 0;
377            
378 336 50         if (!obj_program_name) {
379 0           return SPVM_API_die(env, stack, "The obj_program_name must be defined", __func__, FILE_NAME, __LINE__);
380             }
381            
382 336           SPVM_RUNTIME_BASIC_TYPE* obj_program_name_basic_type = SPVM_API_get_object_basic_type(env, stack, obj_program_name);
383 336 50         if (!(obj_program_name_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_STRING && obj_program_name->type_dimension == 0)) {
    50          
384 0           return SPVM_API_die(env, stack, "The obj_program_name must be a string", __func__, FILE_NAME, __LINE__);
385             }
386            
387 336           SPVM_API_set_class_var_object_by_name(env, stack, "CommandInfo", "$PROGRAM_NAME", obj_program_name, &error_id, __func__, __FILE__, __LINE__);
388 336 50         if (error_id) { return error_id; }
389            
390 336           return 0;
391             }
392              
393 336           int32_t SPVM_API_set_command_info_argv(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* obj_argv) {
394            
395 336           int32_t error_id = 0;
396            
397 336 50         if (!obj_argv) {
398 0           return SPVM_API_die(env, stack, "The obj_argv must be defined", __func__, FILE_NAME, __LINE__);
399             }
400            
401 336           SPVM_RUNTIME_BASIC_TYPE* obj_argv_basic_type = SPVM_API_get_object_basic_type(env, stack, obj_argv);
402 336 50         if (!(obj_argv_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_STRING && obj_argv->type_dimension == 1)) {
    50          
403 0           return SPVM_API_die(env, stack, "The obj_argv must be a string array", __func__, FILE_NAME, __LINE__);
404             }
405            
406 336           SPVM_API_set_class_var_object_by_name(env, stack, "CommandInfo", "$ARGV", obj_argv, &error_id, __func__, __FILE__, __LINE__);
407 336 50         if (error_id) { return error_id; }
408            
409 336           return 0;
410             }
411              
412 336           int32_t SPVM_API_set_command_info_base_time(SPVM_ENV* env, SPVM_VALUE* stack, int64_t base_time) {
413            
414 336           int32_t error_id = 0;
415            
416 336           SPVM_API_set_class_var_long_by_name(env, stack, "CommandInfo", "$BASE_TIME", base_time, &error_id, __func__, __FILE__, __LINE__);
417 336 50         if (error_id) { return error_id; }
418            
419 336           return 0;
420             }
421              
422 336           void SPVM_API_destroy_class_vars(SPVM_ENV* env, SPVM_VALUE* stack){
423              
424             // Runtime
425 336           SPVM_RUNTIME* runtime = env->runtime;
426            
427             // Free objects of class variables
428 15619 100         for (int32_t basic_type_id = 0; basic_type_id < runtime->basic_types_length; basic_type_id++) {
429 15283           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(env->runtime, basic_type_id);
430            
431 17597 100         for (int32_t class_var_index = 0; class_var_index < basic_type->class_vars_length; class_var_index++) {
432            
433 2314           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_index(runtime, basic_type, class_var_index);
434            
435 2314           SPVM_RUNTIME_BASIC_TYPE* class_var_basic_type = class_var->basic_type;
436 2314           int32_t class_var_type_dimension = class_var->type_dimension;
437 2314           int32_t class_var_type_flag = class_var->type_flag;
438            
439 2314           int32_t class_var_type_is_object = SPVM_API_TYPE_is_object_type(runtime, class_var_basic_type, class_var_type_dimension, class_var_type_flag);
440 2314 100         if (class_var_type_is_object) {
441 1446           SPVM_OBJECT** object_ref = (SPVM_OBJECT**)&class_var->data;
442 1446           SPVM_API_assign_object(env, stack, object_ref, NULL);
443             }
444             }
445             }
446 336           }
447              
448 670139           int32_t SPVM_API_args_width(SPVM_ENV* env, SPVM_VALUE* stack) {
449 670139           int32_t args_length = stack[SPVM_API_C_STACK_INDEX_ARGS_WIDTH].ival;
450            
451 670139           return args_length;
452             }
453              
454 4           int32_t SPVM_API_get_basic_type_id(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name) {
455            
456              
457 4           SPVM_RUNTIME* runtime = env->runtime;
458              
459 4 50         if (basic_type_name == NULL) {
460 0           return -1;
461             }
462              
463 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_RUNTIME_get_basic_type_by_name(runtime, basic_type_name);
464 4 100         if (basic_type) {
465 2           int32_t basic_type_id = basic_type->id;
466 2           return basic_type_id;
467             }
468             else {
469 2           return -1;
470             }
471             }
472              
473 282407           SPVM_RUNTIME_BASIC_TYPE* SPVM_API_get_basic_type(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name) {
474            
475              
476 282407           SPVM_RUNTIME* runtime = env->runtime;
477              
478 282407 50         if (basic_type_name == NULL) {
479 0           return NULL;
480             }
481              
482 282407           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_RUNTIME_get_basic_type_by_name(runtime, basic_type_name);
483            
484 282407           return basic_type;
485             }
486              
487 16           void SPVM_API_call_class_method_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* method_name, int32_t args_width, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
488            
489 16           *error_id = 0;
490            
491 16           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
492 16           SPVM_RUNTIME_METHOD* method = SPVM_API_BASIC_TYPE_get_method_by_name(env->runtime, basic_type, method_name);
493 16 100         if (!method) {
494 2           *error_id = SPVM_API_die(env, stack, "The %s class method in the %s class is not found", method_name, basic_type_name, func_name, file, line);
495 2           return;
496             }
497 14           *error_id = SPVM_API_call_method_no_mortal(env, stack, method, args_width);
498 14 50         if (*error_id) {
499 0           const char* message = SPVM_API_get_chars(env, stack, SPVM_API_get_exception(env, stack));
500 0           SPVM_API_die(env, stack, "%s", message, func_name, file, line);
501             }
502             }
503              
504 4           void SPVM_API_call_instance_method_static_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* method_name, int32_t args_width, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
505            
506 4           *error_id = 0;
507            
508 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
509 4           SPVM_RUNTIME_METHOD* method = SPVM_API_BASIC_TYPE_get_method_by_name(env->runtime, basic_type, method_name);
510 4 100         if (!method) {
511 2           *error_id = SPVM_API_die(env, stack, "The %s instance method in the %s class is not found", method_name, basic_type_name, func_name, file, line);
512 2           return;
513             }
514 2           *error_id = SPVM_API_call_method_no_mortal(env, stack, method, args_width);
515 2 50         if (*error_id) {
516 0           const char* message = SPVM_API_get_chars(env, stack, SPVM_API_get_exception(env, stack));
517 0           SPVM_API_die(env, stack, "%s", message, func_name, file, line);
518             }
519             }
520              
521 348           void SPVM_API_call_instance_method_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* method_name, int32_t args_width, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
522            
523 348           *error_id = 0;
524            
525 348           SPVM_OBJECT* object = stack[0].oval;
526            
527 348 50         if (object == NULL) {
528 0           *error_id = SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
529 0           return;
530             };
531            
532 348 50         if (object->type_dimension > 0) {
533 0           *error_id = SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
534 0           return;
535             };
536            
537 348           SPVM_RUNTIME_METHOD* method = SPVM_API_get_instance_method(env, stack, object, method_name);
538 348 100         if (!method) {
539 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
540 2           *error_id = SPVM_API_die(env, stack, "The %s instance method is not found in the %s class or its super class", method_name, basic_type_name, func_name, file, line);
541 2           return;
542             };
543            
544 346           *error_id = SPVM_API_call_method_no_mortal(env, stack, method, args_width);
545            
546 346 100         if (*error_id) {
547 2           const char* message = SPVM_API_get_chars(env, stack, SPVM_API_get_exception(env, stack));
548 2           SPVM_API_die(env, stack, "%s", message, func_name, file, line);
549             }
550             }
551              
552 8           void* SPVM_API_new_object_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
553 8           *error_id = 0;
554            
555 8           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
556 8 100         if (!basic_type) {
557 2           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
558 2           *error_id = 1;
559 2           return NULL;
560             };
561            
562 6           void* object = SPVM_API_new_object(env, stack, basic_type);
563            
564 6           return object;
565             }
566              
567 233432           SPVM_OBJECT* SPVM_API_new_pointer_object_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, void* pointer, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
568 233432           *error_id = 0;
569            
570 233432           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
571 233432 100         if (!basic_type) {
572 2           *error_id = 1;
573 2           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
574 2           return NULL;
575             };
576 233430           SPVM_OBJECT* object = SPVM_API_new_pointer_object(env, stack, basic_type, pointer);
577            
578 233430           return object;
579             }
580              
581 0           SPVM_OBJECT* SPVM_API_new_object_array_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t length, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
582 0           *error_id = 0;
583            
584 0           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
585 0 0         if (!basic_type) {
586 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
587 0           *error_id = 1;
588 0           return NULL;
589             };
590            
591 0           void* object = SPVM_API_new_object_array(env, stack, basic_type, length);
592            
593 0           return object;
594             }
595              
596 0           SPVM_OBJECT* SPVM_API_new_muldim_array_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t type_dimension, int32_t length, int32_t* error_id, const char* func_name, const char* file, int32_t line) { *error_id = 0;
597            
598 0           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
599 0 0         if (!basic_type) {
600 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
601 0           *error_id = 1;
602 0           return NULL;
603             };
604            
605 0           void* object = SPVM_API_new_muldim_array(env, stack, basic_type, type_dimension, length);
606            
607 0           return object;
608             }
609              
610 0           SPVM_OBJECT* SPVM_API_new_mulnum_array_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t length, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
611 0           *error_id = 0;
612            
613 0           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
614 0 0         if (!basic_type) {
615 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
616 0           *error_id = 1;
617 0           return NULL;
618             };
619            
620 0           void* object = SPVM_API_new_mulnum_array(env, stack, basic_type, length);
621            
622 0           return object;
623             }
624              
625 28           int8_t SPVM_API_get_class_var_byte(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
626            
627 28           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
628            
629 28 50         assert(basic_type);
630            
631 28           int32_t class_vars_length = basic_type->class_vars_length;
632            
633 28 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
634            
635 28           int8_t value = class_var->data.bval;
636            
637 28           return value;
638             }
639              
640 28           int16_t SPVM_API_get_class_var_short(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
641            
642 28           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
643            
644 28 50         assert(basic_type);
645            
646 28           int32_t class_vars_length = basic_type->class_vars_length;
647            
648 28 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
649            
650 28           int16_t value = class_var->data.sval;
651            
652 28           return value;
653             }
654              
655 96           int32_t SPVM_API_get_class_var_int(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
656            
657 96           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
658            
659 96 50         assert(basic_type);
660            
661 96           int32_t class_vars_length = basic_type->class_vars_length;
662            
663 96 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
664            
665 96           int32_t value = class_var->data.ival;
666            
667 96           return value;
668             }
669              
670 36           int64_t SPVM_API_get_class_var_long(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
671            
672 36           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
673            
674            
675 36 50         assert(basic_type);
676            
677 36           int32_t class_vars_length = basic_type->class_vars_length;
678            
679 36 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
680            
681 36           int64_t value = class_var->data.lval;
682            
683 36           return value;
684             }
685              
686 28           float SPVM_API_get_class_var_float(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
687            
688 28           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
689            
690 28 50         assert(basic_type);
691            
692 28           int32_t class_vars_length = basic_type->class_vars_length;
693            
694 28 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
695            
696 28           float value = class_var->data.fval;
697            
698 28           return value;
699             }
700              
701 28           double SPVM_API_get_class_var_double(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
702            
703 28           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
704            
705 28 50         assert(basic_type);
706            
707 28           int32_t class_vars_length = basic_type->class_vars_length;
708            
709 28 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
710            
711 28           double value = class_var->data.dval;
712            
713 28           return value;
714             }
715              
716 754           SPVM_OBJECT* SPVM_API_get_class_var_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
717            
718 754           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
719            
720 754 50         assert(basic_type);
721            
722 754           int32_t class_vars_length = basic_type->class_vars_length;
723            
724 754 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
725            
726 754           SPVM_OBJECT* value_maybe_weaken = (SPVM_OBJECT*)class_var->data.oval;
727 754           SPVM_OBJECT* value = SPVM_API_get_object_no_weaken_address(env, stack, value_maybe_weaken);
728            
729 754           return value;
730             }
731              
732 678           SPVM_OBJECT** SPVM_API_get_class_var_object_ref(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
733            
734 678           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
735            
736 678 50         assert(basic_type);
737            
738 678           int32_t class_vars_length = basic_type->class_vars_length;
739            
740 678 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
741            
742 678           SPVM_OBJECT** object_ref = (SPVM_OBJECT**)&class_var->data.oval;
743            
744 678           return object_ref;
745             }
746              
747 0           SPVM_OBJECT* SPVM_API_get_class_var_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
748            
749 0           return SPVM_API_get_class_var_object(env, stack, class_var);
750             }
751              
752 28           void SPVM_API_set_class_var_byte(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, int8_t value) {
753            
754 28           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
755            
756 28 50         assert(basic_type);
757            
758 28           int32_t class_vars_length = basic_type->class_vars_length;
759            
760 28 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
761            
762 28           class_var->data.bval = value;
763 28           }
764              
765 28           void SPVM_API_set_class_var_short(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, int16_t value) {
766            
767 28           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
768            
769 28 50         assert(basic_type);
770            
771 28           int32_t class_vars_length = basic_type->class_vars_length;
772            
773 28 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
774            
775 28           class_var->data.sval = value;
776 28           }
777              
778 92           void SPVM_API_set_class_var_int(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, int32_t value) {
779            
780 92           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
781            
782 92 50         assert(basic_type);
783            
784 92           int32_t class_vars_length = basic_type->class_vars_length;
785            
786 92 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
787            
788 92           class_var->data.ival = value;
789 92           }
790              
791 368           void SPVM_API_set_class_var_long(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, int64_t value) {
792            
793 368           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
794            
795 368 50         assert(basic_type);
796            
797 368           int32_t class_vars_length = basic_type->class_vars_length;
798            
799 368 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
800            
801 368           class_var->data.lval = value;
802 368           }
803              
804 28           void SPVM_API_set_class_var_float(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, float value) {
805            
806 28           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
807            
808 28 50         assert(basic_type);
809            
810 28           int32_t class_vars_length = basic_type->class_vars_length;
811            
812 28 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
813            
814 28           class_var->data.fval = value;
815 28           }
816              
817 28           void SPVM_API_set_class_var_double(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, double value) {
818            
819 28           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
820            
821 28 50         assert(basic_type);
822            
823 28           int32_t class_vars_length = basic_type->class_vars_length;
824            
825 28 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
826            
827 28           class_var->data.dval = value;
828 28           }
829              
830 674           void SPVM_API_set_class_var_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, SPVM_OBJECT* value) {
831            
832 674           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
833            
834 674 50         assert(basic_type);
835            
836 674           int32_t class_vars_length = basic_type->class_vars_length;
837            
838 674 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
839            
840 674           void* object_ref = &class_var->data.oval;
841 674           SPVM_API_assign_object(env, stack, object_ref, value);
842 674           }
843              
844 0           void SPVM_API_set_class_var_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, SPVM_OBJECT* value) {
845            
846 0           SPVM_API_set_class_var_object(env, stack, class_var, value);
847 0           }
848              
849 4           int8_t SPVM_API_get_class_var_byte_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
850 4           *error_id = 0;
851            
852 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
853 4 50         if (!basic_type) {
854 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
855 0           *error_id = 1;
856 0           return 0;
857             }
858            
859 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
860 4 100         if (!class_var) {
861 2           *error_id = 1;
862 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
863 2           return 0;
864             };
865            
866 2           int8_t value = SPVM_API_get_class_var_byte(env, stack, class_var);
867 2           return value;
868             }
869              
870 4           int16_t SPVM_API_get_class_var_short_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
871 4           *error_id = 0;
872            
873 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
874 4 50         if (!basic_type) {
875 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
876 0           *error_id = 1;
877 0           return 0;
878             }
879            
880 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
881 4 100         if (!class_var) {
882 2           *error_id = 1;
883 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
884 2           return 0;
885             };
886            
887 2           int16_t value = SPVM_API_get_class_var_short(env, stack, class_var);
888 2           return value;
889             }
890              
891 4           int32_t SPVM_API_get_class_var_int_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
892 4           *error_id = 0;
893            
894 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
895 4 50         if (!basic_type) {
896 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
897 0           *error_id = 1;
898 0           return 0;
899             }
900            
901 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
902 4 100         if (!class_var) {
903 2           *error_id = 1;
904 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
905 2           return 0;
906             };
907            
908 2           int32_t value = SPVM_API_get_class_var_int(env, stack, class_var);
909 2           return value;
910             }
911              
912 4           int64_t SPVM_API_get_class_var_long_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
913 4           *error_id = 0;
914            
915 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
916 4 50         if (!basic_type) {
917 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
918 0           *error_id = 1;
919 0           return 0;
920             }
921            
922 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
923 4 100         if (!class_var) {
924 2           *error_id = 1;
925 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
926 2           return 0;
927             };
928            
929 2           int64_t value = SPVM_API_get_class_var_long(env, stack, class_var);
930 2           return value;
931             }
932              
933 4           float SPVM_API_get_class_var_float_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
934 4           *error_id = 0;
935            
936 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
937 4 50         if (!basic_type) {
938 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
939 0           *error_id = 1;
940 0           return 0;
941             }
942            
943 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
944 4 100         if (!class_var) {
945 2           *error_id = 1;
946 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
947 2           return 0;
948             };
949            
950 2           float value = SPVM_API_get_class_var_float(env, stack, class_var);
951 2           return value;
952             }
953              
954 4           double SPVM_API_get_class_var_double_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
955 4           *error_id = 0;
956            
957 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
958 4 50         if (!basic_type) {
959 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
960 0           *error_id = 1;
961 0           return 0;
962             }
963            
964 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
965 4 100         if (!class_var) {
966 2           *error_id = 1;
967 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
968 2           return 0;
969             };
970            
971 2           double value = SPVM_API_get_class_var_double(env, stack, class_var);
972 2           return value;
973             }
974              
975 4           SPVM_OBJECT* SPVM_API_get_class_var_object_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
976 4           *error_id = 0;
977            
978 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
979 4 50         if (!basic_type) {
980 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
981 0           *error_id = 1;
982 0           return 0;
983             }
984            
985 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
986 4 100         if (!class_var) {
987 2           *error_id = 1;
988 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
989 2           return 0;
990             };
991            
992 2           SPVM_OBJECT* value = SPVM_API_get_class_var_object(env, stack, class_var);
993 2           return value;
994             }
995              
996 0           SPVM_OBJECT* SPVM_API_get_class_var_string_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
997 0           *error_id = 0;
998            
999 0           return SPVM_API_get_class_var_object_by_name(env, stack, basic_type_name, class_var_name, error_id, func_name, file, line);
1000             }
1001              
1002 4           void SPVM_API_set_class_var_byte_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int8_t value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1003 4           *error_id = 0;
1004            
1005 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1006 4 50         if (!basic_type) {
1007 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
1008 0           *error_id = 1;
1009 0           return;
1010             }
1011            
1012 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1013 4 100         if (!class_var) {
1014 2           *error_id = 1;
1015 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
1016 2           return;
1017             };
1018            
1019 2           SPVM_API_set_class_var_byte(env, stack, class_var, value);
1020             }
1021              
1022 4           void SPVM_API_set_class_var_short_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int16_t value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1023 4           *error_id = 0;
1024            
1025 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1026 4 50         if (!basic_type) {
1027 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
1028 0           *error_id = 1;
1029 0           return;
1030             }
1031            
1032 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1033 4 100         if (!class_var) {
1034 2           *error_id = 1;
1035 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
1036 2           return;
1037             };
1038            
1039 2           SPVM_API_set_class_var_short(env, stack, class_var, value);
1040             }
1041              
1042 4           void SPVM_API_set_class_var_int_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int32_t value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1043 4           *error_id = 0;
1044            
1045 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1046 4 50         if (!basic_type) {
1047 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
1048 0           *error_id = 1;
1049 0           return;
1050             }
1051            
1052 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1053 4 100         if (!class_var) {
1054 2           *error_id = 1;
1055 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
1056 2           return;
1057             };
1058            
1059 2           SPVM_API_set_class_var_int(env, stack, class_var, value);
1060             }
1061              
1062 340           void SPVM_API_set_class_var_long_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, int64_t value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1063 340           *error_id = 0;
1064            
1065 340           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1066 340 50         if (!basic_type) {
1067 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
1068 0           *error_id = 1;
1069 0           return;
1070             }
1071            
1072 340           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1073 340 100         if (!class_var) {
1074 2           *error_id = 1;
1075 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
1076 2           return;
1077             };
1078            
1079 338           SPVM_API_set_class_var_long(env, stack, class_var, value);
1080             }
1081              
1082 4           void SPVM_API_set_class_var_float_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, float value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1083 4           *error_id = 0;
1084            
1085 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1086 4 50         if (!basic_type) {
1087 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
1088 0           *error_id = 1;
1089 0           return;
1090             }
1091            
1092 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1093 4 100         if (!class_var) {
1094 2           *error_id = 1;
1095 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
1096 2           return;
1097             };
1098            
1099 2           SPVM_API_set_class_var_float(env, stack, class_var, value);
1100             }
1101              
1102 4           void SPVM_API_set_class_var_double_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, double value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1103 4           *error_id = 0;
1104            
1105 4           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1106 4 50         if (!basic_type) {
1107 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
1108 0           *error_id = 1;
1109 0           return;
1110             }
1111            
1112 4           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1113 4 100         if (!class_var) {
1114 2           *error_id = 1;
1115 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
1116 2           return;
1117             };
1118            
1119 2           SPVM_API_set_class_var_double(env, stack, class_var, value);
1120             }
1121              
1122 676           void SPVM_API_set_class_var_object_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, SPVM_OBJECT* value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1123 676           *error_id = 0;
1124            
1125 676           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1126 676 50         if (!basic_type) {
1127 0           SPVM_API_die(env, stack, "The %s class is not found", basic_type_name, func_name, file, line);
1128 0           *error_id = 1;
1129 0           return;
1130             }
1131            
1132 676           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1133 676 100         if (!class_var) {
1134 2           *error_id = 1;
1135 2           SPVM_API_die(env, stack, "The %s class variable in the %s class is not found", class_var_name, basic_type_name, func_name, file, line);
1136 2           return;
1137             };
1138            
1139 674           SPVM_API_set_class_var_object(env, stack, class_var, value);
1140             }
1141              
1142 0           void SPVM_API_set_class_var_string_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name, SPVM_OBJECT* value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1143 0           SPVM_API_set_class_var_object_by_name(env, stack, basic_type_name, class_var_name, value, error_id, func_name, file, line);
1144 0           }
1145              
1146 700           int8_t SPVM_API_get_field_byte(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1147              
1148 700           int8_t value = *(int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1149              
1150 700           return value;
1151             }
1152              
1153 10           int16_t SPVM_API_get_field_short(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1154              
1155 10           int16_t value = *(int16_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1156            
1157 10           return value;
1158             }
1159              
1160 20           int32_t SPVM_API_get_field_int(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1161              
1162 20           int32_t value = *(int32_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1163            
1164 20           return value;
1165             }
1166              
1167 10           int64_t SPVM_API_get_field_long(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1168              
1169 10           int64_t value = *(int64_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1170            
1171 10           return value;
1172             }
1173              
1174 10           float SPVM_API_get_field_float(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1175              
1176 10           float value = *(float*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1177            
1178 10           return value;
1179             }
1180              
1181 10           double SPVM_API_get_field_double(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1182              
1183 10           double value = *(double*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1184            
1185 10           return value;
1186             }
1187              
1188 516927           SPVM_OBJECT* SPVM_API_get_field_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1189              
1190 516927           SPVM_OBJECT* value_maybe_weaken = *(SPVM_OBJECT**)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1191 516927           SPVM_OBJECT* value = SPVM_API_get_object_no_weaken_address(env, stack, value_maybe_weaken);
1192            
1193 516927           return value;
1194             }
1195              
1196 346           SPVM_OBJECT** SPVM_API_get_field_object_ref(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1197              
1198 346           SPVM_OBJECT** object_ref = (SPVM_OBJECT**)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1199            
1200 346           return object_ref;
1201             }
1202              
1203 2           SPVM_OBJECT* SPVM_API_get_field_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1204            
1205 2           SPVM_OBJECT* value = SPVM_API_get_field_object(env, stack, object, field);
1206            
1207 2           return value;
1208             }
1209              
1210 14           void SPVM_API_set_field_byte(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field, int8_t value) {
1211              
1212             // Get field value
1213 14           *(int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset) = value;
1214 14           }
1215              
1216 2           void SPVM_API_set_field_short(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field, int16_t value) {
1217              
1218             // Get field value
1219 2           *(int16_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset) = value;
1220 2           }
1221              
1222 6           void SPVM_API_set_field_int(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field, int32_t value) {
1223              
1224             // Get field value
1225 6           *(int32_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset) = value;
1226 6           }
1227              
1228 2           void SPVM_API_set_field_long(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field, int64_t value) {
1229              
1230             // Get field value
1231 2           *(int64_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset) = value;
1232 2           }
1233              
1234 2           void SPVM_API_set_field_float(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field, float value) {
1235              
1236             // Get field value
1237 2           *(float*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset) = value;
1238 2           }
1239              
1240 2           void SPVM_API_set_field_double(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field, double value) {
1241              
1242             // Get field value
1243 2           *(double*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset) = value;
1244 2           }
1245              
1246 233692           void SPVM_API_set_field_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field, SPVM_OBJECT* value) {
1247              
1248             // Get field value
1249 233692           void* object_ref = (void**)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1250              
1251 233692           SPVM_API_assign_object(env, stack, object_ref, value);
1252 233692           }
1253              
1254 0           void SPVM_API_set_field_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field, SPVM_OBJECT* value) {
1255            
1256 0           SPVM_API_set_field_object(env, stack, object, field, value);
1257 0           }
1258              
1259 702           int8_t SPVM_API_get_field_byte_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1260 702           *error_id = 0;
1261            
1262 702 50         if (object == NULL) {
1263 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1264 0           return 0;
1265             };
1266            
1267 702 50         if (object->type_dimension > 0) {
1268 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1269 0           return 0;
1270             };
1271            
1272 702           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1273 702 100         if (!field) {
1274 2           *error_id = 1;
1275 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1276 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1277 2           return 0;
1278             };
1279 700           int8_t value = SPVM_API_get_field_byte(env, stack, object, field);
1280 700           return value;
1281             }
1282              
1283 12           int16_t SPVM_API_get_field_short_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1284 12           *error_id = 0;
1285            
1286 12 50         if (object == NULL) {
1287 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1288 0           return 0;
1289             };
1290            
1291 12 50         if (object->type_dimension > 0) {
1292 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1293 0           return 0;
1294             };
1295            
1296 12           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1297 12 100         if (!field) {
1298 2           *error_id = 1;
1299 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1300 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1301 2           return 0;
1302             };
1303 10           int16_t value = SPVM_API_get_field_short(env, stack, object, field);
1304 10           return value;
1305             }
1306              
1307 20           int32_t SPVM_API_get_field_int_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1308 20           *error_id = 0;
1309            
1310 20 50         if (object == NULL) {
1311 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1312 0           return 0;
1313             };
1314            
1315 20 50         if (object->type_dimension > 0) {
1316 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1317 0           return 0;
1318             };
1319            
1320 20           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1321 20 100         if (!field) {
1322 2           *error_id = 1;
1323 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1324 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1325 2           return 0;
1326             };
1327 18           int32_t value = SPVM_API_get_field_int(env, stack, object, field);
1328 18           return value;
1329             }
1330              
1331 12           int64_t SPVM_API_get_field_long_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1332 12           *error_id = 0;
1333            
1334 12 50         if (object == NULL) {
1335 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1336 0           return 0;
1337             };
1338            
1339 12 50         if (object->type_dimension > 0) {
1340 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1341 0           return 0;
1342             };
1343            
1344 12           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1345 12 100         if (!field) {
1346 2           *error_id = 1;
1347 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1348 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1349 2           return 0;
1350             };
1351 10           int64_t value = SPVM_API_get_field_long(env, stack, object, field);
1352 10           return value;
1353             }
1354              
1355 12           float SPVM_API_get_field_float_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1356 12           *error_id = 0;
1357            
1358 12 50         if (object == NULL) {
1359 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1360 0           return 0;
1361             };
1362            
1363 12 50         if (object->type_dimension > 0) {
1364 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1365 0           return 0;
1366             };
1367            
1368 12           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1369 12 100         if (!field) {
1370 2           *error_id = 1;
1371 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1372 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1373 2           return 0;
1374             };
1375 10           float value = SPVM_API_get_field_float(env, stack, object, field);
1376 10           return value;
1377             }
1378              
1379 12           double SPVM_API_get_field_double_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1380 12           *error_id = 0;
1381            
1382 12 50         if (object == NULL) {
1383 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1384 0           return 0;
1385             };
1386            
1387 12 50         if (object->type_dimension > 0) {
1388 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1389 0           return 0;
1390             };
1391            
1392 12           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1393 12 100         if (!field) {
1394 2           *error_id = 1;
1395 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1396 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1397 2           return 0;
1398             };
1399 10           double value = SPVM_API_get_field_double(env, stack, object, field);
1400 10           return value;
1401             }
1402              
1403 516927           SPVM_OBJECT* SPVM_API_get_field_object_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1404 516927           *error_id = 0;
1405            
1406 516927 50         if (object == NULL) {
1407 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1408 0           return NULL;
1409             };
1410            
1411 516927 50         if (object->type_dimension > 0) {
1412 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1413 0           return NULL;
1414             };
1415            
1416 516927           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1417 516927 100         if (!field) {
1418 2           *error_id = 1;
1419 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1420 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1421 2           return NULL;
1422             };
1423 516925           SPVM_OBJECT* value = SPVM_API_get_field_object(env, stack, object, field);
1424 516925           return value;
1425             }
1426              
1427 346           SPVM_OBJECT** SPVM_API_get_field_object_ref_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1428 346           *error_id = 0;
1429            
1430 346 50         if (object == NULL) {
1431 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1432 0           return NULL;
1433             };
1434            
1435 346 50         if (object->type_dimension > 0) {
1436 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1437 0           return NULL;
1438             };
1439            
1440 346           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1441 346 50         if (!field) {
1442 0           *error_id = 1;
1443 0           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1444 0           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1445 0           return NULL;
1446             };
1447 346           SPVM_OBJECT** object_ref = SPVM_API_get_field_object_ref(env, stack, object, field);
1448 346           return object_ref;
1449             }
1450              
1451 256439           SPVM_OBJECT* SPVM_API_get_field_object_defined_and_has_pointer_by_name(SPVM_ENV* env, SPVM_VALUE* stack, void* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file_name, int32_t line) {
1452            
1453 256439           *error_id = 0;
1454            
1455 256439           void* obj_runtime = env->get_field_object_by_name(env, stack, object, field_name, error_id, func_name, file_name, line);
1456            
1457 256439 50         if (*error_id) { return NULL; }
1458            
1459 256439 50         if (!obj_runtime) {
1460 0           *error_id = env->die(env, stack, "The %s field must be defined.", field_name, func_name, file_name, line);
1461 0           return NULL;
1462             }
1463            
1464 256439           void* runtime = env->get_pointer(env, stack, obj_runtime);
1465            
1466 256439 50         if (!runtime) {
1467 0           *error_id = env->die(env, stack, "The pointer of the %s field must be defined.", field_name, func_name, file_name, line);
1468 0           return NULL;
1469             }
1470            
1471 256439           return obj_runtime;
1472             }
1473              
1474 0           SPVM_OBJECT* SPVM_API_get_field_string_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1475            
1476 0           return SPVM_API_get_field_object_by_name(env, stack, object, field_name, error_id, func_name, file, line);
1477             }
1478              
1479 4           const char* SPVM_API_get_field_string_chars_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1480 4           *error_id = 0;
1481            
1482 4           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1483 4 100         if (!field) {
1484 2           *error_id = 1;
1485 2           SPVM_API_die(env, stack, "The %s field is not found", field_name, func_name, file, line);
1486 2           return NULL;
1487             };
1488 2           SPVM_OBJECT* value = SPVM_API_get_field_string(env, stack, object, field);
1489 2 50         if (value == NULL) {
1490 0           return NULL;
1491             }
1492             else {
1493 2           const char* chars = SPVM_API_get_chars(env, stack, value);
1494 2           return chars;
1495             }
1496             }
1497              
1498 16           void SPVM_API_set_field_byte_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int8_t value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1499 16           *error_id = 0;
1500            
1501 16 50         if (object == NULL) {
1502 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1503 0           return;
1504             };
1505            
1506 16 50         if (object->type_dimension > 0) {
1507 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1508 0           return;
1509             };
1510            
1511 16           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1512 16 100         if (!field) {
1513 2           *error_id = 1;
1514 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1515 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1516 2           return;
1517             }
1518 14           SPVM_API_set_field_byte(env, stack, object, field, value);
1519             }
1520              
1521 4           void SPVM_API_set_field_short_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int16_t value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1522 4           *error_id = 0;
1523            
1524 4 50         if (object == NULL) {
1525 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1526 0           return;
1527             };
1528            
1529 4 50         if (object->type_dimension > 0) {
1530 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1531 0           return;
1532             };
1533            
1534 4           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1535 4 100         if (!field) {
1536 2           *error_id = 1;
1537 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1538 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1539 2           return;
1540             };
1541 2           SPVM_API_set_field_short(env, stack, object, field, value);
1542             }
1543              
1544 4           void SPVM_API_set_field_int_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int32_t value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1545 4           *error_id = 0;
1546            
1547 4 50         if (object == NULL) {
1548 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1549 0           return;
1550             };
1551            
1552 4 50         if (object->type_dimension > 0) {
1553 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1554 0           return;
1555             };
1556            
1557 4           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1558 4 100         if (!field) {
1559 2           *error_id = 1;
1560 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1561 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1562 2           return;
1563             };
1564 2           SPVM_API_set_field_int(env, stack, object, field, value);
1565             }
1566              
1567 4           void SPVM_API_set_field_long_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, int64_t value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1568 4           *error_id = 0;
1569            
1570 4 50         if (object == NULL) {
1571 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1572 0           return;
1573             };
1574            
1575 4 50         if (object->type_dimension > 0) {
1576 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1577 0           return;
1578             };
1579            
1580 4           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1581 4 100         if (!field) {
1582 2           *error_id = 1;
1583 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1584 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1585 2           return;
1586             };
1587 2           SPVM_API_set_field_long(env, stack, object, field, value);
1588             }
1589              
1590 4           void SPVM_API_set_field_float_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, float value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1591 4           *error_id = 0;
1592 4 50         if (object == NULL) {
1593 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1594 0           return;
1595             };
1596            
1597 4 50         if (object->type_dimension > 0) {
1598 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1599 0           return;
1600             };
1601            
1602 4           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1603 4 100         if (!field) {
1604 2           *error_id = 1;
1605 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1606 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1607 2           return;
1608             };
1609 2           SPVM_API_set_field_float(env, stack, object, field, value);
1610             }
1611              
1612 4           void SPVM_API_set_field_double_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, double value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1613 4           *error_id = 0;
1614            
1615 4 50         if (object == NULL) {
1616 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1617 0           return;
1618             };
1619            
1620 4 50         if (object->type_dimension > 0) {
1621 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1622 0           return;
1623             };
1624            
1625 4           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1626 4 100         if (!field) {
1627 2           *error_id = 1;
1628 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1629 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1630 2           return;
1631             };
1632 2           SPVM_API_set_field_double(env, stack, object, field, value);
1633             }
1634              
1635 233694           void SPVM_API_set_field_object_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, SPVM_OBJECT* value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1636 233694           *error_id = 0;
1637            
1638 233694 50         if (object == NULL) {
1639 0           SPVM_API_die(env, stack, "The object must be defined", func_name, file, line);
1640 0           return;
1641             };
1642            
1643 233694 50         if (object->type_dimension > 0) {
1644 0           SPVM_API_die(env, stack, "The type dimension of the object must be equal to 0", func_name, file, line);
1645 0           return;
1646             };
1647            
1648 233694           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1649 233694 100         if (!field) {
1650 2           *error_id = 1;
1651 2           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
1652 2           SPVM_API_die(env, stack, "The %s field is not found in the %s class or its super class", field_name, basic_type_name, func_name, file, line);
1653 2           return;
1654             };
1655 233692           SPVM_API_set_field_object(env, stack, object, field, value);
1656             }
1657              
1658 0           void SPVM_API_set_field_string_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name, SPVM_OBJECT* value, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
1659 0           SPVM_API_set_field_object_by_name(env, stack, object, field_name, value, error_id, func_name, file, line);
1660 0           }
1661              
1662 316           int32_t SPVM_API_die(SPVM_ENV* env, SPVM_VALUE* stack, const char* message, ...) {
1663            
1664             va_list args;
1665            
1666 316           char* message_with_line = (char*)SPVM_API_new_memory_block(env, stack, 512);
1667 316           int32_t message_length = strlen(message);
1668 316 50         if (message_length > 255) {
1669 0           message_length = 255;
1670             }
1671 316           memcpy(message_with_line, message, message_length);
1672 316           const char* place = "\n %s at %s line %d";
1673 316           memcpy(message_with_line + message_length, place, strlen(place));
1674              
1675 316           char* buffer = (char*)SPVM_API_new_memory_block(env, stack, 512);
1676 316           va_start(args, message);
1677 316           vsnprintf(buffer, 511, message_with_line, args);
1678 316           va_end(args);
1679            
1680 316           void* exception = SPVM_API_new_string_no_mortal(env, stack, buffer, strlen(buffer));
1681            
1682 316           SPVM_API_free_memory_block(env, stack, message_with_line);
1683 316           message_with_line = NULL;
1684            
1685 316           SPVM_API_free_memory_block(env, stack, buffer);
1686 316           buffer = NULL;
1687            
1688 316           SPVM_API_set_exception(env, stack, exception);
1689            
1690 316           return SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_CLASS;
1691             }
1692              
1693 682           SPVM_VALUE* SPVM_API_new_stack(SPVM_ENV* env) {
1694            
1695 682           SPVM_RUNTIME* runtime = env->runtime;
1696            
1697             // Arguments and return values : 0-255
1698             // Stack local varialbe : 256-511
1699             // Exception message 511
1700             // Mortal stack 510
1701             // Motal stack top 509
1702             // Motal stack capacity 508
1703            
1704 682           SPVM_VALUE* stack = SPVM_ALLOCATOR_alloc_memory_block_tmp(runtime->allocator, sizeof(SPVM_VALUE) * 512);
1705            
1706 682           int32_t native_mortal_stack_capacity = 1;
1707 682           void* native_mortal_stack = SPVM_API_new_memory_block(env, stack, sizeof(SPVM_OBJECT*) * native_mortal_stack_capacity);
1708 682 50         if (native_mortal_stack == NULL) {
1709 0           return NULL;
1710             }
1711 682           stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_CAPACITY].ival = native_mortal_stack_capacity;
1712 682           stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK].oval = native_mortal_stack;
1713 682           stack[SPVM_API_C_STACK_INDEX_ENV].oval = env;
1714            
1715 682           return stack;
1716             }
1717              
1718 682           void SPVM_API_free_stack(SPVM_ENV* env, SPVM_VALUE* stack) {
1719            
1720 682           SPVM_RUNTIME* runtime = env->runtime;
1721            
1722 682           SPVM_API_set_exception(env, stack, NULL);
1723            
1724 682           SPVM_OBJECT** mortal_stack = stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK].oval;
1725            
1726 682 50         if (mortal_stack != NULL) {
1727 682           SPVM_API_free_memory_block(env, stack, mortal_stack);
1728 682           mortal_stack = NULL;
1729             }
1730            
1731 682           SPVM_ALLOCATOR_free_memory_block_tmp(runtime->allocator, stack);
1732 682           stack = NULL;
1733 682           }
1734              
1735 2843427           int32_t SPVM_API_call_method_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_METHOD* method, int32_t args_width) {
1736            
1737 2843427           int32_t mortal = 0;
1738 2843427           int32_t error_id = SPVM_API_call_method_common(env, stack, method, args_width, mortal);
1739            
1740 2843427           return error_id;
1741             }
1742              
1743 62           int32_t SPVM_API_call_method(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_METHOD* method, int32_t args_width) {
1744            
1745 62           int32_t mortal = 1;
1746 62           int32_t error_id = SPVM_API_call_method_common(env, stack, method, args_width, mortal);
1747            
1748 62           return error_id;
1749             }
1750              
1751 8           int32_t SPVM_API_is_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1752            
1753             int32_t is_array;
1754 8 100         if (object) {
1755 6           is_array = object->type_dimension > 0;
1756             }
1757             else {
1758 2           is_array = 0;
1759             }
1760            
1761 8           return is_array;
1762             }
1763              
1764 14348           int32_t SPVM_API_is_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1765            
1766             int32_t is_string;
1767 14348 50         if (object) {
1768 14348           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
1769 14348 100         is_string = (object_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_STRING && object->type_dimension == 0);
    100          
1770             }
1771             else {
1772 0           is_string = 0;
1773             }
1774            
1775 14348           return is_string;
1776             }
1777              
1778 270           int32_t SPVM_API_is_numeric_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1779              
1780 270           SPVM_RUNTIME* runtime = env->runtime;
1781            
1782             int32_t is_numeric_array;
1783 270 100         if (object) {
1784 268           int32_t object_type_dimension = object->type_dimension;
1785 268 100         if (object_type_dimension == 0) {
1786 6           is_numeric_array = 0;
1787             }
1788 262 100         else if (object_type_dimension == 1) {
1789 254           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
1790 254           int32_t object_basic_type_category = object_basic_type->category;
1791 254 100         switch (object_basic_type_category) {
1792             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_NUMERIC:
1793             {
1794 170           is_numeric_array = 1;
1795 170           break;
1796             }
1797             default: {
1798 254           is_numeric_array = 0;
1799             }
1800             }
1801             }
1802 8 50         else if (object_type_dimension > 1) {
1803 8           is_numeric_array = 0;
1804             }
1805             else {
1806 268           assert(0);
1807             }
1808             }
1809             else {
1810 2           is_numeric_array = 0;
1811             }
1812              
1813 270           return is_numeric_array;
1814             }
1815              
1816              
1817 591690           int32_t SPVM_API_is_object_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1818            
1819 591690           SPVM_RUNTIME* runtime = env->runtime;
1820              
1821             int32_t is_object_array;
1822 591690 100         if (object) {
1823 591688           int32_t object_type_dimension = object->type_dimension;
1824 591688 100         if (object_type_dimension == 0) {
1825 460112           is_object_array = 0;
1826             }
1827 131576 100         else if (object_type_dimension == 1) {
1828 131482           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
1829 131482           int32_t element_type_dimension = 0;
1830 131482           int32_t type_flag = 0;
1831 131482           is_object_array = SPVM_API_TYPE_is_object_type(env->runtime, object_basic_type, element_type_dimension, type_flag);
1832             }
1833 94 50         else if (object_type_dimension > 1) {
1834 94           is_object_array = 1;
1835             }
1836             else {
1837 591688           assert(0);
1838             }
1839             }
1840             else {
1841 2           is_object_array = 0;
1842             }
1843            
1844 591690           return is_object_array;
1845             }
1846              
1847 21026           int32_t SPVM_API_is_mulnum_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1848              
1849 21026           SPVM_RUNTIME* runtime = env->runtime;
1850              
1851             int32_t is_mulnum_array;
1852 21026 100         if (object) {
1853 21024           int32_t object_type_dimension = object->type_dimension;
1854 21024 100         if (object_type_dimension == 0) {
1855 6           is_mulnum_array = 0;
1856             }
1857 21018 100         else if (object_type_dimension == 1) {
1858 20994           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
1859 20994           int32_t object_basic_type_category = object_basic_type->category;
1860 20994 100         switch (object_basic_type_category) {
1861             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_MULNUM:
1862             {
1863 100           is_mulnum_array = 1;
1864 100           break;
1865             }
1866             default: {
1867 20994           is_mulnum_array = 0;
1868             }
1869             }
1870             }
1871 24 50         else if (object_type_dimension > 1) {
1872 24           is_mulnum_array = 0;
1873             }
1874             else {
1875 21024           assert(0);
1876             }
1877             }
1878             else {
1879 2           is_mulnum_array = 0;
1880             }
1881              
1882 21026           return is_mulnum_array;
1883             }
1884              
1885 10           int32_t SPVM_API_is_class(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1886            
1887 10           SPVM_RUNTIME* runtime = env->runtime;
1888              
1889             int32_t is_class;
1890 10 100         if (object) {
1891 8           int32_t object_type_dimension = object->type_dimension;
1892 8 100         if (object_type_dimension == 0) {
1893 6           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
1894 6           int32_t object_basic_type_category = object_basic_type->category;
1895            
1896 6 100         switch (object_basic_type_category) {
1897             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS: {
1898 4           is_class = 1;
1899 4           break;
1900             }
1901             default: {
1902 6           is_class = 0;
1903             }
1904             }
1905             }
1906             else {
1907 8           is_class = 0;
1908             }
1909             }
1910             else {
1911 2           is_class = 0;
1912             }
1913            
1914 10           return is_class;
1915             }
1916              
1917 12           int32_t SPVM_API_is_pointer_class(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1918            
1919 12           SPVM_RUNTIME* runtime = env->runtime;
1920            
1921             int32_t is_pointer_class;
1922 12 100         if (object) {
1923 10           int32_t object_type_dimension = object->type_dimension;
1924 10 100         if (object_type_dimension == 0) {
1925 8           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
1926 8           int32_t object_basic_type_category = object_basic_type->category;
1927            
1928 8 100         switch (object_basic_type_category) {
1929             case SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS: {
1930 6           int32_t basic_type_is_pointer = object_basic_type->is_pointer;
1931            
1932 6 100         if (basic_type_is_pointer) {
1933 2           is_pointer_class = 1;
1934             }
1935             else {
1936 4           is_pointer_class = 0;
1937             }
1938 6           break;
1939             }
1940             default: {
1941 8           is_pointer_class = 0;
1942             }
1943             }
1944             }
1945             else {
1946 10           is_pointer_class = 0;
1947             }
1948             }
1949             else {
1950 2           is_pointer_class = 0;
1951             }
1952            
1953 12           return is_pointer_class;
1954             }
1955              
1956 6726           int32_t SPVM_API_get_elem_size(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array) {
1957            
1958 6726           SPVM_RUNTIME* runtime = env->runtime;
1959            
1960             int32_t elem_size;
1961 6726 50         if (array) {
1962 6726 100         if (SPVM_API_is_string(env, stack, array)) {
1963 6404           elem_size = 1;
1964             }
1965 322 100         else if (SPVM_API_is_object_array(env, stack, array)) {
1966 262           elem_size = sizeof(void*);
1967             }
1968 60 100         else if (SPVM_API_is_numeric_array(env, stack, array)) {
1969            
1970 48           SPVM_RUNTIME_BASIC_TYPE* array_basic_type = SPVM_API_get_object_basic_type(env, stack, array);
1971 48           int32_t type_dimension = array->type_dimension;
1972 48 50         assert(type_dimension == 1);
1973            
1974 48 100         if (array_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE) {
1975 28           elem_size = 1;
1976             }
1977 20 50         else if (array_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT) {
1978 0           elem_size = 2;
1979             }
1980 20 100         else if (array_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_INT || array_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT) {
    50          
1981 8           elem_size = 4;
1982             }
1983 12 50         else if (array_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_LONG || array_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE) {
    50          
1984 12           elem_size = 8;
1985             }
1986             else {
1987 48           assert(0);
1988             }
1989             }
1990 12 50         else if (SPVM_API_is_mulnum_array(env, stack, array)) {
1991 12           SPVM_RUNTIME_BASIC_TYPE* array_basic_type = SPVM_API_get_object_basic_type(env, stack, array);
1992 12           int32_t type_dimension = array->type_dimension;
1993 12 50         assert(type_dimension == 1);
1994            
1995 12           int32_t fields_length = array_basic_type->fields_length;
1996            
1997 12           SPVM_RUNTIME_FIELD* first_field = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, array_basic_type, 0);
1998            
1999 12           int32_t field_basic_type_id = first_field->basic_type->id;
2000            
2001 12 50         if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE) {
2002 0           elem_size = 1 * fields_length;
2003             }
2004 12 50         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT) {
2005 0           elem_size = 2 * fields_length;
2006             }
2007 12 50         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_INT || field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT) {
    50          
2008 0           elem_size = 4 * fields_length;
2009             }
2010 12 50         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_LONG || field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE) {
    50          
2011 12           elem_size = 8 * fields_length;
2012             }
2013             else {
2014 6726           assert(0);
2015             }
2016             }
2017             }
2018             else {
2019 0           elem_size = 0;
2020             }
2021            
2022 6726           return elem_size;
2023             }
2024              
2025 1362921           int32_t SPVM_API_enter_scope(SPVM_ENV* env, SPVM_VALUE* stack){
2026            
2027              
2028 1362921           SPVM_OBJECT*** current_mortal_stack_ptr = (SPVM_OBJECT***)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK];
2029 1362921           int32_t* current_mortal_stack_top_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_TOP];
2030 1362921           int32_t* current_mortal_stack_capacity_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_CAPACITY];
2031            
2032 1362921           int32_t mortal_stack_top = *current_mortal_stack_top_ptr ;
2033            
2034 1362921           return mortal_stack_top;
2035             }
2036              
2037 108           SPVM_OBJECT* SPVM_API_get_type_name_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
2038            
2039            
2040 108 50         assert(object);
2041            
2042 108           SPVM_RUNTIME* runtime = env->runtime;
2043            
2044 108           const char* basic_type_name = SPVM_API_get_object_basic_type_name(env, stack, object);
2045 108           int32_t type_dimension = object->type_dimension;
2046            
2047 108           int32_t length = 0;
2048            
2049             // Basic type
2050 108           length += strlen(basic_type_name);
2051            
2052             //[]
2053 108           length += type_dimension * 2;
2054            
2055 108           void* obj_type_name = SPVM_API_new_string_no_mortal(env, stack, NULL, length);
2056            
2057 108           char* type_name = (char*)SPVM_API_get_chars(env, stack, obj_type_name);
2058            
2059 108           int32_t type_name_index = 0;
2060 108           sprintf((char*)type_name, "%s", basic_type_name);
2061 108           type_name_index += strlen(basic_type_name);
2062            
2063             int32_t dim_index;
2064 204 100         for (dim_index = 0; dim_index < type_dimension; dim_index++) {
2065 96           sprintf((char*)(type_name + type_name_index), "[]");
2066 96           type_name_index += 2;
2067             }
2068            
2069 108           return obj_type_name;
2070             }
2071              
2072 0           SPVM_OBJECT* SPVM_API_get_type_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
2073            
2074            
2075 0           SPVM_OBJECT* obj_type_name = SPVM_API_get_type_name_no_mortal(env, stack, object);
2076            
2077 0           SPVM_API_push_mortal(env, stack, obj_type_name);
2078            
2079 0           return obj_type_name;
2080             }
2081              
2082 8           int32_t SPVM_API_get_compile_type_name_length(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t type_dimension, int32_t type_flag) {
2083            
2084 8           int32_t compile_type_name_length = 0;
2085            
2086             // mutable
2087 8 100         if (type_flag & SPVM_NATIVE_C_TYPE_FLAG_MUTABLE) {
2088 2           compile_type_name_length += strlen("mutable ");
2089             }
2090            
2091             // Basic type
2092 8           compile_type_name_length += strlen(basic_type_name);
2093            
2094             // []
2095 8           compile_type_name_length += type_dimension * 2;
2096            
2097             // *
2098 8 100         if (type_flag & SPVM_NATIVE_C_TYPE_FLAG_REF) {
2099 2           compile_type_name_length += 1;
2100             }
2101            
2102 8           return compile_type_name_length;
2103             }
2104              
2105 8           SPVM_OBJECT* SPVM_API_get_compile_type_name_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t type_dimension, int32_t type_flag) {
2106            
2107 8           int32_t compile_type_name_length = SPVM_API_get_compile_type_name_length(env, stack, basic_type_name, type_dimension, type_flag);
2108            
2109 8           void* obj_compile_type_name = SPVM_API_new_string_no_mortal(env, stack, NULL, compile_type_name_length);
2110            
2111 8           char* compile_type_name = (char*)SPVM_API_get_chars(env, stack, obj_compile_type_name);
2112            
2113 8 100         if (type_flag & SPVM_NATIVE_C_TYPE_FLAG_MUTABLE) {
2114 2           sprintf(compile_type_name, "mutable ");
2115 2           compile_type_name += strlen("mutable ");
2116             }
2117            
2118 8           sprintf(compile_type_name, "%s", basic_type_name);
2119 8           compile_type_name += strlen(basic_type_name);
2120            
2121 12 100         for (int32_t type_dimension_index = 0; type_dimension_index < type_dimension; type_dimension_index++) {
2122 4           sprintf(compile_type_name, "[]");
2123 4           compile_type_name += 2;
2124             }
2125            
2126             // Reference
2127 8 100         if (type_flag & SPVM_NATIVE_C_TYPE_FLAG_REF) {
2128 2           sprintf(compile_type_name, "*");
2129 2           compile_type_name += 1;
2130             }
2131            
2132 8           *compile_type_name = '\0';
2133 8           compile_type_name++;
2134            
2135 8           return obj_compile_type_name;
2136             }
2137              
2138 8           SPVM_OBJECT* SPVM_API_get_compile_type_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t type_dimension, int32_t type_flag) {
2139            
2140 8           SPVM_OBJECT* obj_compile_type_name = SPVM_API_get_compile_type_name_no_mortal(env, stack, basic_type_name, type_dimension, type_flag);
2141            
2142 8           SPVM_API_push_mortal(env, stack, obj_compile_type_name);
2143            
2144 8           return obj_compile_type_name;
2145             }
2146              
2147 2056           SPVM_OBJECT* SPVM_API_new_stack_trace_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* exception, SPVM_RUNTIME_METHOD* method, int32_t line) {
2148              
2149 2056 50         if (stack[SPVM_API_C_STACK_INDEX_CALL_DEPTH].ival > 100) {
2150 0           return exception;
2151             }
2152              
2153 2056           SPVM_RUNTIME* runtime = env->runtime;
2154              
2155 2056           SPVM_RUNTIME_BASIC_TYPE* basic_type = method->current_basic_type;
2156 2056           const char* basic_type_name = basic_type->name;
2157 2056           const char* method_name = method->name;
2158              
2159 2056           const char* class_dir = basic_type->class_dir;
2160             const char* class_dir_sep;
2161 2056 50         if (class_dir) {
2162 2056           class_dir_sep = "/";
2163             }
2164             else {
2165 0           class_dir = "";
2166 0           class_dir_sep = "";
2167             }
2168            
2169 2056           const char* class_rel_file = basic_type->class_rel_file;
2170            
2171             // Basic type name and method name
2172 2056           const char* new_line_part = "\n ";
2173 2056           const char* arrow_part = "->";
2174 2056           const char* at_part = " at ";
2175              
2176             // Exception
2177 2056           const char* exception_bytes = SPVM_API_get_chars(env, stack, exception);
2178 2056           int32_t exception_length = SPVM_API_length(env, stack, exception);
2179            
2180             // Total string length
2181 2056           int32_t total_length = 0;
2182 2056           total_length += exception_length;
2183 2056           total_length += strlen(new_line_part);
2184 2056           total_length += strlen(basic_type_name);
2185 2056           total_length += strlen(arrow_part);
2186 2056           total_length += strlen(method_name);
2187 2056           total_length += strlen(at_part);
2188 2056           total_length += strlen(class_dir);
2189 2056           total_length += strlen(class_dir_sep);
2190 2056           total_length += strlen(class_rel_file);
2191              
2192 2056           const char* line_part = " line ";
2193             char line_str[20];
2194            
2195 2056           sprintf(line_str, "%" PRId32, line);
2196 2056           total_length += strlen(line_part);
2197 2056           total_length += strlen(line_str);
2198            
2199             // Create exception message
2200 2056           void* new_exception = SPVM_API_new_string_no_mortal(env, stack, NULL, total_length);
2201 2056           const char* new_exception_bytes = SPVM_API_get_chars(env, stack, new_exception);
2202            
2203 2056           memcpy(
2204             (void*)(new_exception_bytes),
2205             (void*)(exception_bytes),
2206             exception_length
2207             );
2208              
2209 2056           sprintf(
2210             (char*)new_exception_bytes + exception_length,
2211             "%s%s%s%s%s%s%s%s%s%" PRId32,
2212             new_line_part,
2213             basic_type_name,
2214             arrow_part,
2215             method_name,
2216             at_part,
2217             class_dir,
2218             class_dir_sep,
2219             class_rel_file,
2220             line_part,
2221             line
2222             );
2223            
2224 2056           return new_exception;
2225             }
2226              
2227 0           SPVM_OBJECT* SPVM_API_new_stack_trace(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* exception, SPVM_RUNTIME_METHOD* method, int32_t line) {
2228            
2229            
2230 0           SPVM_OBJECT* stack_trace = SPVM_API_new_stack_trace_no_mortal(env, stack, exception, method, line);
2231            
2232 0           SPVM_API_push_mortal(env, stack, stack_trace);
2233            
2234 0           return stack_trace;
2235             }
2236              
2237 0           void SPVM_API_fprint(SPVM_ENV* env, SPVM_VALUE* stack, FILE* fh, SPVM_OBJECT* string) {
2238            
2239            
2240 0 0         if (string == NULL) {
2241 0           return;
2242             }
2243            
2244 0           const char* bytes = SPVM_API_get_chars(env, stack, string);
2245 0           int32_t string_length = SPVM_API_length(env, stack, string);
2246            
2247             {
2248             int32_t i;
2249 0 0         for (i = 0; i < string_length; i++) {
2250 0           putc((char)bytes[i], fh);
2251             }
2252             }
2253             }
2254              
2255 0           void SPVM_API_print(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
2256            
2257 0           SPVM_RUNTIME* runtime = env->runtime;
2258            
2259 0           SPVM_API_fprint(env, stack, runtime->spvm_stdout, string);
2260 0           }
2261              
2262 0           void SPVM_API_print_stderr(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
2263            
2264 0           SPVM_RUNTIME* runtime = env->runtime;
2265            
2266 0           SPVM_API_fprint(env, stack, runtime->spvm_stderr, string);
2267 0           }
2268              
2269 1102           SPVM_OBJECT* SPVM_API_concat_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string1, SPVM_OBJECT* string2) {
2270            
2271 1102           int32_t string1_length = SPVM_API_length(env, stack, string1);
2272 1102           int32_t string2_length = SPVM_API_length(env, stack, string2);
2273            
2274 1102           int32_t string3_length = string1_length + string2_length;
2275 1102           SPVM_OBJECT* string3 = SPVM_API_new_string_no_mortal(env, stack, NULL, string3_length);
2276            
2277 1102           const char* string1_bytes = SPVM_API_get_chars(env, stack, string1);
2278 1102           const char* string2_bytes = SPVM_API_get_chars(env, stack, string2);
2279 1102           char* string3_bytes = (char*)SPVM_API_get_chars(env, stack, string3);
2280            
2281 1102 100         if (string1_length > 0) {
2282 982           memcpy(string3_bytes, string1_bytes, string1_length);
2283             }
2284 1102 100         if (string2_length) {
2285 910           memcpy(string3_bytes + string1_length, string2_bytes, string2_length);
2286             }
2287            
2288 1102           return string3;
2289             }
2290              
2291 0           SPVM_OBJECT* SPVM_API_concat(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string1, SPVM_OBJECT* string2) {
2292            
2293            
2294 0           SPVM_OBJECT* str = SPVM_API_concat_no_mortal(env, stack, string1, string2);
2295            
2296 0           SPVM_API_push_mortal(env, stack, str);
2297            
2298 0           return str;
2299             }
2300              
2301 2           SPVM_OBJECT* SPVM_API_dump(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
2302            
2303            
2304 2           SPVM_OBJECT* str = SPVM_API_dump_no_mortal(env, stack, object);
2305            
2306 2           SPVM_API_push_mortal(env, stack, str);
2307            
2308 2           return str;
2309             }
2310              
2311 68           SPVM_OBJECT* SPVM_API_dump_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
2312            
2313 68           SPVM_RUNTIME* runtime = env->runtime;
2314            
2315 68           int32_t depth = 0;
2316 68           SPVM_STRING_BUFFER* string_buffer = SPVM_STRING_BUFFER_new(runtime->allocator, 255, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
2317 68           SPVM_HASH* address_symtable = SPVM_HASH_new(runtime->allocator, 255, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
2318            
2319 68           SPVM_API_dump_recursive(env, stack, object, &depth, string_buffer, address_symtable);
2320            
2321 68           int32_t string_buffer_length = string_buffer->length;
2322            
2323 68           SPVM_OBJECT* dump = SPVM_API_new_string_no_mortal(env, stack, string_buffer->string, string_buffer->length);
2324            
2325 68           SPVM_HASH_free(address_symtable);
2326 68           address_symtable = NULL;
2327            
2328 68           SPVM_STRING_BUFFER_free(string_buffer);
2329 68           string_buffer = NULL;
2330            
2331 68           return dump;
2332             }
2333              
2334 2           const char* SPVM_API_dumpc(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
2335            
2336            
2337 2           SPVM_OBJECT* obj_dump = SPVM_API_dump(env, stack, object);
2338            
2339 2           const char* dump_chars = SPVM_API_get_chars(env, stack, obj_dump);
2340            
2341 2           return dump_chars;
2342             }
2343              
2344 168           void SPVM_API_dump_recursive(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, int32_t* depth, SPVM_STRING_BUFFER* string_buffer, SPVM_HASH* address_symtable) {
2345            
2346 168           SPVM_RUNTIME* runtime = env->runtime;
2347            
2348             char tmp_buffer[256];
2349            
2350             SPVM_OBJECT* dump;
2351 168 100         if (object == NULL) {
2352 36           SPVM_STRING_BUFFER_add(string_buffer, "undef");
2353             }
2354             else {
2355 132           int32_t type_dimension = object->type_dimension;
2356            
2357 132 100         if (SPVM_API_is_string(env, stack, object)) {
2358 28           const char* chars = SPVM_API_get_chars(env, stack, object);
2359 28           int32_t chars_length = SPVM_API_length(env, stack, object);
2360 28           SPVM_STRING_BUFFER_add(string_buffer, "\"");
2361 28           SPVM_STRING_BUFFER_add_len(string_buffer, (char*)chars, chars_length);
2362 28           SPVM_STRING_BUFFER_add(string_buffer, "\"");
2363             }
2364 104 100         else if (type_dimension > 0) {
2365 66           int32_t array_length = SPVM_API_length(env, stack, object);
2366 66           int32_t element_type_dimension = type_dimension - 1;
2367            
2368 66           SPVM_STRING_BUFFER_add(string_buffer, "[\n");
2369            
2370 66           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
2371 66           const char* object_basic_type_name = object_basic_type->name;
2372            
2373 216 100         for (int32_t array_index = 0; array_index < array_length; array_index++) {
2374            
2375 326 100         for (int32_t depth_index = 0; depth_index < *depth + 1; depth_index++) {
2376 176           SPVM_STRING_BUFFER_add(string_buffer, " ");
2377             }
2378            
2379 150 100         if (SPVM_API_is_mulnum_array(env, stack, object)) {
2380            
2381 32           SPVM_STRING_BUFFER_add(string_buffer, "{\n");
2382            
2383 32           int32_t fields_length = object_basic_type->fields_length;
2384            
2385 128 100         for (int32_t field_index = 0; field_index < fields_length; field_index++) {
2386 288 100         for (int32_t depth_index = 0; depth_index < *depth + 2; depth_index++) {
2387 192           SPVM_STRING_BUFFER_add(string_buffer, " ");
2388             }
2389            
2390 96           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, object_basic_type, field_index);
2391            
2392 96           int32_t field_basic_type_id = field->basic_type->id;
2393            
2394 96           const char* field_name = field->name;
2395 96           SPVM_STRING_BUFFER_add(string_buffer, field_name);
2396 96           SPVM_STRING_BUFFER_add(string_buffer, " => ");
2397            
2398 96           switch (field_basic_type_id) {
2399             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
2400 24           int8_t* element = &((int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2401 24           sprintf(tmp_buffer, "%d", element[field_index]);
2402 24           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2403 24           break;
2404             }
2405             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
2406 24           int16_t* element = &((int16_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2407 24           sprintf(tmp_buffer, "%d", element[field_index]);
2408 24           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2409 24           break;
2410             }
2411             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
2412 24           int32_t* element = &((int32_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2413 24           sprintf(tmp_buffer, "%d", element[field_index]);
2414 24           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2415 24           break;
2416             }
2417             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
2418 24           int64_t* element = &((int64_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2419 24           sprintf(tmp_buffer, "%lld", (long long int)element[field_index]);
2420 24           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2421 24           break;
2422             }
2423             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
2424 0           float* element = &((float*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2425 0           sprintf(tmp_buffer, "%g", element[field_index]);
2426 0           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2427 0           break;
2428             }
2429             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
2430 0           double* element = &((double*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2431 0           sprintf(tmp_buffer, "%g", element[field_index]);
2432 0           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2433 0           break;
2434             }
2435             }
2436            
2437 96 100         if (field_index == fields_length - 1) {
2438 32           SPVM_STRING_BUFFER_add(string_buffer, "\n");
2439             }
2440             else {
2441 64           SPVM_STRING_BUFFER_add(string_buffer, ",\n");
2442             }
2443             }
2444            
2445 32           SPVM_STRING_BUFFER_add(string_buffer, " }");
2446             }
2447 118 100         else if (SPVM_API_is_numeric_array(env, stack, object)) {
2448 54           switch (object_basic_type->id) {
2449             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
2450 8           int8_t element = ((int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2451 8           sprintf(tmp_buffer, "%d", element);
2452 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2453 8           break;
2454             }
2455             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
2456 8           int16_t element = ((int16_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2457 8           sprintf(tmp_buffer, "%d", element);
2458 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2459 8           break;
2460             }
2461             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
2462 14           int32_t element = ((int32_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2463 14           sprintf(tmp_buffer, "%d", element);
2464 14           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2465 14           break;
2466             }
2467             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
2468 8           int64_t element = ((int64_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2469 8           sprintf(tmp_buffer, "%lld", (long long int)element);
2470 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2471 8           break;
2472             }
2473             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
2474 8           float element = ((float*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2475 8           sprintf(tmp_buffer, "%g", element);
2476 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2477 8           break;
2478             }
2479             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
2480 8           double element = ((double*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2481 8           sprintf(tmp_buffer, "%g", element);
2482 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2483 54           break;
2484             }
2485             }
2486             }
2487 64 50         else if (SPVM_API_is_object_array(env, stack, object)) {
2488 64           SPVM_OBJECT* element = (((SPVM_OBJECT**)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index]);
2489 64           element = SPVM_API_get_object_no_weaken_address(env, stack, element);
2490 64           (*depth)++;
2491 64           SPVM_API_dump_recursive(env, stack, element, depth, string_buffer, address_symtable);
2492 64           (*depth)--;
2493             }
2494             else {
2495 0           assert(0);
2496             }
2497            
2498 150 100         if (array_index == array_length - 1) {
2499 66           SPVM_STRING_BUFFER_add(string_buffer, "\n");
2500             }
2501             else {
2502 84           SPVM_STRING_BUFFER_add(string_buffer, ",\n");
2503             }
2504             }
2505            
2506 76 100         for (int32_t depth_index = 0; depth_index < *depth; depth_index++) {
2507 10           SPVM_STRING_BUFFER_add(string_buffer, " ");
2508             }
2509 66           SPVM_STRING_BUFFER_add(string_buffer, "]");
2510            
2511 66           SPVM_STRING_BUFFER_add(string_buffer, " : ");
2512 66           SPVM_STRING_BUFFER_add(string_buffer, object_basic_type_name);
2513 136 100         for (int32_t type_dimension_index = 0; type_dimension_index < type_dimension; type_dimension_index++) {
2514 70           SPVM_STRING_BUFFER_add(string_buffer, "[]");
2515             }
2516            
2517             // If the object is weaken, this get the real address
2518 66           sprintf(tmp_buffer, "(%p)", SPVM_API_get_object_no_weaken_address(env, stack, object));
2519 66           SPVM_STRING_BUFFER_add(string_buffer, tmp_buffer);
2520             }
2521             else {
2522             // If the object is weaken, this get the real address
2523 38           sprintf(tmp_buffer, "%p", SPVM_API_get_object_no_weaken_address(env, stack, object));
2524 38           int32_t exists = (int32_t)(intptr_t)SPVM_HASH_get(address_symtable, tmp_buffer, strlen(tmp_buffer));
2525 38 100         if (exists) {
2526             // If the object is weaken, this get the real address
2527 24           sprintf(tmp_buffer, "REUSE_OBJECT(%p)", SPVM_API_get_object_no_weaken_address(env, stack, object));
2528 24           SPVM_STRING_BUFFER_add(string_buffer, tmp_buffer);
2529             }
2530             else {
2531 14           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
2532 14           const char* basic_type_name = object_basic_type->name;
2533            
2534 14           SPVM_HASH_set(address_symtable, tmp_buffer, strlen(tmp_buffer), (void*)(intptr_t)1);
2535            
2536 14           SPVM_STRING_BUFFER_add(string_buffer, basic_type_name);
2537 14           sprintf(tmp_buffer, " (%p) ", object);
2538 14           SPVM_STRING_BUFFER_add(string_buffer, tmp_buffer);
2539            
2540 14           SPVM_STRING_BUFFER_add(string_buffer, "{\n");
2541            
2542             // Free object fields
2543 14           int32_t fields_length = object_basic_type->fields_length;
2544 126 100         for (int32_t field_index = 0; field_index < fields_length; field_index++) {
2545 314 100         for (int32_t depth_index = 0; depth_index < *depth + 1; depth_index++) {
2546 202           SPVM_STRING_BUFFER_add(string_buffer, " ");
2547             }
2548            
2549 112           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, object_basic_type, field_index);
2550            
2551 112           int32_t field_basic_type_id = field->basic_type->id;
2552 112           int32_t field_type_dimension = field->type_dimension;
2553 112           int32_t field_offset = field->offset;
2554 112           const char* field_name = field->name;
2555            
2556 112           SPVM_STRING_BUFFER_add(string_buffer, field_name);
2557 112           SPVM_STRING_BUFFER_add(string_buffer, " => ");
2558 112 100         if (field_type_dimension == 0 && field_basic_type_id >= SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE && field_basic_type_id <= SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE) {
    50          
    100          
2559 76           switch (field_basic_type_id) {
2560             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
2561 12           int8_t field_value = *(int8_t*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2562 12           sprintf(tmp_buffer, "%d", field_value);
2563 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2564 12           break;
2565             }
2566             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
2567 12           int16_t field_value = *(int16_t*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2568 12           sprintf(tmp_buffer, "%d", field_value);
2569 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2570 12           break;
2571             }
2572             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
2573 16           int32_t field_value = *(int32_t*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2574 16           sprintf(tmp_buffer, "%d", field_value);
2575 16           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2576 16           break;
2577             }
2578             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
2579 12           int64_t field_value = *(int64_t*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2580 12           sprintf(tmp_buffer, "%lld", (long long int)field_value);
2581 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2582 12           break;
2583             }
2584             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
2585 12           float field_value = *(float*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2586 12           sprintf(tmp_buffer, "%g", field_value);
2587 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2588 12           break;
2589             }
2590             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
2591 12           double field_value = *(double*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2592 12           sprintf(tmp_buffer, "%g", field_value);
2593 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2594 12           break;
2595             }
2596             default : {
2597 0           assert(0);
2598             }
2599             }
2600 76           }
2601             else {
2602 36           SPVM_OBJECT* field_value = *(SPVM_OBJECT**)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2603 36           field_value = SPVM_API_get_object_no_weaken_address(env, stack, field_value);
2604 36           (*depth)++;
2605 36           SPVM_API_dump_recursive(env, stack, field_value, depth, string_buffer, address_symtable);
2606 36           (*depth)--;
2607             }
2608            
2609 112 100         if (field_index == fields_length - 1) {
2610 14           SPVM_STRING_BUFFER_add(string_buffer, "\n");
2611             }
2612             else {
2613 98           SPVM_STRING_BUFFER_add(string_buffer, ",\n");
2614             }
2615             }
2616            
2617 24 100         for (int32_t depth_index = 0; depth_index < *depth; depth_index++) {
2618 10           SPVM_STRING_BUFFER_add(string_buffer, " ");
2619             }
2620 14           SPVM_STRING_BUFFER_add(string_buffer, "}");
2621             }
2622             }
2623             }
2624 168           }
2625              
2626 14000           void SPVM_API_make_read_only(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
2627 14000           SPVM_RUNTIME_BASIC_TYPE* string_basic_type = SPVM_API_get_object_basic_type(env, stack, string);
2628 14000 50         if (string && string_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_STRING && string->type_dimension == 0) {
    50          
    50          
2629 14000           string->flag |= SPVM_OBJECT_C_FLAG_IS_READ_ONLY;
2630             }
2631 14000           }
2632              
2633 6404           int32_t SPVM_API_is_read_only(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
2634            
2635             int32_t is_read_only;
2636 6404 100         if (string) {
2637 6396 100         if (string->flag & SPVM_OBJECT_C_FLAG_IS_READ_ONLY) {
2638 268           is_read_only = 1;
2639             }
2640             else {
2641 6396           is_read_only = 0;
2642             }
2643             }
2644             else {
2645 8           is_read_only = 0;
2646             }
2647            
2648 6404           return is_read_only;
2649             }
2650              
2651 6410           int32_t SPVM_API_set_exception(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* exception) {
2652            
2653 6410           SPVM_OBJECT** current_exception_ptr = (SPVM_OBJECT**)&stack[SPVM_API_C_STACK_INDEX_EXCEPTION];
2654            
2655 6410           SPVM_API_assign_object(env, stack, current_exception_ptr, exception);
2656            
2657 6410           return 0;
2658             }
2659              
2660 4352           SPVM_OBJECT* SPVM_API_get_exception(SPVM_ENV* env, SPVM_VALUE* stack){
2661              
2662 4352           SPVM_OBJECT** current_exception_ptr = (SPVM_OBJECT**)&stack[SPVM_API_C_STACK_INDEX_EXCEPTION];
2663 4352           SPVM_OBJECT* current_exception = *current_exception_ptr;
2664            
2665 4352           return current_exception;
2666             }
2667              
2668 4           SPVM_OBJECT* SPVM_API_new_byte_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2669            
2670 4           SPVM_OBJECT* object = SPVM_API_new_byte_array_no_mortal(env, stack, length);
2671            
2672 4           SPVM_API_push_mortal(env, stack, object);
2673            
2674 4           return object;
2675             }
2676              
2677 4           SPVM_OBJECT* SPVM_API_new_short_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2678            
2679 4           SPVM_OBJECT* object = SPVM_API_new_short_array_no_mortal(env, stack, length);
2680            
2681 4           SPVM_API_push_mortal(env, stack, object);
2682            
2683 4           return object;
2684             }
2685              
2686 14           SPVM_OBJECT* SPVM_API_new_int_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2687            
2688 14           SPVM_OBJECT* object = SPVM_API_new_int_array_no_mortal(env, stack, length);
2689            
2690 14           SPVM_API_push_mortal(env, stack, object);
2691            
2692 14           return object;
2693             }
2694              
2695 6           SPVM_OBJECT* SPVM_API_new_long_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2696            
2697 6           SPVM_OBJECT* object = SPVM_API_new_long_array_no_mortal(env, stack, length);
2698            
2699 6           SPVM_API_push_mortal(env, stack, object);
2700            
2701 6           return object;
2702             }
2703              
2704 4           SPVM_OBJECT* SPVM_API_new_float_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2705            
2706 4           SPVM_OBJECT* object = SPVM_API_new_float_array_no_mortal(env, stack, length);
2707            
2708 4           SPVM_API_push_mortal(env, stack, object);
2709            
2710 4           return object;
2711             }
2712              
2713 2           SPVM_OBJECT* SPVM_API_new_double_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2714            
2715 2           SPVM_OBJECT* object = SPVM_API_new_double_array_no_mortal(env, stack, length);
2716            
2717 2           SPVM_API_push_mortal(env, stack, object);
2718            
2719 2           return object;
2720             }
2721              
2722 7           SPVM_OBJECT* SPVM_API_new_string_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2723            
2724 7           SPVM_OBJECT* string_array = SPVM_API_new_string_array_no_mortal(env, stack, length);
2725            
2726 7           SPVM_API_push_mortal(env, stack, string_array);
2727            
2728 7           return string_array;
2729             }
2730              
2731 367           SPVM_OBJECT* SPVM_API_new_string_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2732            
2733 367           SPVM_RUNTIME_BASIC_TYPE* string_basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(env->runtime, SPVM_NATIVE_C_BASIC_TYPE_ID_STRING);
2734            
2735 367           SPVM_OBJECT* object = SPVM_API_new_object_array_no_mortal(env, stack, string_basic_type, length);
2736            
2737 367           return object;
2738             }
2739              
2740 12           SPVM_OBJECT* SPVM_API_new_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type) {
2741            
2742 12           SPVM_OBJECT* object = SPVM_API_new_object_no_mortal(env, stack, basic_type);
2743            
2744 12           SPVM_API_push_mortal(env, stack, object);
2745            
2746 12           return object;
2747             }
2748              
2749 300969           SPVM_OBJECT* SPVM_API_new_object_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type) {
2750            
2751 300969           SPVM_RUNTIME* runtime = env->runtime;
2752            
2753 300969 50         if (!basic_type) {
2754 0           return NULL;
2755             }
2756            
2757 300969 50         if (basic_type->category != SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS) {
2758 0           return NULL;
2759             }
2760            
2761             // Alloc body length + 1
2762 300969           int32_t fields_length = basic_type->fields_length;
2763            
2764 300969           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + basic_type->fields_size + 1;
2765            
2766 300969 50         if (!basic_type) {
2767 0           return NULL;
2768             }
2769 300969           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 0, fields_length, 0);
2770            
2771 300969           return object;
2772             }
2773              
2774 264404           SPVM_OBJECT* SPVM_API_new_pointer_object_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, void* pointer) {
2775            
2776 264404           void* obj_object = SPVM_API_new_object_no_mortal(env, stack, basic_type);
2777            
2778 264404           SPVM_API_set_pointer(env, stack, obj_object, pointer);
2779            
2780 264404           return obj_object;
2781             }
2782              
2783 233432           SPVM_OBJECT* SPVM_API_new_pointer_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, void* pointer) {
2784            
2785            
2786 233432           SPVM_OBJECT* object = SPVM_API_new_pointer_object_no_mortal(env, stack, basic_type, pointer);
2787            
2788 233432           SPVM_API_push_mortal(env, stack, object);
2789            
2790 233432           return object;
2791             }
2792              
2793 68831           SPVM_OBJECT* SPVM_API_new_string_nolen_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, const char* bytes) {
2794            
2795            
2796 68831           int32_t length = strlen((char*)bytes);
2797            
2798 68831           SPVM_OBJECT* object = SPVM_API_new_string_no_mortal(env, stack, NULL, length);
2799            
2800 68831 50         if (bytes != NULL && length > 0) {
    100          
2801 68690           memcpy((void*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)), (char*)bytes, length);
2802             }
2803            
2804 68831           return object;
2805             }
2806              
2807 68695           SPVM_OBJECT* SPVM_API_new_string_nolen(SPVM_ENV* env, SPVM_VALUE* stack, const char* bytes) {
2808            
2809            
2810 68695           SPVM_OBJECT* object = SPVM_API_new_string_nolen_no_mortal(env, stack, bytes);
2811            
2812 68695           SPVM_API_push_mortal(env, stack, object);
2813            
2814 68695           return object;
2815             }
2816              
2817 159811           SPVM_OBJECT* SPVM_API_new_string_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, const char* bytes, int32_t length) {
2818            
2819            
2820 159811 50         if (length < 0) {
2821 0           return NULL;
2822             }
2823            
2824 159811           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(char) * (length + 1);
2825            
2826 159811           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_STRING);
2827            
2828 159811           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 0, length, 0);
2829            
2830 159811 50         if (object) {
2831 159811 100         if (bytes != NULL && length > 0) {
    100          
2832 83601           memcpy((void*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)), (char*)bytes, length);
2833             }
2834             }
2835            
2836 159811           return object;
2837             }
2838              
2839 32           int32_t SPVM_API_get_bool_object_value(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* bool_object) {
2840            
2841 32           int32_t value = *(int32_t*)((intptr_t)bool_object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
2842            
2843 32           return value;
2844             }
2845              
2846 1319           SPVM_OBJECT* SPVM_API_new_string(SPVM_ENV* env, SPVM_VALUE* stack, const char* bytes, int32_t length) {
2847            
2848            
2849 1319           SPVM_OBJECT* object = SPVM_API_new_string_no_mortal(env, stack, bytes, length);
2850            
2851 1319           SPVM_API_push_mortal(env, stack, object);
2852            
2853 1319           return object;
2854             }
2855              
2856 836           SPVM_OBJECT* SPVM_API_new_byte_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2857            
2858 836 50         if (length < 0) {
2859 0           return NULL;
2860             }
2861            
2862 836           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(int8_t) * (length + 1);
2863            
2864 836           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE);
2865            
2866 836           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2867            
2868 836           return object;
2869             }
2870              
2871 714           SPVM_OBJECT* SPVM_API_new_short_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2872            
2873 714           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(int16_t) * (length + 1);
2874            
2875 714           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT);
2876            
2877 714           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2878            
2879 714           return object;
2880             }
2881              
2882 910           SPVM_OBJECT* SPVM_API_new_int_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2883            
2884 910           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(int32_t) * (length + 1);
2885            
2886 910           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_INT);
2887            
2888 910           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2889            
2890 910           return object;
2891             }
2892              
2893 706           SPVM_OBJECT* SPVM_API_new_long_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2894            
2895 706 50         if (length < 0) {
2896 0           return NULL;
2897             }
2898            
2899 706           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(int64_t) * (length + 1);
2900            
2901 706           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_LONG);
2902            
2903 706           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2904            
2905 706           return object;
2906             }
2907              
2908 706           SPVM_OBJECT* SPVM_API_new_float_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2909            
2910 706           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(float) * (length + 1);
2911            
2912 706           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT);
2913            
2914 706           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2915            
2916 706           return object;
2917             }
2918              
2919 714           SPVM_OBJECT* SPVM_API_new_double_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2920            
2921 714           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(double) * (length + 1);
2922            
2923 714           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE);
2924            
2925 714           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2926            
2927 714           return object;
2928             }
2929              
2930 52598           SPVM_OBJECT* SPVM_API_new_object_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t length) {
2931            
2932 52598           SPVM_RUNTIME* runtime = env->runtime;
2933            
2934             SPVM_OBJECT object_for_type_check;
2935 52598           object_for_type_check.basic_type = basic_type;
2936 52598           object_for_type_check.type_dimension = 1;
2937            
2938 52598           int32_t is_object_array = SPVM_API_is_object_array(env, stack, &object_for_type_check);
2939            
2940 52598 50         if (!is_object_array) {
2941 0           return NULL;
2942             }
2943            
2944 52598 50         if (!basic_type) {
2945 0           return NULL;
2946             }
2947            
2948 52598           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(void*) * (length + 1);
2949            
2950 52598           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2951            
2952 52598           return object;
2953             }
2954              
2955 4           SPVM_OBJECT* SPVM_API_new_object_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t length) {
2956            
2957 4           SPVM_OBJECT* object = SPVM_API_new_object_array_no_mortal(env, stack, basic_type, length);
2958            
2959 4           SPVM_API_push_mortal(env, stack, object);
2960            
2961 4           return object;
2962             }
2963              
2964 70           SPVM_OBJECT* SPVM_API_new_muldim_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension, int32_t length) {
2965            
2966 70 50         if (type_dimension < 2) {
2967 0           return NULL;
2968             }
2969 70 50         else if (basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_ANY_OBJECT) {
2970 0           return NULL;
2971             }
2972            
2973 70           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(void*) * (length + 1);
2974            
2975 70 50         if (!basic_type) {
2976 0           return NULL;
2977             }
2978 70           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, type_dimension, length, 0);
2979            
2980 70           return object;
2981             }
2982              
2983 0           SPVM_OBJECT* SPVM_API_new_muldim_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension, int32_t length) {
2984            
2985 0           SPVM_OBJECT* object = SPVM_API_new_muldim_array_no_mortal(env, stack, basic_type, type_dimension, length);
2986            
2987 0           SPVM_API_push_mortal(env, stack, object);
2988            
2989 0           return object;
2990             }
2991              
2992 226           SPVM_OBJECT* SPVM_API_new_mulnum_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t length) {
2993            
2994 226           SPVM_RUNTIME* runtime = env->runtime;
2995            
2996             // valut_t array dimension must be 1
2997 226           const char* basic_type_name = basic_type->name;
2998            
2999 226           int32_t fields_length = basic_type->fields_length;
3000 226           SPVM_RUNTIME_FIELD* field_first = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, basic_type, 0);
3001            
3002 226           int32_t field_basic_type_id = field_first->basic_type->id;
3003            
3004             int32_t unit_size;
3005 226 100         if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE) {
3006 42           unit_size = sizeof(int8_t);
3007             }
3008 184 100         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT) {
3009 32           unit_size = sizeof(int16_t);
3010             }
3011 152 100         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_INT) {
3012 44           unit_size = sizeof(int32_t);
3013             }
3014 108 100         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) {
3015 32           unit_size = sizeof(int64_t);
3016             }
3017 76 100         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT) {
3018 28           unit_size = sizeof(float);
3019             }
3020 48 50         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE) {
3021 48           unit_size = sizeof(double);
3022             }
3023             else {
3024 0           assert(0);
3025             }
3026            
3027 226           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + unit_size * fields_length * (length + 1);
3028            
3029 226           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
3030            
3031 226           return object;
3032             }
3033              
3034 0           SPVM_OBJECT* SPVM_API_new_mulnum_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t length) {
3035            
3036 0           SPVM_OBJECT* object = SPVM_API_new_mulnum_array_no_mortal(env, stack, basic_type, length);
3037            
3038 0           SPVM_API_push_mortal(env, stack, object);
3039            
3040 0           return object;
3041             }
3042              
3043 268           SPVM_OBJECT* SPVM_API_new_array_proto_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t length) {
3044              
3045 268 50         if (array == NULL) {
3046 0           return NULL;
3047             }
3048            
3049 268 50         if (length < 0) {
3050 0           return NULL;
3051             }
3052            
3053 268           size_t element_size = SPVM_API_get_elem_size(env, stack, array);
3054            
3055 268           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + element_size * (length + 1);
3056            
3057 268           SPVM_RUNTIME_BASIC_TYPE* array_basic_type = SPVM_API_get_object_basic_type(env, stack, array);
3058 268           SPVM_OBJECT* new_array = SPVM_API_new_object_common(env, stack, alloc_size, array_basic_type, array->type_dimension, length, 0);
3059            
3060 268           return new_array;
3061             }
3062              
3063 262           SPVM_OBJECT* SPVM_API_new_array_proto(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t length) {
3064            
3065            
3066 262           SPVM_OBJECT* object = SPVM_API_new_array_proto_no_mortal(env, stack, array, length);
3067            
3068 262           SPVM_API_push_mortal(env, stack, object);
3069            
3070 262           return object;
3071             }
3072              
3073 0           int32_t SPVM_API_get_object_basic_type_id(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3074 0           return object->basic_type->id;
3075             }
3076              
3077 2699093           SPVM_RUNTIME_BASIC_TYPE* SPVM_API_get_object_basic_type(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3078            
3079 2699093           return object->basic_type;
3080             }
3081              
3082 190072           const char* SPVM_API_get_object_basic_type_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3083            
3084 190072           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3085            
3086 190072           return object_basic_type->name;
3087             }
3088              
3089 21006           int32_t SPVM_API_get_object_type_dimension(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3090 21006           return object->type_dimension;
3091             }
3092              
3093 187742           int32_t SPVM_API_length(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3094            
3095 187742           int32_t length = object->length;
3096            
3097 187742           return length;
3098             }
3099              
3100 518562           void SPVM_API_set_length(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, int32_t length) {
3101            
3102 518562           object->length = length;
3103 518562           }
3104              
3105 1022           int8_t* SPVM_API_get_elems_byte(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3106            
3107 1022           return (int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3108             }
3109              
3110 180106           const char* SPVM_API_get_chars(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
3111            
3112 180106           return (const char*)((intptr_t)string + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3113             }
3114              
3115 926           int16_t* SPVM_API_get_elems_short(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3116            
3117 926           return (int16_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3118             }
3119              
3120 1150           int32_t* SPVM_API_get_elems_int(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3121            
3122 1150           return (int32_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3123             }
3124              
3125 928           int64_t* SPVM_API_get_elems_long(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3126            
3127 928           return (int64_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3128             }
3129              
3130 922           float* SPVM_API_get_elems_float(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3131            
3132 922           return (float*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3133             }
3134              
3135 916           double* SPVM_API_get_elems_double(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3136            
3137 916           return (double*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3138             }
3139              
3140 101691           SPVM_OBJECT* SPVM_API_get_elem_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t index) {
3141            
3142 101691           SPVM_OBJECT* object_maybe_weaken = ((SPVM_OBJECT**)((intptr_t)array + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[index];
3143 101691           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, object_maybe_weaken);
3144            
3145 101691           return object;
3146             }
3147              
3148 30816           void SPVM_API_set_elem_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t index, SPVM_OBJECT* object) {
3149            
3150 30816           void* object_ref = &((void**)((intptr_t)array + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[index];
3151            
3152 30816           SPVM_API_assign_object(env, stack, object_ref, object);
3153 30816           }
3154              
3155 101479           SPVM_OBJECT* SPVM_API_get_elem_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t index) {
3156            
3157 101479           return SPVM_API_get_elem_object(env, stack, array, index);
3158             }
3159              
3160 119           void SPVM_API_set_elem_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t index, SPVM_OBJECT* string) {
3161            
3162 119           SPVM_API_set_elem_object(env, stack, array, index, string);
3163 119           }
3164              
3165 1722071           void* SPVM_API_get_pointer(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3166            
3167 1722071           return object->pointer;
3168             }
3169              
3170 264404           void SPVM_API_set_pointer(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, void* pointer) {
3171            
3172 264404           object->pointer = pointer;
3173 264404           }
3174              
3175 751783           SPVM_RUNTIME_FIELD* SPVM_API_get_field(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name) {
3176            
3177 751783           SPVM_RUNTIME* runtime = env->runtime;
3178            
3179 751783 50         if (!object) {
3180 0           return NULL;
3181             }
3182            
3183 751783           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3184            
3185 751783 50         if (object->type_dimension != 0) {
3186 0           return NULL;
3187             }
3188            
3189 751783           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_name(runtime, object_basic_type, field_name);
3190            
3191 751783           return field;
3192             }
3193              
3194 3026           SPVM_RUNTIME_FIELD* SPVM_API_get_field_static(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* field_name) {
3195            
3196 3026           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3197            
3198 3026 50         if (!basic_type) {
3199 0           return NULL;
3200             }
3201            
3202 3026           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_name(env->runtime, basic_type, field_name);
3203            
3204 3026           return field;
3205             }
3206              
3207 108           SPVM_RUNTIME_CLASS_VAR* SPVM_API_get_class_var(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* class_var_name) {
3208            
3209 108           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3210            
3211 108 50         if (!basic_type) {
3212 0           return NULL;
3213             }
3214            
3215 108           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
3216            
3217 108           return class_var;
3218             }
3219              
3220 12957           SPVM_RUNTIME_METHOD* SPVM_API_get_method(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* method_name) {
3221            
3222 12957           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3223            
3224 12957 50         if (!basic_type) {
3225 0           return NULL;
3226             }
3227            
3228 12957           SPVM_RUNTIME_METHOD* method = SPVM_API_BASIC_TYPE_get_method_by_name(env->runtime, basic_type, method_name);
3229            
3230 12957           return method;
3231             }
3232              
3233 58           SPVM_RUNTIME_METHOD* SPVM_API_get_class_method(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* method_name) {
3234            
3235 58           SPVM_RUNTIME_METHOD* method = SPVM_API_get_method(env, stack, basic_type_name, method_name);
3236            
3237 58 50         if (method) {
3238 58 50         if (!method->is_class_method) {
3239 0           return NULL;
3240             }
3241             }
3242            
3243 58           return method;
3244             }
3245              
3246 2           SPVM_RUNTIME_METHOD* SPVM_API_get_instance_method_static(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* method_name) {
3247            
3248 2           SPVM_RUNTIME_METHOD* method = SPVM_API_get_method(env, stack, basic_type_name, method_name);
3249            
3250 2 50         if (method) {
3251 2 50         if (method->is_class_method) {
3252 0           return NULL;
3253             }
3254             }
3255            
3256 2           return method;
3257             }
3258              
3259 689102           SPVM_RUNTIME_METHOD* SPVM_API_get_instance_method(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* method_name) {
3260            
3261             // Method
3262 689102           SPVM_RUNTIME_METHOD* method = NULL;
3263            
3264             // Compiler
3265 689102           SPVM_RUNTIME* runtime = env->runtime;
3266            
3267 689102 50         if (!object) {
3268 0           return NULL;
3269             }
3270            
3271             // Basic type
3272 689102           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3273 689102           SPVM_RUNTIME_BASIC_TYPE* parent_basic_type = object_basic_type;
3274            
3275             while (1) {
3276 689204 100         if (!parent_basic_type) {
3277 10           break;
3278             }
3279            
3280             // Method
3281 689194           method = SPVM_API_BASIC_TYPE_get_method_by_name(runtime, parent_basic_type, method_name);
3282 689194 100         if (method) {
3283             // Instance method
3284 689092 50         if (method->is_class_method) {
3285 0           method = NULL;
3286             }
3287 689092           break;
3288             }
3289            
3290 102           parent_basic_type = parent_basic_type->parent;
3291 102           }
3292            
3293 689102           return method;
3294             }
3295              
3296             // Deprecated
3297 1457635           void* SPVM_API_new_memory_stack(SPVM_ENV* env, SPVM_VALUE* stack, size_t size) {
3298            
3299 1457635           return SPVM_API_new_memory_block(env, stack, size);
3300             }
3301              
3302 1978224           void* SPVM_API_new_memory_block(SPVM_ENV* env, SPVM_VALUE* stack, size_t size) {
3303            
3304 1978224           SPVM_RUNTIME* runtime = env->runtime;
3305            
3306 1978224 50         assert(size > 0);
3307            
3308             if ((uint64_t)size > (uint64_t)SIZE_MAX) {
3309             return NULL;
3310             }
3311            
3312 1978224           void* block = SPVM_ALLOCATOR_alloc_memory_block_unmanaged((size_t)size);
3313            
3314 1978224           stack[SPVM_API_C_STACK_INDEX_MEMORY_BLOCKS_COUNT].ival++;
3315            
3316             #ifdef SPVM_DEBUG_MEMORY
3317             fprintf(runtime->spvm_stderr, "[Debug]Function : new_memory_block, Block Address: %p, Stack Address : %p, Memory Blocks Count : %d\n", block, stack, stack[SPVM_API_C_STACK_INDEX_MEMORY_BLOCKS_COUNT].ival);
3318             #endif
3319            
3320 1978224           return block;
3321             }
3322              
3323             // Deprecated
3324 1977554           void SPVM_API_free_memory_block(SPVM_ENV* env, SPVM_VALUE* stack, void* block) {
3325            
3326 1977554           SPVM_RUNTIME* runtime = env->runtime;
3327            
3328 1977554 100         if (block) {
3329 1977552           SPVM_ALLOCATOR_free_memory_block_unmanaged(block);
3330 1977552           stack[SPVM_API_C_STACK_INDEX_MEMORY_BLOCKS_COUNT].ival--;
3331             #ifdef SPVM_DEBUG_MEMORY
3332             fprintf(runtime->spvm_stderr, "[Debug]Function : free_memory_block, Block Address: %p, Stack Address : %p, Memory Blocks Count : %d\n", block, stack, stack[SPVM_API_C_STACK_INDEX_MEMORY_BLOCKS_COUNT].ival);
3333             #endif
3334             }
3335 1977554           }
3336              
3337 1457635           void SPVM_API_free_memory_stack(SPVM_ENV* env, SPVM_VALUE* stack, void* block) {
3338            
3339 1457635           SPVM_API_free_memory_block(env, stack, block);
3340            
3341 1457635           }
3342              
3343 548           int32_t SPVM_API_get_memory_blocks_count_stack(SPVM_ENV* env, SPVM_VALUE* stack) {
3344            
3345 548           return SPVM_API_get_memory_blocks_count(env, stack);
3346             }
3347              
3348 572           int32_t SPVM_API_get_memory_blocks_count(SPVM_ENV* env, SPVM_VALUE* stack) {
3349            
3350            
3351 572           int32_t memory_blocks_count = stack[SPVM_API_C_STACK_INDEX_MEMORY_BLOCKS_COUNT].ival;
3352            
3353 572           return memory_blocks_count;
3354             }
3355              
3356 222           SPVM_OBJECT* SPVM_API_copy_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3357 222 50         if (!object) {
3358 0           return NULL;
3359             }
3360            
3361             SPVM_OBJECT* new_object;
3362            
3363 222           int32_t length = SPVM_API_length(env, stack, object);
3364            
3365 222 100         if (SPVM_API_is_string(env, stack, object)) {
3366 216           new_object = SPVM_API_new_string_no_mortal(env, stack, NULL, length);
3367            
3368 216           const char* object_chars = SPVM_API_get_chars(env, stack, object);
3369 216           char* new_object_chars = (char*)SPVM_API_get_chars(env, stack, new_object);
3370            
3371 216           memcpy(new_object_chars, object_chars, length);
3372             }
3373 12 100         else if (SPVM_API_is_numeric_array(env, stack, object) || SPVM_API_is_mulnum_array(env, stack, object)) {
    50          
3374 6           new_object = SPVM_API_new_array_proto_no_mortal(env, stack, object, length);
3375            
3376 6           const char* object_bytes = (const char*)SPVM_API_get_elems_byte(env, stack, object);
3377 6           char* new_object_bytes = (char*)SPVM_API_get_elems_byte(env, stack, new_object);
3378            
3379 6           size_t element_size = SPVM_API_get_elem_size(env, stack, object);
3380            
3381 6           memcpy(new_object_bytes, object_bytes, element_size * length);
3382             }
3383             else {
3384 0           new_object = NULL;
3385             }
3386            
3387 222           return new_object;
3388             }
3389              
3390 0           SPVM_OBJECT* SPVM_API_copy(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3391            
3392            
3393 0           SPVM_OBJECT* new_object = SPVM_API_copy_no_mortal(env, stack, object);
3394            
3395 0           SPVM_API_push_mortal(env, stack, new_object);
3396            
3397 0           return new_object;
3398             }
3399              
3400 34           void SPVM_API_shorten(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string, int32_t new_length) {
3401            
3402            
3403 34 50         if (string != NULL) {
3404 34 50         if (SPVM_API_is_string(env, stack, string)) {
3405 34 50         if (!SPVM_API_is_read_only(env, stack, string)) {
3406 34           int32_t length = SPVM_API_length(env, stack, string);
3407            
3408 34 100         if (new_length > length) {
3409 2           new_length = length;
3410             }
3411 32 50         else if (new_length < 0) {
3412 0           new_length = 0;
3413             }
3414            
3415 34           SPVM_API_set_length(env, stack, string, new_length);
3416 34           char* chars = (char*)SPVM_API_get_chars(env, stack, string);
3417 34 50         if (new_length > length) {
3418 0           memset(chars + new_length, 0, new_length - length);
3419             }
3420             }
3421             }
3422             }
3423 34           }
3424              
3425 107723           int32_t SPVM_API_elem_isa(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, SPVM_OBJECT* element) {
3426            
3427 107723           SPVM_RUNTIME* runtime = env->runtime;
3428            
3429 107723 50         assert(array);
3430            
3431 107723           SPVM_RUNTIME_BASIC_TYPE* array_basic_type = SPVM_API_get_object_basic_type(env, stack,array);
3432            
3433 107723           int32_t array_type_dimension = array->type_dimension;
3434            
3435 107723 50         assert(array_type_dimension > 0);
3436 107723           int32_t runtime_assignability = SPVM_API_isa(env, stack, element, array_basic_type, array_type_dimension - 1);
3437              
3438 107723           return runtime_assignability;
3439             }
3440              
3441 962           int32_t SPVM_API_is_type(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension) {
3442            
3443             // Object must be not null
3444 962 50         assert(object);
3445            
3446 962           int32_t is_type = 0;
3447 962           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3448 962 100         if (object_basic_type->id == basic_type->id && object->type_dimension == type_dimension) {
    100          
3449 956           is_type = 1;
3450             }
3451            
3452 962           return is_type;
3453             }
3454              
3455 820           int32_t SPVM_API_is_type_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* basic_type_name, int32_t type_dimension) {
3456            
3457 820           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3458 820 50         if (!basic_type) {
3459 0           return 0;
3460             };
3461            
3462 820           int32_t is_type = SPVM_API_is_type(env, stack, object, basic_type, type_dimension);
3463            
3464 820           return is_type;
3465             }
3466              
3467 312571           int32_t SPVM_API_isa(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension) {
3468            
3469 312571           SPVM_RUNTIME* runtime = env->runtime;
3470            
3471             int32_t isa;
3472 312571 100         if (object == NULL) {
3473 222           isa = 1;
3474             }
3475             else {
3476 312349           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3477 312349           int32_t object_type_dimension = object->type_dimension;
3478 312349 50         if (!basic_type) {
3479 0           isa = 0;
3480             }
3481             else {
3482 312349           isa = SPVM_API_TYPE_can_assign(env->runtime, basic_type, type_dimension, 0, object_basic_type, object_type_dimension, 0);
3483             }
3484             }
3485            
3486 312571           return isa;
3487             }
3488              
3489 0           int32_t SPVM_API_isa_by_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* basic_type_name, int32_t type_dimension) {
3490            
3491 0           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3492 0 0         if (!basic_type) {
3493 0           return 0;
3494             };
3495            
3496 0           int32_t isa = SPVM_API_isa(env, stack, object, basic_type, type_dimension);
3497            
3498 0           return isa;
3499             }
3500              
3501 0           int32_t SPVM_API_get_basic_type_id_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
3502 0           *error_id = 0;
3503            
3504 0           int32_t basic_type_id = SPVM_API_get_basic_type_id(env, stack, basic_type_name);
3505 0 0         if (basic_type_id < 0) {
3506 0           *error_id = 1;
3507 0           SPVM_API_die(env, stack, "The %s basic type is not found", basic_type_name, func_name, file, line);
3508             };
3509 0           return basic_type_id;
3510             }
3511              
3512 0           SPVM_RUNTIME_BASIC_TYPE* SPVM_API_get_basic_type_by_name(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, int32_t* error_id, const char* func_name, const char* file, int32_t line) {
3513 0           *error_id = 0;
3514            
3515 0           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3516 0 0         if (!basic_type) {
3517 0           *error_id = 1;
3518 0           SPVM_API_die(env, stack, "The %s basic type is not found", basic_type_name, func_name, file, line);
3519             };
3520            
3521 0           return basic_type;
3522             }
3523              
3524 164403           SPVM_RUNTIME_BASIC_TYPE* SPVM_API_get_basic_type_by_id(SPVM_ENV* env, SPVM_VALUE* stack, int32_t basic_type_id) {
3525            
3526 164403           void* basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(env->runtime, basic_type_id);
3527            
3528 164403           return basic_type;
3529             }
3530              
3531 8           void* SPVM_API_strerror_string(SPVM_ENV* env, SPVM_VALUE* stack, int32_t errno_value, int32_t length) {
3532            
3533 8 50         if (length < 0) {
3534 0           return NULL;
3535             }
3536            
3537 8 50         if (length == 0) {
3538 8           length = 64;
3539             }
3540            
3541 8           void* obj_strerror_value = SPVM_API_new_string(env, stack, NULL, length);
3542 8           char* strerror_value = (char*)SPVM_API_get_chars(env, stack, obj_strerror_value);
3543            
3544 8           int32_t status = SPVM_STRERROR_strerror(errno_value, strerror_value, length);
3545            
3546 8 50         if (status == 0) {
3547 8           SPVM_API_shorten(env, stack, obj_strerror_value, strlen(strerror_value));
3548 8           return obj_strerror_value;
3549             }
3550             else {
3551 0           return NULL;
3552             }
3553             }
3554              
3555 4           const char* SPVM_API_strerror(SPVM_ENV* env, SPVM_VALUE* stack, int32_t errno_value, int32_t length) {
3556            
3557 4           void* obj_strerror_value = SPVM_API_strerror_string(env, stack, errno_value, length);
3558            
3559 4 50         if (obj_strerror_value) {
3560 4           char* strerror_value = (char*)SPVM_API_get_chars(env, stack, obj_strerror_value);
3561 4           return strerror_value;
3562             }
3563             else {
3564 0           return NULL;
3565             }
3566             }
3567              
3568 2           void* SPVM_API_strerror_string_nolen(SPVM_ENV* env, SPVM_VALUE* stack, int32_t errno_value) {
3569 2           return SPVM_API_strerror_string(env, stack, errno_value, 0);
3570             }
3571              
3572 2           const char* SPVM_API_strerror_nolen(SPVM_ENV* env, SPVM_VALUE* stack, int32_t errno_value) {
3573 2           return SPVM_API_strerror(env, stack, errno_value, 0);
3574             }
3575              
3576 1457635           int32_t SPVM_API_call_method_vm(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_METHOD* method, int32_t args_width) {
3577 1457635           return SPVM_VM_call_method(env, stack, method, args_width);
3578             }
3579              
3580 4           const char* SPVM_API_get_spvm_version_string(SPVM_ENV* env, SPVM_VALUE* stack) {
3581            
3582 4           const char* spvm_version_string = SPVM_NATIVE_VERSION_STRING;
3583            
3584 4           return spvm_version_string;
3585             }
3586              
3587 2           double SPVM_API_get_spvm_version_number(SPVM_ENV* env, SPVM_VALUE* stack) {
3588            
3589 2           const char* spvm_version_string = SPVM_API_get_spvm_version_string(env, stack);
3590            
3591 2 50         assert(spvm_version_string);
3592            
3593 2           int32_t spvm_version_string_length = strlen(spvm_version_string);
3594            
3595             char *end;
3596 2           errno = 0;
3597 2           double version_number = strtod(spvm_version_string, &end);
3598 2 50         assert(*end == '\0');
3599 2 50         assert(errno == 0);
3600            
3601 2           return version_number;
3602             }
3603              
3604 15           const char* SPVM_API_get_version_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type){
3605            
3606 15           return basic_type->version_string;
3607             }
3608              
3609 4           double SPVM_API_get_version_number(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type) {
3610            
3611 4           const char* version_string = SPVM_API_get_version_string(env, stack, basic_type);
3612            
3613 4 50         if (!version_string) {
3614 0           return -1;
3615             }
3616            
3617 4           int32_t version_string_length = strlen(version_string);
3618            
3619 4           char version_string_without_hyphen[20] = {0};
3620 4           int32_t version_string_without_hyphen_length = 0;
3621 36 100         for (int32_t i = 0; i < version_string_length; i++) {
3622 32           char ch = version_string[i];
3623 32 50         if (!(ch == '_')) {
3624 32           version_string_without_hyphen[version_string_without_hyphen_length] = ch;
3625 32           version_string_without_hyphen_length++;
3626             }
3627             }
3628            
3629             char *end;
3630 4           errno = 0;
3631 4           double version_number = strtod(version_string_without_hyphen, &end);
3632 4 50         assert(*end == '\0');
3633 4 50         assert(errno == 0);
3634            
3635 4           return version_number;
3636             }
3637              
3638 518528           SPVM_OBJECT* SPVM_API_new_object_common(SPVM_ENV* env, SPVM_VALUE* stack, size_t alloc_size, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension, int32_t length, int32_t flag) {
3639            
3640 518528           SPVM_OBJECT* object = SPVM_API_new_memory_block(env, stack, alloc_size);
3641            
3642 518528 50         if (object) {
3643 518528           object->basic_type = basic_type;
3644 518528           object->type_dimension = type_dimension;
3645 518528           object->flag = flag;
3646            
3647             // The length of string can be shorten.
3648 518528           SPVM_API_set_length(env, stack, object, length);
3649             }
3650            
3651 518528           SPVM_MUTEX* mutex = SPVM_API_get_object_mutex(env, stack, object);
3652            
3653 518528           SPVM_MUTEX_init(mutex);
3654            
3655 518528           return object;
3656             }
3657              
3658 20           int32_t SPVM_API_check_stack_env(SPVM_ENV* env, SPVM_VALUE* stack) {
3659            
3660 20           int32_t is_valid = 0;
3661 20 50         if (stack[SPVM_API_C_STACK_INDEX_ENV].oval == env) {
3662 20           is_valid = 1;
3663             }
3664            
3665 20           return is_valid;
3666             }
3667              
3668 2843489           int32_t SPVM_API_call_method_common(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_METHOD* method, int32_t args_width, int32_t mortal) {
3669            
3670             // Runtime
3671 2843489           SPVM_RUNTIME* runtime = env->runtime;
3672            
3673 2843489           int32_t error_id = 0;
3674 2843489           stack[SPVM_API_C_STACK_INDEX_ARGS_WIDTH].ival = args_width;
3675 2843489           stack[SPVM_API_C_STACK_INDEX_CALL_DEPTH].ival++;
3676            
3677 2843489           int32_t max_call_depth = 10000;
3678 2843489 50         if (stack[SPVM_API_C_STACK_INDEX_CALL_DEPTH].ival > max_call_depth) {
3679 0           error_id = SPVM_API_die(env, stack, "Deep recursion occurs. The depth of a method call must be less than %d", max_call_depth, FILE_NAME, __LINE__);
3680             }
3681             else {
3682 2843489           void* method_return_basic_type = method->return_basic_type;
3683 2843489           int32_t method_return_type_dimension = method->return_type_dimension;
3684 2843489           int32_t method_return_type_flag = method->return_type_flag;
3685            
3686 2843489           SPVM_RUNTIME_BASIC_TYPE* current_basic_type = method->current_basic_type;
3687            
3688 2843489           int32_t method_return_type_is_object = SPVM_API_TYPE_is_object_type(runtime, method_return_basic_type, method_return_type_dimension, method_return_type_flag);
3689 2843489           int32_t no_need_call = 0;
3690 2843489 100         if (method->is_init) {
3691            
3692 21535 100         if (current_basic_type->initialized) {
3693 12198           no_need_call = 1;
3694             }
3695             else {
3696 9337           current_basic_type->initialized = 1;
3697             }
3698             }
3699            
3700 2843489 100         if (!no_need_call) {
3701             // Call native method
3702 2831291 100         if (method->is_native) {
3703             // Enter scope
3704 1362919           int32_t original_mortal_stack_top = SPVM_API_enter_scope(env, stack);
3705            
3706             // Set argument default values
3707 1362919           int32_t optional_args_length = method->args_length - method->required_args_length;
3708 1362919 100         if (optional_args_length > 0) {
3709            
3710             // Operation codes
3711 368           SPVM_OPCODE* opcodes = method->opcodes;
3712            
3713             // Execute operation codes
3714 368           int32_t opcode_rel_index = 0;
3715             while (1) {
3716            
3717 820           SPVM_OPCODE* opcode = &(opcodes[opcode_rel_index]);
3718            
3719 820 100         if (opcode->id == SPVM_OPCODE_C_ID_END_ARGS) {
3720 368           break;
3721             }
3722            
3723 452           switch (opcode->id) {
3724             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_BYTE: {
3725 4           int32_t stack_index = opcode->operand3 & 0xFF;
3726 4 100         if (stack_index >= args_width) {
3727 2           stack[stack_index].bval = (int8_t)(uint8_t)opcode->operand1;
3728             }
3729 4           break;
3730             }
3731             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_SHORT: {
3732 4           int32_t stack_index = opcode->operand3 & 0xFF;
3733 4 100         if (stack_index >= args_width) {
3734 2           stack[stack_index].sval = (int16_t)(uint16_t)opcode->operand1;
3735             }
3736 4           break;
3737             }
3738             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_INT: {
3739 16           int32_t stack_index = opcode->operand3 & 0xFF;
3740 16 100         if (stack_index >= args_width) {
3741 8           stack[stack_index].ival = (int32_t)opcode->operand1;
3742             }
3743 16           break;
3744             }
3745             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_LONG: {
3746 4           int32_t stack_index = opcode->operand3 & 0xFF;
3747 4 100         if (stack_index >= args_width) {
3748 2           stack[stack_index].lval = *(int64_t*)&opcode->operand1;
3749             }
3750 4           break;
3751             }
3752             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_FLOAT: {
3753 4           int32_t stack_index = opcode->operand3 & 0xFF;
3754 4 100         if (stack_index >= args_width) {
3755             SPVM_VALUE default_value;
3756 2           default_value.ival = (int32_t)opcode->operand1;
3757 2           stack[stack_index].fval = default_value.fval;
3758             }
3759 4           break;
3760             }
3761             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_DOUBLE: {
3762 4           int32_t stack_index = opcode->operand3 & 0xFF;
3763 4 100         if (stack_index >= args_width) {
3764 2           stack[stack_index].dval = *(double*)&opcode->operand1;
3765             }
3766 4           break;
3767             }
3768             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_OBJECT: {
3769 372           int32_t stack_index = opcode->operand3 & 0xFF;
3770 372 100         if (stack_index >= args_width) {
3771 16           stack[stack_index].oval = NULL;
3772             }
3773 372           break;
3774             }
3775             }
3776            
3777 452           opcode_rel_index++;
3778 452           }
3779             }
3780            
3781             // Call native subrotuine
3782 1362919           int32_t (*native_address)(SPVM_ENV*, SPVM_VALUE*) = method->native_address;
3783 1362919 50         assert(native_address != NULL);
3784 1362919           error_id = (*native_address)(env, stack);
3785            
3786             // Increment ref count of return value
3787 1362919 100         if (!error_id) {
3788 1362609 100         if (method_return_type_is_object) {
3789 306584           SPVM_OBJECT* return_object = *(void**)&stack[0];
3790 306584 100         if (return_object != NULL) {
3791 305998           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, return_object);
3792            
3793 305998           SPVM_MUTEX_lock(object_mutex);
3794            
3795 305998           SPVM_API_inc_ref_count(env, stack, return_object);
3796            
3797 305998           SPVM_MUTEX_unlock(object_mutex);
3798             }
3799             }
3800             }
3801            
3802             // Leave scope
3803 1362919           SPVM_API_leave_scope(env, stack, original_mortal_stack_top);
3804            
3805             // Decrement ref count of return value
3806 1362919 100         if (!error_id) {
3807 1362609 100         if (method_return_type_is_object) {
3808 306584           SPVM_OBJECT* return_object = *(void**)&stack[0];
3809 306584 100         if (return_object != NULL) {
3810 305998           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, return_object);
3811            
3812 305998           SPVM_MUTEX_lock(object_mutex);
3813            
3814 305998           SPVM_API_dec_ref_count(env, stack, return_object);
3815            
3816 305998           SPVM_MUTEX_unlock(object_mutex);
3817             }
3818             }
3819             }
3820            
3821             // Set default exception message
3822 1362919 100         if (error_id && SPVM_API_get_exception(env, stack) == NULL) {
    50          
3823 0           void* exception = SPVM_API_new_string_nolen_no_mortal(env, stack, "Error");
3824 1362919           SPVM_API_set_exception(env, stack, exception);
3825             }
3826             }
3827             else {
3828             // Call precompiled method
3829 1468372           void* method_precompile_address = method->precompile_address;
3830 1468372 100         if (method_precompile_address) {
3831 10737           int32_t (*precompile_address)(SPVM_ENV*, SPVM_VALUE*) = method_precompile_address;
3832 10737           error_id = (*precompile_address)(env, stack);
3833             }
3834             // Call sub virtual machine
3835             else {
3836 1457635           error_id = SPVM_API_call_method_vm(env, stack, method, args_width);
3837             }
3838             }
3839            
3840 2831291 100         if (mortal && method_return_type_is_object) {
    100          
3841 6           SPVM_API_push_mortal(env, stack, stack[0].oval);
3842             }
3843             }
3844             }
3845            
3846 2843489           stack[SPVM_API_C_STACK_INDEX_CALL_DEPTH].ival--;
3847            
3848 2843489           return error_id;
3849             }
3850              
3851 303785           int32_t SPVM_API_push_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3852            
3853            
3854 303785           SPVM_OBJECT*** current_mortal_stack_ptr = (SPVM_OBJECT***)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK];
3855 303785           int32_t* current_mortal_stack_top_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_TOP];
3856 303785           int32_t* current_mortal_stack_capacity_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_CAPACITY];
3857            
3858 303785 50         if (object != NULL) {
3859             // Extend mortal stack
3860 303785 100         if (*current_mortal_stack_top_ptr >= *current_mortal_stack_capacity_ptr) {
3861 359           int32_t new_mortal_stack_capacity = *current_mortal_stack_capacity_ptr * 2;
3862 359           SPVM_OBJECT** new_mortal_stack = SPVM_API_new_memory_block(env, stack, sizeof(void*) * new_mortal_stack_capacity);
3863 359 50         if (new_mortal_stack == NULL) {
3864 0           return SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_CLASS;
3865             }
3866 359           memcpy(new_mortal_stack, *current_mortal_stack_ptr, sizeof(void*) * *current_mortal_stack_capacity_ptr);
3867 359           *current_mortal_stack_capacity_ptr = new_mortal_stack_capacity;
3868 359           SPVM_API_free_memory_block(env, stack, *current_mortal_stack_ptr);
3869 359           *current_mortal_stack_ptr = NULL;
3870 359           *current_mortal_stack_ptr = new_mortal_stack;
3871             }
3872            
3873 303785           SPVM_API_assign_object(env, stack, &(*current_mortal_stack_ptr)[*current_mortal_stack_top_ptr], object);
3874            
3875 303785           *current_mortal_stack_top_ptr = *current_mortal_stack_top_ptr + 1;
3876             }
3877            
3878 303785           return 0;
3879             }
3880              
3881 1362921           void SPVM_API_leave_scope(SPVM_ENV* env, SPVM_VALUE* stack, int32_t original_mortal_stack_top) {
3882            
3883 1362921           SPVM_OBJECT*** current_mortal_stack_ptr = (SPVM_OBJECT***)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK];
3884 1362921           int32_t* current_mortal_stack_top_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_TOP];
3885 1362921           int32_t* current_mortal_stack_capacity_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_CAPACITY];
3886            
3887             int32_t mortal_stack_index;
3888 1666706 100         for (mortal_stack_index = original_mortal_stack_top; mortal_stack_index < *current_mortal_stack_top_ptr; mortal_stack_index++) {
3889            
3890 303785           SPVM_OBJECT** object_ref = &(*current_mortal_stack_ptr)[mortal_stack_index];
3891            
3892 303785           SPVM_API_assign_object(env, stack, object_ref, NULL);
3893            
3894             }
3895            
3896 1362921           *current_mortal_stack_top_ptr = original_mortal_stack_top;
3897 1362921           }
3898              
3899 1300771           void SPVM_API_leave_scope_local(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** object_vars, int32_t* mortal_stack, int32_t* mortal_stack_top_ptr, int32_t original_mortal_stack_top) {
3900            
3901 2131311 100         for (int32_t mortal_stack_index = original_mortal_stack_top; mortal_stack_index < *mortal_stack_top_ptr; mortal_stack_index++) {
3902 830540           int32_t var_index = mortal_stack[mortal_stack_index];
3903 830540           SPVM_OBJECT** object_ref = (SPVM_OBJECT**)&object_vars[var_index];
3904 830540 100         if (*object_ref != NULL) {
3905 810029           SPVM_API_assign_object(env, stack, object_ref, NULL);
3906             }
3907             }
3908 1300771           *mortal_stack_top_ptr = original_mortal_stack_top;
3909            
3910 1300771           }
3911              
3912 8304489           SPVM_OBJECT* SPVM_API_get_object_no_weaken_address(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3913             // Dropping weaken flag
3914 8304489           void* object_no_weaken_address = (void*)((intptr_t)object & ~(intptr_t)1);
3915            
3916 8304489           return object_no_weaken_address;
3917             }
3918              
3919 1868556           int32_t SPVM_API_isweak_only_check_flag(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
3920 1868556           int32_t isweak = (intptr_t)*ref & 1;
3921 1868556           return isweak;
3922             }
3923              
3924 4           int32_t SPVM_API_isweak(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
3925 4           SPVM_RUNTIME* runtime = env->runtime;
3926            
3927 4 50         assert(ref);
3928            
3929 4 50         if (*ref == NULL) {
3930 0           return 0;
3931             }
3932            
3933 4           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
3934            
3935 4           SPVM_MUTEX* mutex_object = SPVM_API_get_object_mutex(env, stack, object);
3936            
3937 4           SPVM_MUTEX_lock(mutex_object);
3938            
3939 4           int32_t isweak = SPVM_API_isweak_only_check_flag(env, stack, ref);
3940            
3941 4           SPVM_MUTEX_unlock(mutex_object);
3942            
3943 4           return isweak;
3944             }
3945              
3946 384           int32_t SPVM_API_weaken(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
3947            
3948 384 50         assert(ref);
3949            
3950 384 100         if (*ref == NULL) {
3951 2           return 0;
3952             }
3953            
3954 382           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
3955            
3956 382           SPVM_MUTEX* mutex_object = SPVM_API_get_object_mutex(env, stack, object);
3957            
3958 382           SPVM_MUTEX_lock(mutex_object);
3959            
3960 382           int32_t isweak = SPVM_API_isweak_only_check_flag(env, stack, ref);
3961            
3962 382           SPVM_OBJECT* destroied_referent = NULL;
3963 382 100         if (!isweak) {
3964            
3965 380           int32_t ref_count = SPVM_API_get_ref_count(env, stack, object);
3966            
3967 380 50         assert(ref_count > 0);
3968            
3969             // If reference count is 1, the object is destroied
3970 380 100         if (ref_count == 1) {
3971 2           destroied_referent = object;
3972 2           *ref = NULL;
3973             }
3974             else {
3975             // Weaken is implemented by tag pointer.
3976             // If pointer most right bit is 1, object is weaken.
3977 378           *ref = (SPVM_OBJECT*)((intptr_t)*ref | 1);
3978            
3979 378           SPVM_API_dec_ref_count(env, stack, object);
3980            
3981 378           SPVM_WEAKEN_BACKREF* new_weaken_backref = SPVM_API_new_memory_block(env, stack, sizeof(SPVM_WEAKEN_BACKREF));
3982 378           new_weaken_backref->ref = ref;
3983            
3984             // Create a new weaken back refference
3985 378 50         if (object->weaken_backref_head == NULL) {
3986 378           object->weaken_backref_head = new_weaken_backref;
3987             }
3988             // Add weaken back refference
3989             else {
3990 0           SPVM_WEAKEN_BACKREF* weaken_backref_next = object->weaken_backref_head;
3991            
3992 0 0         while (weaken_backref_next->next != NULL){
3993 0           weaken_backref_next = weaken_backref_next->next;
3994             }
3995 0           weaken_backref_next->next = new_weaken_backref;
3996             }
3997             }
3998             }
3999            
4000 382           SPVM_MUTEX_unlock(mutex_object);
4001            
4002 382 100         if (destroied_referent) {
4003 2           SPVM_API_assign_object(env, stack, &destroied_referent, NULL);
4004             }
4005            
4006 384           return 0;
4007             }
4008              
4009 5816333           void SPVM_API_unweaken_thread_unsafe(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
4010            
4011 5816333 50         assert(ref);
4012            
4013 5816333 100         if (*ref == NULL) {
4014 3948163           return;
4015             }
4016            
4017 1868170           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
4018            
4019 1868170           int32_t isweak = SPVM_API_isweak_only_check_flag(env, stack, ref);
4020            
4021 1868170 100         if (isweak) {
4022            
4023 363 50         assert(object->weaken_backref_head);
4024            
4025             // Drop weaken flag
4026 363           *ref = (SPVM_OBJECT*)((intptr_t)*ref & ~(intptr_t)1);
4027            
4028 363           SPVM_API_inc_ref_count(env, stack, object);
4029            
4030             // Remove a weaken back reference
4031 363 50         assert(object->weaken_backref_head);
4032 363           SPVM_WEAKEN_BACKREF** weaken_backref_next_ptr = &object->weaken_backref_head;
4033 363 50         while (*weaken_backref_next_ptr != NULL){
4034 363 50         if ((*weaken_backref_next_ptr)->ref == ref) {
4035 363           SPVM_WEAKEN_BACKREF* tmp = (*weaken_backref_next_ptr)->next;
4036            
4037 363           SPVM_WEAKEN_BACKREF* weaken_backref_next = *weaken_backref_next_ptr;
4038            
4039 363           SPVM_API_free_memory_block(env, stack, weaken_backref_next);
4040 363           weaken_backref_next = NULL;
4041            
4042 363           *weaken_backref_next_ptr = tmp;
4043 363           break;
4044             }
4045 0           *weaken_backref_next_ptr = (*weaken_backref_next_ptr)->next;
4046             }
4047             }
4048            
4049             }
4050              
4051 0           void SPVM_API_unweaken(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
4052            
4053 0 0         assert(ref);
4054            
4055 0 0         if (*ref == NULL) {
4056 0           return;
4057             }
4058            
4059 0           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
4060            
4061 0           SPVM_MUTEX* mutex_object = SPVM_API_get_object_mutex(env, stack, object);
4062            
4063 0           SPVM_MUTEX_lock(mutex_object);
4064            
4065 0           SPVM_API_unweaken_thread_unsafe(env, stack, ref);
4066            
4067 0           SPVM_MUTEX_unlock(mutex_object);
4068             }
4069              
4070 15           void SPVM_API_free_weaken_backrefs(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_WEAKEN_BACKREF* weaken_backref_head) {
4071            
4072 15           SPVM_WEAKEN_BACKREF* weaken_backref_head_cur = weaken_backref_head;
4073 15           SPVM_WEAKEN_BACKREF* weaken_backref_head_next = NULL;
4074 30 100         while (weaken_backref_head_cur != NULL){
4075 15           *(weaken_backref_head_cur->ref) = NULL;
4076 15           weaken_backref_head_next = weaken_backref_head_cur->next;
4077            
4078 15           SPVM_API_free_memory_block(env, stack, weaken_backref_head_cur);
4079 15           weaken_backref_head_cur = NULL;
4080 15           weaken_backref_head_cur = weaken_backref_head_next;
4081             }
4082 15           }
4083              
4084 5816333           void SPVM_API_assign_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref, SPVM_OBJECT* object) {
4085            
4086 5816333           SPVM_RUNTIME* runtime = env->runtime;
4087            
4088 5816333           SPVM_MUTEX* runtime_mutex_update_object = runtime->mutex_update_object;
4089            
4090 5816333           SPVM_MUTEX_lock(runtime_mutex_update_object);
4091            
4092 5816333           SPVM_OBJECT* object_assign_off = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
4093 5816333 100         if (object_assign_off) {
4094            
4095 1868170           SPVM_MUTEX* mutex_object_assign_off = SPVM_API_get_object_mutex(env, stack, object_assign_off);
4096            
4097 1868170           SPVM_MUTEX_lock(mutex_object_assign_off);
4098             }
4099            
4100 5816333 50         assert(!((intptr_t)object & 1));
4101            
4102 5816333           int32_t lock_object_mutex = 0;
4103 5816333 100         if (object && (object != object_assign_off)) {
    100          
4104 1868309           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, object);
4105            
4106 1868309           SPVM_MUTEX_lock(object_mutex);
4107 1868309           lock_object_mutex = 1;
4108             }
4109            
4110 5816333           SPVM_MUTEX_unlock(runtime_mutex_update_object);
4111            
4112 5816333           SPVM_API_unweaken_thread_unsafe(env, stack, ref);
4113            
4114 5816333 100         if (object) {
4115 1868857           SPVM_API_inc_ref_count(env, stack, object);
4116             }
4117            
4118 5816333           *ref = object;
4119            
4120 5816333 100         if (object) {
4121 1868857           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, object);
4122 1868857 100         if (lock_object_mutex) {
4123 1868309           SPVM_MUTEX_unlock(object_mutex);
4124             }
4125             }
4126            
4127 5816333 100         if (!object_assign_off) {
4128 3948163           return;
4129             }
4130            
4131 1868170           int32_t object_assign_off_ref_count = SPVM_API_get_ref_count(env, stack, object_assign_off);
4132            
4133 1868170 50         assert(object_assign_off_ref_count > 0);
4134            
4135 1868170           SPVM_MUTEX* mutex_object_assign_off = SPVM_API_get_object_mutex(env, stack, object_assign_off);
4136 1868170 100         if (object_assign_off_ref_count > 1) {
4137            
4138 1350314           SPVM_API_dec_ref_count(env, stack, object_assign_off);
4139 1350314           SPVM_MUTEX_unlock(mutex_object_assign_off);
4140            
4141 1350314           return;
4142             }
4143            
4144 517856           SPVM_MUTEX_unlock(mutex_object_assign_off);
4145            
4146             // Free object_assign_off array
4147 517856 100         if (SPVM_API_is_object_array(env, stack, object_assign_off)) {
4148 52930           int32_t length = SPVM_API_length(env, stack, object_assign_off);
4149 2256671 100         for (int32_t index = 0; index < length; index++) {
4150 2203741           SPVM_OBJECT** ref = &(((SPVM_OBJECT**)((intptr_t)object_assign_off + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[index]);
4151 2203741           SPVM_API_assign_object(env, stack, ref, NULL);
4152             }
4153             }
4154             // Free object_assign_off
4155             else {
4156 464926           SPVM_RUNTIME_BASIC_TYPE* object_assign_off_basic_type = SPVM_API_get_object_basic_type(env, stack, object_assign_off);
4157 464926           int32_t object_assign_off_basic_type_category = object_assign_off_basic_type->category;
4158 464926 100         if (object_assign_off_basic_type_category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS) {
4159             // Class
4160 300297           SPVM_RUNTIME* runtime = env->runtime;
4161            
4162             // Call destructor
4163 300297 100         if (object_assign_off_basic_type->destructor_method) {
4164            
4165 706           SPVM_VALUE save_stack0 = stack[0];
4166 706           SPVM_OBJECT* save_exception = SPVM_API_get_exception(env, stack);
4167 706           SPVM_OBJECT* save_exception_referent = NULL;
4168 706           SPVM_API_assign_object(env, stack, &save_exception_referent, save_exception);
4169            
4170 706           SPVM_RUNTIME_METHOD* destructor_method = SPVM_API_BASIC_TYPE_get_method_by_index(env->runtime, object_assign_off_basic_type, object_assign_off_basic_type->destructor_method->index);
4171            
4172 706           stack[0].oval = object_assign_off;
4173 706           int32_t args_width = 1;
4174 706           int32_t error_id = SPVM_API_call_method_no_mortal(env, stack, destructor_method, args_width);
4175            
4176             // Exception in destructor is changed to warning
4177 706 100         if (error_id) {
4178 2           void* exception = SPVM_API_get_exception(env, stack);
4179 2           const char* exception_chars = SPVM_API_get_chars(env, stack, exception);
4180 2           fprintf(runtime->spvm_stderr, "[The following exception is coverted to a warning because it is thrown in the DESTROY method]\n%s\n", exception_chars);
4181             }
4182            
4183             // Restore stack and exception
4184 706           stack[0] = save_stack0;
4185 706           SPVM_API_set_exception(env, stack, save_exception);
4186 706           SPVM_API_assign_object(env, stack, &save_exception_referent, NULL);
4187             }
4188            
4189             // Free object_assign_off fields
4190 300297           int32_t object_assign_off_fields_length = object_assign_off_basic_type->fields_length;
4191 608482 100         for (int32_t field_index = 0; field_index < object_assign_off_fields_length; field_index++) {
4192 308185           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, object_assign_off_basic_type, field_index);
4193            
4194 308185           void* field_basic_type = field->basic_type;
4195 308185           int32_t field_type_dimension = field->type_dimension;
4196 308185           int32_t field_type_flag = field->type_flag;
4197 308185           int32_t field_type_is_object_assign_off = SPVM_API_TYPE_is_object_type(runtime, field_basic_type, field_type_dimension, field_type_flag);
4198            
4199 308185 100         if (field_type_is_object_assign_off) {
4200 252297           SPVM_OBJECT** ref = (SPVM_OBJECT**)((intptr_t)object_assign_off + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
4201 252297           SPVM_API_assign_object(env, stack, ref, NULL);
4202             }
4203             }
4204             }
4205            
4206             }
4207            
4208 517856           SPVM_MUTEX_lock(mutex_object_assign_off);
4209            
4210 517856           SPVM_API_dec_ref_count(env, stack, object_assign_off);
4211            
4212 517856           object_assign_off_ref_count = SPVM_API_get_ref_count(env, stack, object_assign_off);
4213            
4214 517856 50         if (object_assign_off_ref_count > 0) {
4215 0           SPVM_MUTEX_unlock(mutex_object_assign_off);
4216             }
4217 517856 50         else if (object_assign_off_ref_count == 0) {
4218            
4219             // Free weak back refenreces
4220 517856 100         if (object_assign_off->weaken_backref_head != NULL) {
4221 15           SPVM_API_free_weaken_backrefs(env, stack, object_assign_off->weaken_backref_head);
4222 15           object_assign_off->weaken_backref_head = NULL;
4223             }
4224            
4225 517856           SPVM_MUTEX_unlock(mutex_object_assign_off);
4226 517856           SPVM_MUTEX_destroy(mutex_object_assign_off);
4227            
4228             // Free object_assign_off
4229 517856           SPVM_API_free_memory_block(env, stack, object_assign_off);
4230 517856           object_assign_off = NULL;
4231             }
4232             else {
4233 0           assert(0);
4234             }
4235             }
4236              
4237 2264601           void SPVM_API_inc_ref_count(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4238            
4239 2264601 50         if (object != NULL) {
4240 2264601           int32_t ref_count = SPVM_API_get_ref_count(env, stack, object);
4241 2264601 50         assert(ref_count >= 0);
4242            
4243 2264601           object->ref_count++;
4244             }
4245            
4246 2264601           }
4247              
4248 2263929           void SPVM_API_dec_ref_count(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4249            
4250 2263929           SPVM_RUNTIME* runtime = env->runtime;
4251            
4252 2263929 50         if (object != NULL) {
4253 2263929           int32_t ref_count = SPVM_API_get_ref_count(env, stack, object);
4254 2263929 50         assert(ref_count > 0);
4255            
4256 2263929           object->ref_count--;
4257             }
4258            
4259 2263929           }
4260              
4261 6914962           int32_t SPVM_API_get_ref_count(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4262            
4263 6914962           int32_t ref_count = object->ref_count;
4264            
4265 6914962           return ref_count;
4266             }
4267              
4268 8961948           SPVM_MUTEX* SPVM_API_get_object_mutex(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4269            
4270 8961948           SPVM_MUTEX* object_mutex = (SPVM_MUTEX*)((intptr_t)object + sizeof(SPVM_OBJECT));
4271            
4272 8961948           return object_mutex;
4273             }
4274              
4275 178766           void SPVM_API_lock_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4276            
4277 178766           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, object);
4278            
4279 178766           SPVM_MUTEX_lock(object_mutex);
4280 178766           }
4281              
4282 178766           void SPVM_API_unlock_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4283            
4284 178766           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, object);
4285            
4286 178766           SPVM_MUTEX_unlock(object_mutex);
4287 178766           }
4288