File Coverage

lib/SPVM/Builder/src/spvm_api.c
Criterion Covered Total %
statement 1819 2123 85.6
branch 546 784 69.6
condition n/a
subroutine n/a
pod n/a
total 2365 2907 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 119269           SPVM_ENV* SPVM_API_new_env(void) {
51              
52 119269           SPVM_API_ALLOCATOR* api_allocator = SPVM_API_ALLOCATOR_new_api();
53            
54 119269           SPVM_API_STRING_BUFFER* api_string_buffer = SPVM_API_STRING_BUFFER_new_api();
55            
56 119269           SPVM_API_COMPILER* api_compiler = SPVM_API_COMPILER_new_api();
57            
58 119269           SPVM_API_RUNTIME* api_runtime = SPVM_API_RUNTIME_new_api();
59            
60 119269           SPVM_API_CLASS_FILE* api_class_file = SPVM_API_CLASS_FILE_new_api();
61            
62 119269           SPVM_API_BASIC_TYPE* api_basic_type = SPVM_API_BASIC_TYPE_new_api();
63            
64 119269           SPVM_API_CLASS_VAR* api_class_var = SPVM_API_CLASS_VAR_new_api();
65            
66 119269           SPVM_API_FIELD* api_field = SPVM_API_FIELD_new_api();
67            
68 119269           SPVM_API_TYPE* api_type = SPVM_API_TYPE_new_api();
69            
70 119269           SPVM_API_METHOD* api_method = SPVM_API_METHOD_new_api();
71            
72 119269           SPVM_API_ARG* api_arg = SPVM_API_ARG_new_api();
73            
74 119269           SPVM_API_INTERNAL* api_internal = SPVM_API_INTERNAL_new_api();
75            
76 119269           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 119269           SPVM_ENV_API* env_api = calloc(1, sizeof(env_api_init));
91 119269           memcpy(env_api, env_api_init, sizeof(env_api_init));
92              
93              
94              
95              
96              
97              
98             // Native APIs
99 119269           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 119269           SPVM_ENV* env = calloc(1, sizeof(env_init));
321 119269 50         if (env == NULL) {
322 0           return NULL;
323             }
324 119269           memcpy(env, env_init, sizeof(env_init));
325            
326 119269           return env;
327             }
328              
329 119269           void SPVM_API_free_env(SPVM_ENV* env) {
330              
331             // Free env api
332 119269           SPVM_API_ALLOCATOR_free_api(env->api->allocator);
333 119269           SPVM_API_STRING_BUFFER_free_api(env->api->string_buffer);
334 119269           SPVM_API_COMPILER_free_api(env->api->compiler);
335 119269           SPVM_API_RUNTIME_free_api(env->api->runtime);
336 119269           SPVM_API_CLASS_FILE_free_api(env->api->class_file);
337 119269           SPVM_API_BASIC_TYPE_free_api(env->api->basic_type);
338 119269           SPVM_API_CLASS_VAR_free_api(env->api->class_var);
339 119269           SPVM_API_FIELD_free_api(env->api->field);
340 119269           SPVM_API_TYPE_free_api(env->api->type);
341 119269           SPVM_API_METHOD_free_api(env->api->method);
342 119269           SPVM_API_ARG_free_api(env->api->arg);
343 119269           SPVM_API_INTERNAL_free_api(env->api->internal);
344            
345 119269           free(env->api);
346            
347             // Free env
348 119269           free(env);
349 119269           env = NULL;
350 119269           }
351              
352 480           int32_t SPVM_API_call_init_methods(SPVM_ENV* env, SPVM_VALUE* stack) {
353            
354 480           int32_t error_id = 0;
355            
356             // Runtime
357 480           SPVM_RUNTIME* runtime = env->runtime;
358            
359             // Call INIT blocks
360 480           int32_t basic_types_length = runtime->basic_types_length;
361 25160 100         for (int32_t basic_type_id = 0; basic_type_id < basic_types_length; basic_type_id++) {
362 24680           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(env->runtime, basic_type_id);
363 24680 100         if (basic_type->init_method) {
364 15272           SPVM_RUNTIME_METHOD* init_method = SPVM_API_BASIC_TYPE_get_method_by_index(env->runtime, basic_type, basic_type->init_method->index);
365 15272           int32_t args_width = 0;
366 15272           error_id = SPVM_API_call_method_no_mortal(env, stack, init_method, args_width);
367 15272 50         if (error_id) { break; }
368             }
369             }
370            
371 480           return error_id;
372             }
373              
374 326           int32_t SPVM_API_set_command_info_program_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* obj_program_name) {
375            
376 326           int32_t error_id = 0;
377            
378 326 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 326           SPVM_RUNTIME_BASIC_TYPE* obj_program_name_basic_type = SPVM_API_get_object_basic_type(env, stack, obj_program_name);
383 326 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 326           SPVM_API_set_class_var_object_by_name(env, stack, "CommandInfo", "$PROGRAM_NAME", obj_program_name, &error_id, __func__, __FILE__, __LINE__);
388 326 50         if (error_id) { return error_id; }
389            
390 326           return 0;
391             }
392              
393 326           int32_t SPVM_API_set_command_info_argv(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* obj_argv) {
394            
395 326           int32_t error_id = 0;
396            
397 326 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 326           SPVM_RUNTIME_BASIC_TYPE* obj_argv_basic_type = SPVM_API_get_object_basic_type(env, stack, obj_argv);
402 326 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 326           SPVM_API_set_class_var_object_by_name(env, stack, "CommandInfo", "$ARGV", obj_argv, &error_id, __func__, __FILE__, __LINE__);
407 326 50         if (error_id) { return error_id; }
408            
409 326           return 0;
410             }
411              
412 326           int32_t SPVM_API_set_command_info_base_time(SPVM_ENV* env, SPVM_VALUE* stack, int64_t base_time) {
413            
414 326           int32_t error_id = 0;
415            
416 326           SPVM_API_set_class_var_long_by_name(env, stack, "CommandInfo", "$BASE_TIME", base_time, &error_id, __func__, __FILE__, __LINE__);
417 326 50         if (error_id) { return error_id; }
418            
419 326           return 0;
420             }
421              
422 326           void SPVM_API_destroy_class_vars(SPVM_ENV* env, SPVM_VALUE* stack){
423              
424             // Runtime
425 326           SPVM_RUNTIME* runtime = env->runtime;
426            
427             // Free objects of class variables
428 15469 100         for (int32_t basic_type_id = 0; basic_type_id < runtime->basic_types_length; basic_type_id++) {
429 15143           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(env->runtime, basic_type_id);
430            
431 17443 100         for (int32_t class_var_index = 0; class_var_index < basic_type->class_vars_length; class_var_index++) {
432            
433 2300           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_index(runtime, basic_type, class_var_index);
434            
435 2300           SPVM_RUNTIME_BASIC_TYPE* class_var_basic_type = class_var->basic_type;
436 2300           int32_t class_var_type_dimension = class_var->type_dimension;
437 2300           int32_t class_var_type_flag = class_var->type_flag;
438            
439 2300           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 2300 100         if (class_var_type_is_object) {
441 1412           SPVM_OBJECT** object_ref = (SPVM_OBJECT**)&class_var->data;
442 1412           SPVM_API_assign_object(env, stack, object_ref, NULL);
443             }
444             }
445             }
446 326           }
447              
448 670679           int32_t SPVM_API_args_width(SPVM_ENV* env, SPVM_VALUE* stack) {
449 670679           int32_t args_length = stack[SPVM_API_C_STACK_INDEX_ARGS_WIDTH].ival;
450            
451 670679           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 287267           SPVM_RUNTIME_BASIC_TYPE* SPVM_API_get_basic_type(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name) {
474            
475              
476 287267           SPVM_RUNTIME* runtime = env->runtime;
477              
478 287267 50         if (basic_type_name == NULL) {
479 0           return NULL;
480             }
481              
482 287267           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_RUNTIME_get_basic_type_by_name(runtime, basic_type_name);
483            
484 287267           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 338           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 338           *error_id = 0;
524            
525 338           SPVM_OBJECT* object = stack[0].oval;
526            
527 338 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 338 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 338           SPVM_RUNTIME_METHOD* method = SPVM_API_get_instance_method(env, stack, object, method_name);
538 338 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 336           *error_id = SPVM_API_call_method_no_mortal(env, stack, method, args_width);
545            
546 336 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 237631           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 237631           *error_id = 0;
569            
570 237631           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
571 237631 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 237629           SPVM_OBJECT* object = SPVM_API_new_pointer_object(env, stack, basic_type, pointer);
577            
578 237629           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 734           SPVM_OBJECT* SPVM_API_get_class_var_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
717            
718 734           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
719            
720 734 50         assert(basic_type);
721            
722 734           int32_t class_vars_length = basic_type->class_vars_length;
723            
724 734 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
725            
726 734           SPVM_OBJECT* value_maybe_weaken = (SPVM_OBJECT*)class_var->data.oval;
727 734           SPVM_OBJECT* value = SPVM_API_get_object_no_weaken_address(env, stack, value_maybe_weaken);
728            
729 734           return value;
730             }
731              
732 658           SPVM_OBJECT** SPVM_API_get_class_var_object_ref(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var) {
733            
734 658           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
735            
736 658 50         assert(basic_type);
737            
738 658           int32_t class_vars_length = basic_type->class_vars_length;
739            
740 658 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
741            
742 658           SPVM_OBJECT** object_ref = (SPVM_OBJECT**)&class_var->data.oval;
743            
744 658           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 358           void SPVM_API_set_class_var_long(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, int64_t value) {
792            
793 358           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
794            
795 358 50         assert(basic_type);
796            
797 358           int32_t class_vars_length = basic_type->class_vars_length;
798            
799 358 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
800            
801 358           class_var->data.lval = value;
802 358           }
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 654           void SPVM_API_set_class_var_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_CLASS_VAR* class_var, SPVM_OBJECT* value) {
831            
832 654           SPVM_RUNTIME_BASIC_TYPE* basic_type = class_var->current_basic_type;
833            
834 654 50         assert(basic_type);
835            
836 654           int32_t class_vars_length = basic_type->class_vars_length;
837            
838 654 50         assert(class_var->index >= 0 && class_var->index < class_vars_length);
    50          
839            
840 654           void* object_ref = &class_var->data.oval;
841 654           SPVM_API_assign_object(env, stack, object_ref, value);
842 654           }
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 330           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 330           *error_id = 0;
1064            
1065 330           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1066 330 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 330           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1073 330 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 328           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 656           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 656           *error_id = 0;
1124            
1125 656           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
1126 656 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 656           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
1133 656 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 654           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 680           int8_t SPVM_API_get_field_byte(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1147              
1148 680           int8_t value = *(int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1149              
1150 680           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 526562           SPVM_OBJECT* SPVM_API_get_field_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1189              
1190 526562           SPVM_OBJECT* value_maybe_weaken = *(SPVM_OBJECT**)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1191 526562           SPVM_OBJECT* value = SPVM_API_get_object_no_weaken_address(env, stack, value_maybe_weaken);
1192            
1193 526562           return value;
1194             }
1195              
1196 336           SPVM_OBJECT** SPVM_API_get_field_object_ref(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_FIELD* field) {
1197              
1198 336           SPVM_OBJECT** object_ref = (SPVM_OBJECT**)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1199            
1200 336           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 237881           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 237881           void* object_ref = (void**)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
1250              
1251 237881           SPVM_API_assign_object(env, stack, object_ref, value);
1252 237881           }
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 682           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 682           *error_id = 0;
1261            
1262 682 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 682 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 682           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1273 682 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 680           int8_t value = SPVM_API_get_field_byte(env, stack, object, field);
1280 680           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 526562           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 526562           *error_id = 0;
1405            
1406 526562 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 526562 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 526562           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1417 526562 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 526560           SPVM_OBJECT* value = SPVM_API_get_field_object(env, stack, object, field);
1424 526560           return value;
1425             }
1426              
1427 336           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 336           *error_id = 0;
1429            
1430 336 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 336 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 336           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1441 336 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 336           SPVM_OBJECT** object_ref = SPVM_API_get_field_object_ref(env, stack, object, field);
1448 336           return object_ref;
1449             }
1450              
1451 260930           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 260930           *error_id = 0;
1454            
1455 260930           void* obj_runtime = env->get_field_object_by_name(env, stack, object, field_name, error_id, func_name, file_name, line);
1456            
1457 260930 50         if (*error_id) { return NULL; }
1458            
1459 260930 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 260930           void* runtime = env->get_pointer(env, stack, obj_runtime);
1465            
1466 260930 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 260930           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 237883           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 237883           *error_id = 0;
1637            
1638 237883 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 237883 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 237883           SPVM_RUNTIME_FIELD* field = SPVM_API_get_field(env, stack, object, field_name);
1649 237883 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 237881           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 662           SPVM_VALUE* SPVM_API_new_stack(SPVM_ENV* env) {
1694            
1695 662           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 662           SPVM_VALUE* stack = SPVM_ALLOCATOR_alloc_memory_block_tmp(runtime->allocator, sizeof(SPVM_VALUE) * 512);
1705            
1706 662           int32_t native_mortal_stack_capacity = 1;
1707 662           void* native_mortal_stack = SPVM_API_new_memory_block(env, stack, sizeof(SPVM_OBJECT*) * native_mortal_stack_capacity);
1708 662 50         if (native_mortal_stack == NULL) {
1709 0           return NULL;
1710             }
1711 662           stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_CAPACITY].ival = native_mortal_stack_capacity;
1712 662           stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK].oval = native_mortal_stack;
1713 662           stack[SPVM_API_C_STACK_INDEX_ENV].oval = env;
1714            
1715 662           return stack;
1716             }
1717              
1718 662           void SPVM_API_free_stack(SPVM_ENV* env, SPVM_VALUE* stack) {
1719            
1720 662           SPVM_RUNTIME* runtime = env->runtime;
1721            
1722 662           SPVM_API_set_exception(env, stack, NULL);
1723            
1724 662           SPVM_OBJECT** mortal_stack = stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK].oval;
1725            
1726 662 50         if (mortal_stack != NULL) {
1727 662           SPVM_API_free_memory_block(env, stack, mortal_stack);
1728 662           mortal_stack = NULL;
1729             }
1730            
1731 662           SPVM_ALLOCATOR_free_memory_block_tmp(runtime->allocator, stack);
1732 662           stack = NULL;
1733 662           }
1734              
1735 2855968           int32_t SPVM_API_call_method_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_METHOD* method, int32_t args_width) {
1736            
1737 2855968           int32_t mortal = 0;
1738 2855968           int32_t error_id = SPVM_API_call_method_common(env, stack, method, args_width, mortal);
1739            
1740 2855968           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 600572           int32_t SPVM_API_is_object_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1818            
1819 600572           SPVM_RUNTIME* runtime = env->runtime;
1820              
1821             int32_t is_object_array;
1822 600572 100         if (object) {
1823 600570           int32_t object_type_dimension = object->type_dimension;
1824 600570 100         if (object_type_dimension == 0) {
1825 467613           is_object_array = 0;
1826             }
1827 132957 100         else if (object_type_dimension == 1) {
1828 132863           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
1829 132863           int32_t element_type_dimension = 0;
1830 132863           int32_t type_flag = 0;
1831 132863           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 600570           assert(0);
1838             }
1839             }
1840             else {
1841 2           is_object_array = 0;
1842             }
1843            
1844 600572           return is_object_array;
1845             }
1846              
1847 21263           int32_t SPVM_API_is_mulnum_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
1848              
1849 21263           SPVM_RUNTIME* runtime = env->runtime;
1850              
1851             int32_t is_mulnum_array;
1852 21263 100         if (object) {
1853 21261           int32_t object_type_dimension = object->type_dimension;
1854 21261 100         if (object_type_dimension == 0) {
1855 6           is_mulnum_array = 0;
1856             }
1857 21255 100         else if (object_type_dimension == 1) {
1858 21231           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
1859 21231           int32_t object_basic_type_category = object_basic_type->category;
1860 21231 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 21231           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 21261           assert(0);
1876             }
1877             }
1878             else {
1879 2           is_mulnum_array = 0;
1880             }
1881              
1882 21263           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 1372531           int32_t SPVM_API_enter_scope(SPVM_ENV* env, SPVM_VALUE* stack){
2026            
2027              
2028 1372531           SPVM_OBJECT*** current_mortal_stack_ptr = (SPVM_OBJECT***)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK];
2029 1372531           int32_t* current_mortal_stack_top_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_TOP];
2030 1372531           int32_t* current_mortal_stack_capacity_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_CAPACITY];
2031            
2032 1372531           int32_t mortal_stack_top = *current_mortal_stack_top_ptr ;
2033            
2034 1372531           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            
2258 0           SPVM_API_fprint(env, stack, stdout, string);
2259 0           }
2260              
2261 0           void SPVM_API_print_stderr(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
2262            
2263            
2264 0           SPVM_API_fprint(env, stack, stderr, string);
2265 0           }
2266              
2267 1102           SPVM_OBJECT* SPVM_API_concat_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string1, SPVM_OBJECT* string2) {
2268            
2269 1102           int32_t string1_length = SPVM_API_length(env, stack, string1);
2270 1102           int32_t string2_length = SPVM_API_length(env, stack, string2);
2271            
2272 1102           int32_t string3_length = string1_length + string2_length;
2273 1102           SPVM_OBJECT* string3 = SPVM_API_new_string_no_mortal(env, stack, NULL, string3_length);
2274            
2275 1102           const char* string1_bytes = SPVM_API_get_chars(env, stack, string1);
2276 1102           const char* string2_bytes = SPVM_API_get_chars(env, stack, string2);
2277 1102           char* string3_bytes = (char*)SPVM_API_get_chars(env, stack, string3);
2278            
2279 1102 100         if (string1_length > 0) {
2280 982           memcpy(string3_bytes, string1_bytes, string1_length);
2281             }
2282 1102 100         if (string2_length) {
2283 910           memcpy(string3_bytes + string1_length, string2_bytes, string2_length);
2284             }
2285            
2286 1102           return string3;
2287             }
2288              
2289 0           SPVM_OBJECT* SPVM_API_concat(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string1, SPVM_OBJECT* string2) {
2290            
2291            
2292 0           SPVM_OBJECT* str = SPVM_API_concat_no_mortal(env, stack, string1, string2);
2293            
2294 0           SPVM_API_push_mortal(env, stack, str);
2295            
2296 0           return str;
2297             }
2298              
2299 2           SPVM_OBJECT* SPVM_API_dump(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
2300            
2301            
2302 2           SPVM_OBJECT* str = SPVM_API_dump_no_mortal(env, stack, object);
2303            
2304 2           SPVM_API_push_mortal(env, stack, str);
2305            
2306 2           return str;
2307             }
2308              
2309 68           SPVM_OBJECT* SPVM_API_dump_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
2310            
2311 68           SPVM_RUNTIME* runtime = env->runtime;
2312            
2313 68           int32_t depth = 0;
2314 68           SPVM_STRING_BUFFER* string_buffer = SPVM_STRING_BUFFER_new(runtime->allocator, 255, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
2315 68           SPVM_HASH* address_symtable = SPVM_HASH_new(runtime->allocator, 255, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
2316            
2317 68           SPVM_API_dump_recursive(env, stack, object, &depth, string_buffer, address_symtable);
2318            
2319 68           int32_t string_buffer_length = string_buffer->length;
2320            
2321 68           SPVM_OBJECT* dump = SPVM_API_new_string_no_mortal(env, stack, string_buffer->string, string_buffer->length);
2322            
2323 68           SPVM_HASH_free(address_symtable);
2324 68           address_symtable = NULL;
2325            
2326 68           SPVM_STRING_BUFFER_free(string_buffer);
2327 68           string_buffer = NULL;
2328            
2329 68           return dump;
2330             }
2331              
2332 2           const char* SPVM_API_dumpc(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
2333            
2334            
2335 2           SPVM_OBJECT* obj_dump = SPVM_API_dump(env, stack, object);
2336            
2337 2           const char* dump_chars = SPVM_API_get_chars(env, stack, obj_dump);
2338            
2339 2           return dump_chars;
2340             }
2341              
2342 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) {
2343            
2344 168           SPVM_RUNTIME* runtime = env->runtime;
2345            
2346             char tmp_buffer[256];
2347            
2348             SPVM_OBJECT* dump;
2349 168 100         if (object == NULL) {
2350 36           SPVM_STRING_BUFFER_add(string_buffer, "undef");
2351             }
2352             else {
2353 132           int32_t type_dimension = object->type_dimension;
2354            
2355 132 100         if (SPVM_API_is_string(env, stack, object)) {
2356 28           const char* chars = SPVM_API_get_chars(env, stack, object);
2357 28           int32_t chars_length = SPVM_API_length(env, stack, object);
2358 28           SPVM_STRING_BUFFER_add(string_buffer, "\"");
2359 28           SPVM_STRING_BUFFER_add_len(string_buffer, (char*)chars, chars_length);
2360 28           SPVM_STRING_BUFFER_add(string_buffer, "\"");
2361             }
2362 104 100         else if (type_dimension > 0) {
2363 66           int32_t array_length = SPVM_API_length(env, stack, object);
2364 66           int32_t element_type_dimension = type_dimension - 1;
2365            
2366 66           SPVM_STRING_BUFFER_add(string_buffer, "[\n");
2367            
2368 66           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
2369 66           const char* object_basic_type_name = object_basic_type->name;
2370            
2371 216 100         for (int32_t array_index = 0; array_index < array_length; array_index++) {
2372            
2373 326 100         for (int32_t depth_index = 0; depth_index < *depth + 1; depth_index++) {
2374 176           SPVM_STRING_BUFFER_add(string_buffer, " ");
2375             }
2376            
2377 150 100         if (SPVM_API_is_mulnum_array(env, stack, object)) {
2378            
2379 32           SPVM_STRING_BUFFER_add(string_buffer, "{\n");
2380            
2381 32           int32_t fields_length = object_basic_type->fields_length;
2382            
2383 128 100         for (int32_t field_index = 0; field_index < fields_length; field_index++) {
2384 288 100         for (int32_t depth_index = 0; depth_index < *depth + 2; depth_index++) {
2385 192           SPVM_STRING_BUFFER_add(string_buffer, " ");
2386             }
2387            
2388 96           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, object_basic_type, field_index);
2389            
2390 96           int32_t field_basic_type_id = field->basic_type->id;
2391            
2392 96           const char* field_name = field->name;
2393 96           SPVM_STRING_BUFFER_add(string_buffer, field_name);
2394 96           SPVM_STRING_BUFFER_add(string_buffer, " => ");
2395            
2396 96           switch (field_basic_type_id) {
2397             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
2398 24           int8_t* element = &((int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2399 24           sprintf(tmp_buffer, "%d", element[field_index]);
2400 24           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2401 24           break;
2402             }
2403             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
2404 24           int16_t* element = &((int16_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2405 24           sprintf(tmp_buffer, "%d", element[field_index]);
2406 24           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2407 24           break;
2408             }
2409             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
2410 24           int32_t* element = &((int32_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2411 24           sprintf(tmp_buffer, "%d", element[field_index]);
2412 24           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2413 24           break;
2414             }
2415             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
2416 24           int64_t* element = &((int64_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2417 24           sprintf(tmp_buffer, "%lld", (long long int)element[field_index]);
2418 24           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2419 24           break;
2420             }
2421             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
2422 0           float* element = &((float*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2423 0           sprintf(tmp_buffer, "%g", element[field_index]);
2424 0           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2425 0           break;
2426             }
2427             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
2428 0           double* element = &((double*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index * fields_length];
2429 0           sprintf(tmp_buffer, "%g", element[field_index]);
2430 0           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2431 0           break;
2432             }
2433             }
2434            
2435 96 100         if (field_index == fields_length - 1) {
2436 32           SPVM_STRING_BUFFER_add(string_buffer, "\n");
2437             }
2438             else {
2439 64           SPVM_STRING_BUFFER_add(string_buffer, ",\n");
2440             }
2441             }
2442            
2443 32           SPVM_STRING_BUFFER_add(string_buffer, " }");
2444             }
2445 118 100         else if (SPVM_API_is_numeric_array(env, stack, object)) {
2446 54           switch (object_basic_type->id) {
2447             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
2448 8           int8_t element = ((int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2449 8           sprintf(tmp_buffer, "%d", element);
2450 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2451 8           break;
2452             }
2453             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
2454 8           int16_t element = ((int16_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2455 8           sprintf(tmp_buffer, "%d", element);
2456 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2457 8           break;
2458             }
2459             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
2460 14           int32_t element = ((int32_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2461 14           sprintf(tmp_buffer, "%d", element);
2462 14           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2463 14           break;
2464             }
2465             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
2466 8           int64_t element = ((int64_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2467 8           sprintf(tmp_buffer, "%lld", (long long int)element);
2468 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2469 8           break;
2470             }
2471             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
2472 8           float element = ((float*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2473 8           sprintf(tmp_buffer, "%g", element);
2474 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2475 8           break;
2476             }
2477             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
2478 8           double element = ((double*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index];
2479 8           sprintf(tmp_buffer, "%g", element);
2480 8           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2481 54           break;
2482             }
2483             }
2484             }
2485 64 50         else if (SPVM_API_is_object_array(env, stack, object)) {
2486 64           SPVM_OBJECT* element = (((SPVM_OBJECT**)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[array_index]);
2487 64           element = SPVM_API_get_object_no_weaken_address(env, stack, element);
2488 64           (*depth)++;
2489 64           SPVM_API_dump_recursive(env, stack, element, depth, string_buffer, address_symtable);
2490 64           (*depth)--;
2491             }
2492             else {
2493 0           assert(0);
2494             }
2495            
2496 150 100         if (array_index == array_length - 1) {
2497 66           SPVM_STRING_BUFFER_add(string_buffer, "\n");
2498             }
2499             else {
2500 84           SPVM_STRING_BUFFER_add(string_buffer, ",\n");
2501             }
2502             }
2503            
2504 76 100         for (int32_t depth_index = 0; depth_index < *depth; depth_index++) {
2505 10           SPVM_STRING_BUFFER_add(string_buffer, " ");
2506             }
2507 66           SPVM_STRING_BUFFER_add(string_buffer, "]");
2508            
2509 66           SPVM_STRING_BUFFER_add(string_buffer, " : ");
2510 66           SPVM_STRING_BUFFER_add(string_buffer, object_basic_type_name);
2511 136 100         for (int32_t type_dimension_index = 0; type_dimension_index < type_dimension; type_dimension_index++) {
2512 70           SPVM_STRING_BUFFER_add(string_buffer, "[]");
2513             }
2514            
2515             // If the object is weaken, this get the real address
2516 66           sprintf(tmp_buffer, "(%p)", SPVM_API_get_object_no_weaken_address(env, stack, object));
2517 66           SPVM_STRING_BUFFER_add(string_buffer, tmp_buffer);
2518             }
2519             else {
2520             // If the object is weaken, this get the real address
2521 38           sprintf(tmp_buffer, "%p", SPVM_API_get_object_no_weaken_address(env, stack, object));
2522 38           int32_t exists = (int32_t)(intptr_t)SPVM_HASH_get(address_symtable, tmp_buffer, strlen(tmp_buffer));
2523 38 100         if (exists) {
2524             // If the object is weaken, this get the real address
2525 24           sprintf(tmp_buffer, "REUSE_OBJECT(%p)", SPVM_API_get_object_no_weaken_address(env, stack, object));
2526 24           SPVM_STRING_BUFFER_add(string_buffer, tmp_buffer);
2527             }
2528             else {
2529 14           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
2530 14           const char* basic_type_name = object_basic_type->name;
2531            
2532 14           SPVM_HASH_set(address_symtable, tmp_buffer, strlen(tmp_buffer), (void*)(intptr_t)1);
2533            
2534 14           SPVM_STRING_BUFFER_add(string_buffer, basic_type_name);
2535 14           sprintf(tmp_buffer, " (%p) ", object);
2536 14           SPVM_STRING_BUFFER_add(string_buffer, tmp_buffer);
2537            
2538 14           SPVM_STRING_BUFFER_add(string_buffer, "{\n");
2539            
2540             // Free object fields
2541 14           int32_t fields_length = object_basic_type->fields_length;
2542 126 100         for (int32_t field_index = 0; field_index < fields_length; field_index++) {
2543 314 100         for (int32_t depth_index = 0; depth_index < *depth + 1; depth_index++) {
2544 202           SPVM_STRING_BUFFER_add(string_buffer, " ");
2545             }
2546            
2547 112           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, object_basic_type, field_index);
2548            
2549 112           int32_t field_basic_type_id = field->basic_type->id;
2550 112           int32_t field_type_dimension = field->type_dimension;
2551 112           int32_t field_offset = field->offset;
2552 112           const char* field_name = field->name;
2553            
2554 112           SPVM_STRING_BUFFER_add(string_buffer, field_name);
2555 112           SPVM_STRING_BUFFER_add(string_buffer, " => ");
2556 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          
2557 76           switch (field_basic_type_id) {
2558             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
2559 12           int8_t field_value = *(int8_t*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2560 12           sprintf(tmp_buffer, "%d", field_value);
2561 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2562 12           break;
2563             }
2564             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
2565 12           int16_t field_value = *(int16_t*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2566 12           sprintf(tmp_buffer, "%d", field_value);
2567 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2568 12           break;
2569             }
2570             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
2571 16           int32_t field_value = *(int32_t*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2572 16           sprintf(tmp_buffer, "%d", field_value);
2573 16           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2574 16           break;
2575             }
2576             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
2577 12           int64_t field_value = *(int64_t*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2578 12           sprintf(tmp_buffer, "%lld", (long long int)field_value);
2579 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2580 12           break;
2581             }
2582             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
2583 12           float field_value = *(float*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2584 12           sprintf(tmp_buffer, "%g", field_value);
2585 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2586 12           break;
2587             }
2588             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
2589 12           double field_value = *(double*)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2590 12           sprintf(tmp_buffer, "%g", field_value);
2591 12           SPVM_STRING_BUFFER_add(string_buffer, (const char*)tmp_buffer);
2592 12           break;
2593             }
2594             default : {
2595 0           assert(0);
2596             }
2597             }
2598 76           }
2599             else {
2600 36           SPVM_OBJECT* field_value = *(SPVM_OBJECT**)((intptr_t)object + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field_offset);
2601 36           field_value = SPVM_API_get_object_no_weaken_address(env, stack, field_value);
2602 36           (*depth)++;
2603 36           SPVM_API_dump_recursive(env, stack, field_value, depth, string_buffer, address_symtable);
2604 36           (*depth)--;
2605             }
2606            
2607 112 100         if (field_index == fields_length - 1) {
2608 14           SPVM_STRING_BUFFER_add(string_buffer, "\n");
2609             }
2610             else {
2611 98           SPVM_STRING_BUFFER_add(string_buffer, ",\n");
2612             }
2613             }
2614            
2615 24 100         for (int32_t depth_index = 0; depth_index < *depth; depth_index++) {
2616 10           SPVM_STRING_BUFFER_add(string_buffer, " ");
2617             }
2618 14           SPVM_STRING_BUFFER_add(string_buffer, "}");
2619             }
2620             }
2621             }
2622 168           }
2623              
2624 14000           void SPVM_API_make_read_only(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
2625 14000           SPVM_RUNTIME_BASIC_TYPE* string_basic_type = SPVM_API_get_object_basic_type(env, stack, string);
2626 14000 50         if (string && string_basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_STRING && string->type_dimension == 0) {
    50          
    50          
2627 14000           string->flag |= SPVM_OBJECT_C_FLAG_IS_READ_ONLY;
2628             }
2629 14000           }
2630              
2631 6404           int32_t SPVM_API_is_read_only(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
2632            
2633             int32_t is_read_only;
2634 6404 100         if (string) {
2635 6396 100         if (string->flag & SPVM_OBJECT_C_FLAG_IS_READ_ONLY) {
2636 268           is_read_only = 1;
2637             }
2638             else {
2639 6396           is_read_only = 0;
2640             }
2641             }
2642             else {
2643 8           is_read_only = 0;
2644             }
2645            
2646 6404           return is_read_only;
2647             }
2648              
2649 6370           int32_t SPVM_API_set_exception(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* exception) {
2650            
2651 6370           SPVM_OBJECT** current_exception_ptr = (SPVM_OBJECT**)&stack[SPVM_API_C_STACK_INDEX_EXCEPTION];
2652            
2653 6370           SPVM_API_assign_object(env, stack, current_exception_ptr, exception);
2654            
2655 6370           return 0;
2656             }
2657              
2658 4332           SPVM_OBJECT* SPVM_API_get_exception(SPVM_ENV* env, SPVM_VALUE* stack){
2659              
2660 4332           SPVM_OBJECT** current_exception_ptr = (SPVM_OBJECT**)&stack[SPVM_API_C_STACK_INDEX_EXCEPTION];
2661 4332           SPVM_OBJECT* current_exception = *current_exception_ptr;
2662            
2663 4332           return current_exception;
2664             }
2665              
2666 4           SPVM_OBJECT* SPVM_API_new_byte_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2667            
2668 4           SPVM_OBJECT* object = SPVM_API_new_byte_array_no_mortal(env, stack, length);
2669            
2670 4           SPVM_API_push_mortal(env, stack, object);
2671            
2672 4           return object;
2673             }
2674              
2675 4           SPVM_OBJECT* SPVM_API_new_short_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2676            
2677 4           SPVM_OBJECT* object = SPVM_API_new_short_array_no_mortal(env, stack, length);
2678            
2679 4           SPVM_API_push_mortal(env, stack, object);
2680            
2681 4           return object;
2682             }
2683              
2684 14           SPVM_OBJECT* SPVM_API_new_int_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2685            
2686 14           SPVM_OBJECT* object = SPVM_API_new_int_array_no_mortal(env, stack, length);
2687            
2688 14           SPVM_API_push_mortal(env, stack, object);
2689            
2690 14           return object;
2691             }
2692              
2693 6           SPVM_OBJECT* SPVM_API_new_long_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2694            
2695 6           SPVM_OBJECT* object = SPVM_API_new_long_array_no_mortal(env, stack, length);
2696            
2697 6           SPVM_API_push_mortal(env, stack, object);
2698            
2699 6           return object;
2700             }
2701              
2702 4           SPVM_OBJECT* SPVM_API_new_float_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2703            
2704 4           SPVM_OBJECT* object = SPVM_API_new_float_array_no_mortal(env, stack, length);
2705            
2706 4           SPVM_API_push_mortal(env, stack, object);
2707            
2708 4           return object;
2709             }
2710              
2711 2           SPVM_OBJECT* SPVM_API_new_double_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2712            
2713 2           SPVM_OBJECT* object = SPVM_API_new_double_array_no_mortal(env, stack, length);
2714            
2715 2           SPVM_API_push_mortal(env, stack, object);
2716            
2717 2           return object;
2718             }
2719              
2720 7           SPVM_OBJECT* SPVM_API_new_string_array(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2721            
2722 7           SPVM_OBJECT* string_array = SPVM_API_new_string_array_no_mortal(env, stack, length);
2723            
2724 7           SPVM_API_push_mortal(env, stack, string_array);
2725            
2726 7           return string_array;
2727             }
2728              
2729 357           SPVM_OBJECT* SPVM_API_new_string_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2730            
2731 357           SPVM_RUNTIME_BASIC_TYPE* string_basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(env->runtime, SPVM_NATIVE_C_BASIC_TYPE_ID_STRING);
2732            
2733 357           SPVM_OBJECT* object = SPVM_API_new_object_array_no_mortal(env, stack, string_basic_type, length);
2734            
2735 357           return object;
2736             }
2737              
2738 12           SPVM_OBJECT* SPVM_API_new_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type) {
2739            
2740 12           SPVM_OBJECT* object = SPVM_API_new_object_no_mortal(env, stack, basic_type);
2741            
2742 12           SPVM_API_push_mortal(env, stack, object);
2743            
2744 12           return object;
2745             }
2746              
2747 306199           SPVM_OBJECT* SPVM_API_new_object_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type) {
2748            
2749 306199           SPVM_RUNTIME* runtime = env->runtime;
2750            
2751 306199 50         if (!basic_type) {
2752 0           return NULL;
2753             }
2754            
2755 306199 50         if (basic_type->category != SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS) {
2756 0           return NULL;
2757             }
2758            
2759             // Alloc body length + 1
2760 306199           int32_t fields_length = basic_type->fields_length;
2761            
2762 306199           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + basic_type->fields_size + 1;
2763            
2764 306199 50         if (!basic_type) {
2765 0           return NULL;
2766             }
2767 306199           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 0, fields_length, 0);
2768            
2769 306199           return object;
2770             }
2771              
2772 269294           SPVM_OBJECT* SPVM_API_new_pointer_object_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, void* pointer) {
2773            
2774 269294           void* obj_object = SPVM_API_new_object_no_mortal(env, stack, basic_type);
2775            
2776 269294           SPVM_API_set_pointer(env, stack, obj_object, pointer);
2777            
2778 269294           return obj_object;
2779             }
2780              
2781 237631           SPVM_OBJECT* SPVM_API_new_pointer_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, void* pointer) {
2782            
2783            
2784 237631           SPVM_OBJECT* object = SPVM_API_new_pointer_object_no_mortal(env, stack, basic_type, pointer);
2785            
2786 237631           SPVM_API_push_mortal(env, stack, object);
2787            
2788 237631           return object;
2789             }
2790              
2791 70228           SPVM_OBJECT* SPVM_API_new_string_nolen_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, const char* bytes) {
2792            
2793            
2794 70228           int32_t length = strlen((char*)bytes);
2795            
2796 70228           SPVM_OBJECT* object = SPVM_API_new_string_no_mortal(env, stack, NULL, length);
2797            
2798 70228 50         if (bytes != NULL && length > 0) {
    100          
2799 70085           memcpy((void*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)), (char*)bytes, length);
2800             }
2801            
2802 70228           return object;
2803             }
2804              
2805 70092           SPVM_OBJECT* SPVM_API_new_string_nolen(SPVM_ENV* env, SPVM_VALUE* stack, const char* bytes) {
2806            
2807            
2808 70092           SPVM_OBJECT* object = SPVM_API_new_string_nolen_no_mortal(env, stack, bytes);
2809            
2810 70092           SPVM_API_push_mortal(env, stack, object);
2811            
2812 70092           return object;
2813             }
2814              
2815 162062           SPVM_OBJECT* SPVM_API_new_string_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, const char* bytes, int32_t length) {
2816            
2817            
2818 162062 50         if (length < 0) {
2819 0           return NULL;
2820             }
2821            
2822 162062           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(char) * (length + 1);
2823            
2824 162062           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_STRING);
2825            
2826 162062           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 0, length, 0);
2827            
2828 162062 50         if (object) {
2829 162062 100         if (bytes != NULL && length > 0) {
    100          
2830 84453           memcpy((void*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)), (char*)bytes, length);
2831             }
2832             }
2833            
2834 162062           return object;
2835             }
2836              
2837 32           int32_t SPVM_API_get_bool_object_value(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* bool_object) {
2838            
2839 32           int32_t value = *(int32_t*)((intptr_t)bool_object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
2840            
2841 32           return value;
2842             }
2843              
2844 1326           SPVM_OBJECT* SPVM_API_new_string(SPVM_ENV* env, SPVM_VALUE* stack, const char* bytes, int32_t length) {
2845            
2846            
2847 1326           SPVM_OBJECT* object = SPVM_API_new_string_no_mortal(env, stack, bytes, length);
2848            
2849 1326           SPVM_API_push_mortal(env, stack, object);
2850            
2851 1326           return object;
2852             }
2853              
2854 836           SPVM_OBJECT* SPVM_API_new_byte_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2855            
2856 836 50         if (length < 0) {
2857 0           return NULL;
2858             }
2859            
2860 836           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(int8_t) * (length + 1);
2861            
2862 836           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE);
2863            
2864 836           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2865            
2866 836           return object;
2867             }
2868              
2869 714           SPVM_OBJECT* SPVM_API_new_short_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2870            
2871 714           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(int16_t) * (length + 1);
2872            
2873 714           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT);
2874            
2875 714           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2876            
2877 714           return object;
2878             }
2879              
2880 910           SPVM_OBJECT* SPVM_API_new_int_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2881            
2882 910           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(int32_t) * (length + 1);
2883            
2884 910           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_INT);
2885            
2886 910           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2887            
2888 910           return object;
2889             }
2890              
2891 706           SPVM_OBJECT* SPVM_API_new_long_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2892            
2893 706 50         if (length < 0) {
2894 0           return NULL;
2895             }
2896            
2897 706           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(int64_t) * (length + 1);
2898            
2899 706           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_LONG);
2900            
2901 706           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2902            
2903 706           return object;
2904             }
2905              
2906 706           SPVM_OBJECT* SPVM_API_new_float_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2907            
2908 706           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(float) * (length + 1);
2909            
2910 706           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT);
2911            
2912 706           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2913            
2914 706           return object;
2915             }
2916              
2917 714           SPVM_OBJECT* SPVM_API_new_double_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, int32_t length) {
2918            
2919 714           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(double) * (length + 1);
2920            
2921 714           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type_by_id(env, stack, SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE);
2922            
2923 714           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2924            
2925 714           return object;
2926             }
2927              
2928 53170           SPVM_OBJECT* SPVM_API_new_object_array_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t length) {
2929            
2930 53170           SPVM_RUNTIME* runtime = env->runtime;
2931            
2932             SPVM_OBJECT object_for_type_check;
2933 53170           object_for_type_check.basic_type = basic_type;
2934 53170           object_for_type_check.type_dimension = 1;
2935            
2936 53170           int32_t is_object_array = SPVM_API_is_object_array(env, stack, &object_for_type_check);
2937            
2938 53170 50         if (!is_object_array) {
2939 0           return NULL;
2940             }
2941            
2942 53170 50         if (!basic_type) {
2943 0           return NULL;
2944             }
2945            
2946 53170           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(void*) * (length + 1);
2947            
2948 53170           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
2949            
2950 53170           return object;
2951             }
2952              
2953 4           SPVM_OBJECT* SPVM_API_new_object_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t length) {
2954            
2955 4           SPVM_OBJECT* object = SPVM_API_new_object_array_no_mortal(env, stack, basic_type, length);
2956            
2957 4           SPVM_API_push_mortal(env, stack, object);
2958            
2959 4           return object;
2960             }
2961              
2962 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) {
2963            
2964 70 50         if (type_dimension < 2) {
2965 0           return NULL;
2966             }
2967 70 50         else if (basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_ANY_OBJECT) {
2968 0           return NULL;
2969             }
2970            
2971 70           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + sizeof(void*) * (length + 1);
2972            
2973 70 50         if (!basic_type) {
2974 0           return NULL;
2975             }
2976 70           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, type_dimension, length, 0);
2977            
2978 70           return object;
2979             }
2980              
2981 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) {
2982            
2983 0           SPVM_OBJECT* object = SPVM_API_new_muldim_array_no_mortal(env, stack, basic_type, type_dimension, length);
2984            
2985 0           SPVM_API_push_mortal(env, stack, object);
2986            
2987 0           return object;
2988             }
2989              
2990 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) {
2991            
2992 226           SPVM_RUNTIME* runtime = env->runtime;
2993            
2994             // valut_t array dimension must be 1
2995 226           const char* basic_type_name = basic_type->name;
2996            
2997 226           int32_t fields_length = basic_type->fields_length;
2998 226           SPVM_RUNTIME_FIELD* field_first = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, basic_type, 0);
2999            
3000 226           int32_t field_basic_type_id = field_first->basic_type->id;
3001            
3002             int32_t unit_size;
3003 226 100         if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE) {
3004 42           unit_size = sizeof(int8_t);
3005             }
3006 184 100         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT) {
3007 32           unit_size = sizeof(int16_t);
3008             }
3009 152 100         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_INT) {
3010 44           unit_size = sizeof(int32_t);
3011             }
3012 108 100         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) {
3013 32           unit_size = sizeof(int64_t);
3014             }
3015 76 100         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT) {
3016 28           unit_size = sizeof(float);
3017             }
3018 48 50         else if (field_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE) {
3019 48           unit_size = sizeof(double);
3020             }
3021             else {
3022 0           assert(0);
3023             }
3024            
3025 226           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + unit_size * fields_length * (length + 1);
3026            
3027 226           SPVM_OBJECT* object = SPVM_API_new_object_common(env, stack, alloc_size, basic_type, 1, length, 0);
3028            
3029 226           return object;
3030             }
3031              
3032 0           SPVM_OBJECT* SPVM_API_new_mulnum_array(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t length) {
3033            
3034 0           SPVM_OBJECT* object = SPVM_API_new_mulnum_array_no_mortal(env, stack, basic_type, length);
3035            
3036 0           SPVM_API_push_mortal(env, stack, object);
3037            
3038 0           return object;
3039             }
3040              
3041 268           SPVM_OBJECT* SPVM_API_new_array_proto_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t length) {
3042              
3043 268 50         if (array == NULL) {
3044 0           return NULL;
3045             }
3046            
3047 268 50         if (length < 0) {
3048 0           return NULL;
3049             }
3050            
3051 268           size_t element_size = SPVM_API_get_elem_size(env, stack, array);
3052            
3053 268           size_t alloc_size = (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + element_size * (length + 1);
3054            
3055 268           SPVM_RUNTIME_BASIC_TYPE* array_basic_type = SPVM_API_get_object_basic_type(env, stack, array);
3056 268           SPVM_OBJECT* new_array = SPVM_API_new_object_common(env, stack, alloc_size, array_basic_type, array->type_dimension, length, 0);
3057            
3058 268           return new_array;
3059             }
3060              
3061 262           SPVM_OBJECT* SPVM_API_new_array_proto(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t length) {
3062            
3063            
3064 262           SPVM_OBJECT* object = SPVM_API_new_array_proto_no_mortal(env, stack, array, length);
3065            
3066 262           SPVM_API_push_mortal(env, stack, object);
3067            
3068 262           return object;
3069             }
3070              
3071 0           int32_t SPVM_API_get_object_basic_type_id(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3072 0           return object->basic_type->id;
3073             }
3074              
3075 2744260           SPVM_RUNTIME_BASIC_TYPE* SPVM_API_get_object_basic_type(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3076            
3077 2744260           return object->basic_type;
3078             }
3079              
3080 193358           const char* SPVM_API_get_object_basic_type_name(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3081            
3082 193358           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3083            
3084 193358           return object_basic_type->name;
3085             }
3086              
3087 21243           int32_t SPVM_API_get_object_type_dimension(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3088 21243           return object->type_dimension;
3089             }
3090              
3091 190945           int32_t SPVM_API_length(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3092            
3093 190945           int32_t length = object->length;
3094            
3095 190945           return length;
3096             }
3097              
3098 526615           void SPVM_API_set_length(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, int32_t length) {
3099            
3100 526615           object->length = length;
3101 526615           }
3102              
3103 1022           int8_t* SPVM_API_get_elems_byte(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3104            
3105 1022           return (int8_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3106             }
3107              
3108 183237           const char* SPVM_API_get_chars(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string) {
3109            
3110 183237           return (const char*)((intptr_t)string + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3111             }
3112              
3113 926           int16_t* SPVM_API_get_elems_short(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3114            
3115 926           return (int16_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3116             }
3117              
3118 1150           int32_t* SPVM_API_get_elems_int(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3119            
3120 1150           return (int32_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3121             }
3122              
3123 928           int64_t* SPVM_API_get_elems_long(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3124            
3125 928           return (int64_t*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3126             }
3127              
3128 922           float* SPVM_API_get_elems_float(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3129            
3130 922           return (float*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3131             }
3132              
3133 916           double* SPVM_API_get_elems_double(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3134            
3135 916           return (double*)((intptr_t)object + SPVM_API_RUNTIME_get_object_data_offset(env->runtime));
3136             }
3137              
3138 104193           SPVM_OBJECT* SPVM_API_get_elem_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t index) {
3139            
3140 104193           SPVM_OBJECT* object_maybe_weaken = ((SPVM_OBJECT**)((intptr_t)array + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[index];
3141 104193           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, object_maybe_weaken);
3142            
3143 104193           return object;
3144             }
3145              
3146 31176           void SPVM_API_set_elem_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t index, SPVM_OBJECT* object) {
3147            
3148 31176           void* object_ref = &((void**)((intptr_t)array + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[index];
3149            
3150 31176           SPVM_API_assign_object(env, stack, object_ref, object);
3151 31176           }
3152              
3153 103981           SPVM_OBJECT* SPVM_API_get_elem_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t index) {
3154            
3155 103981           return SPVM_API_get_elem_object(env, stack, array, index);
3156             }
3157              
3158 119           void SPVM_API_set_elem_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, int32_t index, SPVM_OBJECT* string) {
3159            
3160 119           SPVM_API_set_elem_object(env, stack, array, index, string);
3161 119           }
3162              
3163 1751815           void* SPVM_API_get_pointer(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3164            
3165 1751815           return object->pointer;
3166             }
3167              
3168 269294           void SPVM_API_set_pointer(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, void* pointer) {
3169            
3170 269294           object->pointer = pointer;
3171 269294           }
3172              
3173 765577           SPVM_RUNTIME_FIELD* SPVM_API_get_field(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* field_name) {
3174            
3175 765577           SPVM_RUNTIME* runtime = env->runtime;
3176            
3177 765577 50         if (!object) {
3178 0           return NULL;
3179             }
3180            
3181 765577           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3182            
3183 765577 50         if (object->type_dimension != 0) {
3184 0           return NULL;
3185             }
3186            
3187 765577           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_name(runtime, object_basic_type, field_name);
3188            
3189 765577           return field;
3190             }
3191              
3192 3026           SPVM_RUNTIME_FIELD* SPVM_API_get_field_static(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* field_name) {
3193            
3194 3026           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3195            
3196 3026 50         if (!basic_type) {
3197 0           return NULL;
3198             }
3199            
3200 3026           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_name(env->runtime, basic_type, field_name);
3201            
3202 3026           return field;
3203             }
3204              
3205 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) {
3206            
3207 108           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3208            
3209 108 50         if (!basic_type) {
3210 0           return NULL;
3211             }
3212            
3213 108           SPVM_RUNTIME_CLASS_VAR* class_var = SPVM_API_BASIC_TYPE_get_class_var_by_name(env->runtime, basic_type, class_var_name);
3214            
3215 108           return class_var;
3216             }
3217              
3218 12957           SPVM_RUNTIME_METHOD* SPVM_API_get_method(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* method_name) {
3219            
3220 12957           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3221            
3222 12957 50         if (!basic_type) {
3223 0           return NULL;
3224             }
3225            
3226 12957           SPVM_RUNTIME_METHOD* method = SPVM_API_BASIC_TYPE_get_method_by_name(env->runtime, basic_type, method_name);
3227            
3228 12957           return method;
3229             }
3230              
3231 58           SPVM_RUNTIME_METHOD* SPVM_API_get_class_method(SPVM_ENV* env, SPVM_VALUE* stack, const char* basic_type_name, const char* method_name) {
3232            
3233 58           SPVM_RUNTIME_METHOD* method = SPVM_API_get_method(env, stack, basic_type_name, method_name);
3234            
3235 58 50         if (method) {
3236 58 50         if (!method->is_class_method) {
3237 0           return NULL;
3238             }
3239             }
3240            
3241 58           return method;
3242             }
3243              
3244 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) {
3245            
3246 2           SPVM_RUNTIME_METHOD* method = SPVM_API_get_method(env, stack, basic_type_name, method_name);
3247            
3248 2 50         if (method) {
3249 2 50         if (method->is_class_method) {
3250 0           return NULL;
3251             }
3252             }
3253            
3254 2           return method;
3255             }
3256              
3257 700635           SPVM_RUNTIME_METHOD* SPVM_API_get_instance_method(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, const char* method_name) {
3258            
3259             // Method
3260 700635           SPVM_RUNTIME_METHOD* method = NULL;
3261            
3262             // Compiler
3263 700635           SPVM_RUNTIME* runtime = env->runtime;
3264            
3265 700635 50         if (!object) {
3266 0           return NULL;
3267             }
3268            
3269             // Basic type
3270 700635           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3271 700635           SPVM_RUNTIME_BASIC_TYPE* parent_basic_type = object_basic_type;
3272            
3273             while (1) {
3274 700737 100         if (!parent_basic_type) {
3275 10           break;
3276             }
3277            
3278             // Method
3279 700727           method = SPVM_API_BASIC_TYPE_get_method_by_name(runtime, parent_basic_type, method_name);
3280 700727 100         if (method) {
3281             // Instance method
3282 700625 50         if (method->is_class_method) {
3283 0           method = NULL;
3284             }
3285 700625           break;
3286             }
3287            
3288 102           parent_basic_type = parent_basic_type->parent;
3289 102           }
3290            
3291 700635           return method;
3292             }
3293              
3294             // Deprecated
3295 1460468           void* SPVM_API_new_memory_stack(SPVM_ENV* env, SPVM_VALUE* stack, size_t size) {
3296            
3297 1460468           return SPVM_API_new_memory_block(env, stack, size);
3298             }
3299              
3300 1989070           void* SPVM_API_new_memory_block(SPVM_ENV* env, SPVM_VALUE* stack, size_t size) {
3301            
3302 1989070 50         assert(size > 0);
3303            
3304             if ((uint64_t)size > (uint64_t)SIZE_MAX) {
3305             return NULL;
3306             }
3307            
3308 1989070           void* block = SPVM_ALLOCATOR_alloc_memory_block_unmanaged((size_t)size);
3309            
3310 1989070           stack[SPVM_API_C_STACK_INDEX_MEMORY_BLOCKS_COUNT].ival++;
3311            
3312             #ifdef SPVM_DEBUG_MEMORY
3313             fprintf(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);
3314             #endif
3315            
3316 1989070           return block;
3317             }
3318              
3319             // Deprecated
3320 1988420           void SPVM_API_free_memory_block(SPVM_ENV* env, SPVM_VALUE* stack, void* block) {
3321            
3322 1988420 100         if (block) {
3323 1988418           SPVM_ALLOCATOR_free_memory_block_unmanaged(block);
3324 1988418           stack[SPVM_API_C_STACK_INDEX_MEMORY_BLOCKS_COUNT].ival--;
3325             #ifdef SPVM_DEBUG_MEMORY
3326             fprintf(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);
3327             #endif
3328             }
3329 1988420           }
3330              
3331 1460468           void SPVM_API_free_memory_stack(SPVM_ENV* env, SPVM_VALUE* stack, void* block) {
3332            
3333 1460468           SPVM_API_free_memory_block(env, stack, block);
3334            
3335 1460468           }
3336              
3337 548           int32_t SPVM_API_get_memory_blocks_count_stack(SPVM_ENV* env, SPVM_VALUE* stack) {
3338            
3339 548           return SPVM_API_get_memory_blocks_count(env, stack);
3340             }
3341              
3342 572           int32_t SPVM_API_get_memory_blocks_count(SPVM_ENV* env, SPVM_VALUE* stack) {
3343            
3344            
3345 572           int32_t memory_blocks_count = stack[SPVM_API_C_STACK_INDEX_MEMORY_BLOCKS_COUNT].ival;
3346            
3347 572           return memory_blocks_count;
3348             }
3349              
3350 222           SPVM_OBJECT* SPVM_API_copy_no_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3351 222 50         if (!object) {
3352 0           return NULL;
3353             }
3354            
3355             SPVM_OBJECT* new_object;
3356            
3357 222           int32_t length = SPVM_API_length(env, stack, object);
3358            
3359 222 100         if (SPVM_API_is_string(env, stack, object)) {
3360 216           new_object = SPVM_API_new_string_no_mortal(env, stack, NULL, length);
3361            
3362 216           const char* object_chars = SPVM_API_get_chars(env, stack, object);
3363 216           char* new_object_chars = (char*)SPVM_API_get_chars(env, stack, new_object);
3364            
3365 216           memcpy(new_object_chars, object_chars, length);
3366             }
3367 12 100         else if (SPVM_API_is_numeric_array(env, stack, object) || SPVM_API_is_mulnum_array(env, stack, object)) {
    50          
3368 6           new_object = SPVM_API_new_array_proto_no_mortal(env, stack, object, length);
3369            
3370 6           const char* object_bytes = (const char*)SPVM_API_get_elems_byte(env, stack, object);
3371 6           char* new_object_bytes = (char*)SPVM_API_get_elems_byte(env, stack, new_object);
3372            
3373 6           size_t element_size = SPVM_API_get_elem_size(env, stack, object);
3374            
3375 6           memcpy(new_object_bytes, object_bytes, element_size * length);
3376             }
3377             else {
3378 0           new_object = NULL;
3379             }
3380            
3381 222           return new_object;
3382             }
3383              
3384 0           SPVM_OBJECT* SPVM_API_copy(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3385            
3386            
3387 0           SPVM_OBJECT* new_object = SPVM_API_copy_no_mortal(env, stack, object);
3388            
3389 0           SPVM_API_push_mortal(env, stack, new_object);
3390            
3391 0           return new_object;
3392             }
3393              
3394 34           void SPVM_API_shorten(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* string, int32_t new_length) {
3395            
3396            
3397 34 50         if (string != NULL) {
3398 34 50         if (SPVM_API_is_string(env, stack, string)) {
3399 34 50         if (!SPVM_API_is_read_only(env, stack, string)) {
3400 34           int32_t length = SPVM_API_length(env, stack, string);
3401            
3402 34 100         if (new_length > length) {
3403 2           new_length = length;
3404             }
3405 32 50         else if (new_length < 0) {
3406 0           new_length = 0;
3407             }
3408            
3409 34           SPVM_API_set_length(env, stack, string, new_length);
3410 34           char* chars = (char*)SPVM_API_get_chars(env, stack, string);
3411 34 50         if (new_length > length) {
3412 0           memset(chars + new_length, 0, new_length - length);
3413             }
3414             }
3415             }
3416             }
3417 34           }
3418              
3419 109608           int32_t SPVM_API_elem_isa(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* array, SPVM_OBJECT* element) {
3420            
3421 109608           SPVM_RUNTIME* runtime = env->runtime;
3422            
3423 109608 50         assert(array);
3424            
3425 109608           SPVM_RUNTIME_BASIC_TYPE* array_basic_type = SPVM_API_get_object_basic_type(env, stack,array);
3426            
3427 109608           int32_t array_type_dimension = array->type_dimension;
3428            
3429 109608 50         assert(array_type_dimension > 0);
3430 109608           int32_t runtime_assignability = SPVM_API_isa(env, stack, element, array_basic_type, array_type_dimension - 1);
3431              
3432 109608           return runtime_assignability;
3433             }
3434              
3435 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) {
3436            
3437             // Object must be not null
3438 962 50         assert(object);
3439            
3440 962           int32_t is_type = 0;
3441 962           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3442 962 100         if (object_basic_type->id == basic_type->id && object->type_dimension == type_dimension) {
    100          
3443 956           is_type = 1;
3444             }
3445            
3446 962           return is_type;
3447             }
3448              
3449 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) {
3450            
3451 820           SPVM_RUNTIME_BASIC_TYPE* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3452 820 50         if (!basic_type) {
3453 0           return 0;
3454             };
3455            
3456 820           int32_t is_type = SPVM_API_is_type(env, stack, object, basic_type, type_dimension);
3457            
3458 820           return is_type;
3459             }
3460              
3461 318141           int32_t SPVM_API_isa(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object, SPVM_RUNTIME_BASIC_TYPE* basic_type, int32_t type_dimension) {
3462            
3463 318141           SPVM_RUNTIME* runtime = env->runtime;
3464            
3465             int32_t isa;
3466 318141 100         if (object == NULL) {
3467 222           isa = 1;
3468             }
3469             else {
3470 317919           SPVM_RUNTIME_BASIC_TYPE* object_basic_type = SPVM_API_get_object_basic_type(env, stack, object);
3471 317919           int32_t object_type_dimension = object->type_dimension;
3472 317919 50         if (!basic_type) {
3473 0           isa = 0;
3474             }
3475             else {
3476 317919           isa = SPVM_API_TYPE_can_assign(env->runtime, basic_type, type_dimension, 0, object_basic_type, object_type_dimension, 0);
3477             }
3478             }
3479            
3480 318141           return isa;
3481             }
3482              
3483 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) {
3484            
3485 0           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3486 0 0         if (!basic_type) {
3487 0           return 0;
3488             };
3489            
3490 0           int32_t isa = SPVM_API_isa(env, stack, object, basic_type, type_dimension);
3491            
3492 0           return isa;
3493             }
3494              
3495 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) {
3496 0           *error_id = 0;
3497            
3498 0           int32_t basic_type_id = SPVM_API_get_basic_type_id(env, stack, basic_type_name);
3499 0 0         if (basic_type_id < 0) {
3500 0           *error_id = 1;
3501 0           SPVM_API_die(env, stack, "The %s basic type is not found", basic_type_name, func_name, file, line);
3502             };
3503 0           return basic_type_id;
3504             }
3505              
3506 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) {
3507 0           *error_id = 0;
3508            
3509 0           void* basic_type = SPVM_API_get_basic_type(env, stack, basic_type_name);
3510 0 0         if (!basic_type) {
3511 0           *error_id = 1;
3512 0           SPVM_API_die(env, stack, "The %s basic type is not found", basic_type_name, func_name, file, line);
3513             };
3514            
3515 0           return basic_type;
3516             }
3517              
3518 166654           SPVM_RUNTIME_BASIC_TYPE* SPVM_API_get_basic_type_by_id(SPVM_ENV* env, SPVM_VALUE* stack, int32_t basic_type_id) {
3519            
3520 166654           void* basic_type = SPVM_API_RUNTIME_get_basic_type_by_id(env->runtime, basic_type_id);
3521            
3522 166654           return basic_type;
3523             }
3524              
3525 8           void* SPVM_API_strerror_string(SPVM_ENV* env, SPVM_VALUE* stack, int32_t errno_value, int32_t length) {
3526            
3527 8 50         if (length < 0) {
3528 0           return NULL;
3529             }
3530            
3531 8 50         if (length == 0) {
3532 8           length = 64;
3533             }
3534            
3535 8           void* obj_strerror_value = SPVM_API_new_string(env, stack, NULL, length);
3536 8           char* strerror_value = (char*)SPVM_API_get_chars(env, stack, obj_strerror_value);
3537            
3538 8           int32_t status = SPVM_STRERROR_strerror(errno_value, strerror_value, length);
3539            
3540 8 50         if (status == 0) {
3541 8           SPVM_API_shorten(env, stack, obj_strerror_value, strlen(strerror_value));
3542 8           return obj_strerror_value;
3543             }
3544             else {
3545 0           return NULL;
3546             }
3547             }
3548              
3549 4           const char* SPVM_API_strerror(SPVM_ENV* env, SPVM_VALUE* stack, int32_t errno_value, int32_t length) {
3550            
3551 4           void* obj_strerror_value = SPVM_API_strerror_string(env, stack, errno_value, length);
3552            
3553 4 50         if (obj_strerror_value) {
3554 4           char* strerror_value = (char*)SPVM_API_get_chars(env, stack, obj_strerror_value);
3555 4           return strerror_value;
3556             }
3557             else {
3558 0           return NULL;
3559             }
3560             }
3561              
3562 2           void* SPVM_API_strerror_string_nolen(SPVM_ENV* env, SPVM_VALUE* stack, int32_t errno_value) {
3563 2           return SPVM_API_strerror_string(env, stack, errno_value, 0);
3564             }
3565              
3566 2           const char* SPVM_API_strerror_nolen(SPVM_ENV* env, SPVM_VALUE* stack, int32_t errno_value) {
3567 2           return SPVM_API_strerror(env, stack, errno_value, 0);
3568             }
3569              
3570 1460468           int32_t SPVM_API_call_method_vm(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_METHOD* method, int32_t args_width) {
3571 1460468           return SPVM_VM_call_method(env, stack, method, args_width);
3572             }
3573              
3574 4           const char* SPVM_API_get_spvm_version_string(SPVM_ENV* env, SPVM_VALUE* stack) {
3575            
3576 4           const char* spvm_version_string = SPVM_NATIVE_VERSION_STRING;
3577            
3578 4           return spvm_version_string;
3579             }
3580              
3581 2           double SPVM_API_get_spvm_version_number(SPVM_ENV* env, SPVM_VALUE* stack) {
3582            
3583 2           const char* spvm_version_string = SPVM_API_get_spvm_version_string(env, stack);
3584            
3585 2 50         assert(spvm_version_string);
3586            
3587 2           int32_t spvm_version_string_length = strlen(spvm_version_string);
3588            
3589             char *end;
3590 2           errno = 0;
3591 2           double version_number = strtod(spvm_version_string, &end);
3592 2 50         assert(*end == '\0');
3593 2 50         assert(errno == 0);
3594            
3595 2           return version_number;
3596             }
3597              
3598 15           const char* SPVM_API_get_version_string(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type){
3599            
3600 15           return basic_type->version_string;
3601             }
3602              
3603 4           double SPVM_API_get_version_number(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_BASIC_TYPE* basic_type) {
3604            
3605 4           const char* version_string = SPVM_API_get_version_string(env, stack, basic_type);
3606            
3607 4 50         if (!version_string) {
3608 0           return -1;
3609             }
3610            
3611 4           int32_t version_string_length = strlen(version_string);
3612            
3613 4           char version_string_without_hyphen[20] = {0};
3614 4           int32_t version_string_without_hyphen_length = 0;
3615 36 100         for (int32_t i = 0; i < version_string_length; i++) {
3616 32           char ch = version_string[i];
3617 32 50         if (!(ch == '_')) {
3618 32           version_string_without_hyphen[version_string_without_hyphen_length] = ch;
3619 32           version_string_without_hyphen_length++;
3620             }
3621             }
3622            
3623             char *end;
3624 4           errno = 0;
3625 4           double version_number = strtod(version_string_without_hyphen, &end);
3626 4 50         assert(*end == '\0');
3627 4 50         assert(errno == 0);
3628            
3629 4           return version_number;
3630             }
3631              
3632 526581           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) {
3633            
3634 526581           SPVM_OBJECT* object = SPVM_API_new_memory_block(env, stack, alloc_size);
3635            
3636 526581 50         if (object) {
3637 526581           object->basic_type = basic_type;
3638 526581           object->type_dimension = type_dimension;
3639 526581           object->flag = flag;
3640            
3641             // The length of string can be shorten.
3642 526581           SPVM_API_set_length(env, stack, object, length);
3643             }
3644            
3645 526581           SPVM_MUTEX* mutex = SPVM_API_get_object_mutex(env, stack, object);
3646            
3647 526581           SPVM_MUTEX_init(mutex);
3648            
3649 526581           return object;
3650             }
3651              
3652 20           int32_t SPVM_API_check_stack_env(SPVM_ENV* env, SPVM_VALUE* stack) {
3653            
3654 20           int32_t is_valid = 0;
3655 20 50         if (stack[SPVM_API_C_STACK_INDEX_ENV].oval == env) {
3656 20           is_valid = 1;
3657             }
3658            
3659 20           return is_valid;
3660             }
3661              
3662 2856030           int32_t SPVM_API_call_method_common(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_RUNTIME_METHOD* method, int32_t args_width, int32_t mortal) {
3663            
3664             // Runtime
3665 2856030           SPVM_RUNTIME* runtime = env->runtime;
3666            
3667 2856030           int32_t error_id = 0;
3668 2856030           stack[SPVM_API_C_STACK_INDEX_ARGS_WIDTH].ival = args_width;
3669 2856030           stack[SPVM_API_C_STACK_INDEX_CALL_DEPTH].ival++;
3670            
3671 2856030           int32_t max_call_depth = 10000;
3672 2856030 50         if (stack[SPVM_API_C_STACK_INDEX_CALL_DEPTH].ival > max_call_depth) {
3673 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__);
3674             }
3675             else {
3676 2856030           void* method_return_basic_type = method->return_basic_type;
3677 2856030           int32_t method_return_type_dimension = method->return_type_dimension;
3678 2856030           int32_t method_return_type_flag = method->return_type_flag;
3679            
3680 2856030           SPVM_RUNTIME_BASIC_TYPE* current_basic_type = method->current_basic_type;
3681            
3682 2856030           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);
3683 2856030           int32_t no_need_call = 0;
3684 2856030 100         if (method->is_init) {
3685            
3686 21575 100         if (current_basic_type->initialized) {
3687 12296           no_need_call = 1;
3688             }
3689             else {
3690 9279           current_basic_type->initialized = 1;
3691             }
3692             }
3693            
3694 2856030 100         if (!no_need_call) {
3695             // Call native method
3696 2843734 100         if (method->is_native) {
3697             // Enter scope
3698 1372529           int32_t original_mortal_stack_top = SPVM_API_enter_scope(env, stack);
3699            
3700             // Set argument default values
3701 1372529           int32_t optional_args_length = method->args_length - method->required_args_length;
3702 1372529 100         if (optional_args_length > 0) {
3703            
3704             // Operation codes
3705 358           SPVM_OPCODE* opcodes = method->opcodes;
3706            
3707             // Execute operation codes
3708 358           int32_t opcode_rel_index = 0;
3709             while (1) {
3710            
3711 800           SPVM_OPCODE* opcode = &(opcodes[opcode_rel_index]);
3712            
3713 800 100         if (opcode->id == SPVM_OPCODE_C_ID_END_ARGS) {
3714 358           break;
3715             }
3716            
3717 442           switch (opcode->id) {
3718             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_BYTE: {
3719 4           int32_t stack_index = opcode->operand3 & 0xFF;
3720 4 100         if (stack_index >= args_width) {
3721 2           stack[stack_index].bval = (int8_t)(uint8_t)opcode->operand1;
3722             }
3723 4           break;
3724             }
3725             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_SHORT: {
3726 4           int32_t stack_index = opcode->operand3 & 0xFF;
3727 4 100         if (stack_index >= args_width) {
3728 2           stack[stack_index].sval = (int16_t)(uint16_t)opcode->operand1;
3729             }
3730 4           break;
3731             }
3732             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_INT: {
3733 16           int32_t stack_index = opcode->operand3 & 0xFF;
3734 16 100         if (stack_index >= args_width) {
3735 8           stack[stack_index].ival = (int32_t)opcode->operand1;
3736             }
3737 16           break;
3738             }
3739             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_LONG: {
3740 4           int32_t stack_index = opcode->operand3 & 0xFF;
3741 4 100         if (stack_index >= args_width) {
3742 2           stack[stack_index].lval = *(int64_t*)&opcode->operand1;
3743             }
3744 4           break;
3745             }
3746             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_FLOAT: {
3747 4           int32_t stack_index = opcode->operand3 & 0xFF;
3748 4 100         if (stack_index >= args_width) {
3749             SPVM_VALUE default_value;
3750 2           default_value.ival = (int32_t)opcode->operand1;
3751 2           stack[stack_index].fval = default_value.fval;
3752             }
3753 4           break;
3754             }
3755             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_DOUBLE: {
3756 4           int32_t stack_index = opcode->operand3 & 0xFF;
3757 4 100         if (stack_index >= args_width) {
3758 2           stack[stack_index].dval = *(double*)&opcode->operand1;
3759             }
3760 4           break;
3761             }
3762             case SPVM_OPCODE_C_ID_GET_STACK_OPTIONAL_OBJECT: {
3763 362           int32_t stack_index = opcode->operand3 & 0xFF;
3764 362 100         if (stack_index >= args_width) {
3765 16           stack[stack_index].oval = NULL;
3766             }
3767 362           break;
3768             }
3769             }
3770            
3771 442           opcode_rel_index++;
3772 442           }
3773             }
3774            
3775             // Call native subrotuine
3776 1372529           int32_t (*native_address)(SPVM_ENV*, SPVM_VALUE*) = method->native_address;
3777 1372529 50         assert(native_address != NULL);
3778 1372529           error_id = (*native_address)(env, stack);
3779            
3780             // Increment ref count of return value
3781 1372529 100         if (!error_id) {
3782 1372219 100         if (method_return_type_is_object) {
3783 312139           SPVM_OBJECT* return_object = *(void**)&stack[0];
3784 312139 100         if (return_object != NULL) {
3785 311561           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, return_object);
3786            
3787 311561           SPVM_MUTEX_lock(object_mutex);
3788            
3789 311561           SPVM_API_inc_ref_count(env, stack, return_object);
3790            
3791 311561           SPVM_MUTEX_unlock(object_mutex);
3792             }
3793             }
3794             }
3795            
3796             // Leave scope
3797 1372529           SPVM_API_leave_scope(env, stack, original_mortal_stack_top);
3798            
3799             // Decrement ref count of return value
3800 1372529 100         if (!error_id) {
3801 1372219 100         if (method_return_type_is_object) {
3802 312139           SPVM_OBJECT* return_object = *(void**)&stack[0];
3803 312139 100         if (return_object != NULL) {
3804 311561           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, return_object);
3805            
3806 311561           SPVM_MUTEX_lock(object_mutex);
3807            
3808 311561           SPVM_API_dec_ref_count(env, stack, return_object);
3809            
3810 311561           SPVM_MUTEX_unlock(object_mutex);
3811             }
3812             }
3813             }
3814            
3815             // Set default exception message
3816 1372529 100         if (error_id && SPVM_API_get_exception(env, stack) == NULL) {
    50          
3817 0           void* exception = SPVM_API_new_string_nolen_no_mortal(env, stack, "Error");
3818 1372529           SPVM_API_set_exception(env, stack, exception);
3819             }
3820             }
3821             else {
3822             // Call precompiled method
3823 1471205           void* method_precompile_address = method->precompile_address;
3824 1471205 100         if (method_precompile_address) {
3825 10737           int32_t (*precompile_address)(SPVM_ENV*, SPVM_VALUE*) = method_precompile_address;
3826 10737           error_id = (*precompile_address)(env, stack);
3827             }
3828             // Call sub virtual machine
3829             else {
3830 1460468           error_id = SPVM_API_call_method_vm(env, stack, method, args_width);
3831             }
3832             }
3833            
3834 2843734 100         if (mortal && method_return_type_is_object) {
    100          
3835 6           SPVM_API_push_mortal(env, stack, stack[0].oval);
3836             }
3837             }
3838             }
3839            
3840 2856030           stack[SPVM_API_C_STACK_INDEX_CALL_DEPTH].ival--;
3841            
3842 2856030           return error_id;
3843             }
3844              
3845 309388           int32_t SPVM_API_push_mortal(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3846            
3847            
3848 309388           SPVM_OBJECT*** current_mortal_stack_ptr = (SPVM_OBJECT***)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK];
3849 309388           int32_t* current_mortal_stack_top_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_TOP];
3850 309388           int32_t* current_mortal_stack_capacity_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_CAPACITY];
3851            
3852 309388 50         if (object != NULL) {
3853             // Extend mortal stack
3854 309388 100         if (*current_mortal_stack_top_ptr >= *current_mortal_stack_capacity_ptr) {
3855 349           int32_t new_mortal_stack_capacity = *current_mortal_stack_capacity_ptr * 2;
3856 349           SPVM_OBJECT** new_mortal_stack = SPVM_API_new_memory_block(env, stack, sizeof(void*) * new_mortal_stack_capacity);
3857 349 50         if (new_mortal_stack == NULL) {
3858 0           return SPVM_NATIVE_C_BASIC_TYPE_ID_ERROR_CLASS;
3859             }
3860 349           memcpy(new_mortal_stack, *current_mortal_stack_ptr, sizeof(void*) * *current_mortal_stack_capacity_ptr);
3861 349           *current_mortal_stack_capacity_ptr = new_mortal_stack_capacity;
3862 349           SPVM_API_free_memory_block(env, stack, *current_mortal_stack_ptr);
3863 349           *current_mortal_stack_ptr = NULL;
3864 349           *current_mortal_stack_ptr = new_mortal_stack;
3865             }
3866            
3867 309388           SPVM_API_assign_object(env, stack, &(*current_mortal_stack_ptr)[*current_mortal_stack_top_ptr], object);
3868            
3869 309388           *current_mortal_stack_top_ptr = *current_mortal_stack_top_ptr + 1;
3870             }
3871            
3872 309388           return 0;
3873             }
3874              
3875 1372531           void SPVM_API_leave_scope(SPVM_ENV* env, SPVM_VALUE* stack, int32_t original_mortal_stack_top) {
3876            
3877 1372531           SPVM_OBJECT*** current_mortal_stack_ptr = (SPVM_OBJECT***)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK];
3878 1372531           int32_t* current_mortal_stack_top_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_TOP];
3879 1372531           int32_t* current_mortal_stack_capacity_ptr = (int32_t*)&stack[SPVM_API_C_STACK_INDEX_MORTAL_STACK_CAPACITY];
3880            
3881             int32_t mortal_stack_index;
3882 1681919 100         for (mortal_stack_index = original_mortal_stack_top; mortal_stack_index < *current_mortal_stack_top_ptr; mortal_stack_index++) {
3883            
3884 309388           SPVM_OBJECT** object_ref = &(*current_mortal_stack_ptr)[mortal_stack_index];
3885            
3886 309388           SPVM_API_assign_object(env, stack, object_ref, NULL);
3887            
3888             }
3889            
3890 1372531           *current_mortal_stack_top_ptr = original_mortal_stack_top;
3891 1372531           }
3892              
3893 1317643           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) {
3894            
3895 2159218 100         for (int32_t mortal_stack_index = original_mortal_stack_top; mortal_stack_index < *mortal_stack_top_ptr; mortal_stack_index++) {
3896 841575           int32_t var_index = mortal_stack[mortal_stack_index];
3897 841575           SPVM_OBJECT** object_ref = (SPVM_OBJECT**)&object_vars[var_index];
3898 841575 100         if (*object_ref != NULL) {
3899 820881           SPVM_API_assign_object(env, stack, object_ref, NULL);
3900             }
3901             }
3902 1317643           *mortal_stack_top_ptr = original_mortal_stack_top;
3903            
3904 1317643           }
3905              
3906 8407392           SPVM_OBJECT* SPVM_API_get_object_no_weaken_address(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
3907             // Dropping weaken flag
3908 8407392           void* object_no_weaken_address = (void*)((intptr_t)object & ~(intptr_t)1);
3909            
3910 8407392           return object_no_weaken_address;
3911             }
3912              
3913 1898483           int32_t SPVM_API_isweak_only_check_flag(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
3914 1898483           int32_t isweak = (intptr_t)*ref & 1;
3915 1898483           return isweak;
3916             }
3917              
3918 4           int32_t SPVM_API_isweak(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
3919 4           SPVM_RUNTIME* runtime = env->runtime;
3920            
3921 4 50         assert(ref);
3922            
3923 4 50         if (*ref == NULL) {
3924 0           return 0;
3925             }
3926            
3927 4           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
3928            
3929 4           SPVM_MUTEX* mutex_object = SPVM_API_get_object_mutex(env, stack, object);
3930            
3931 4           SPVM_MUTEX_lock(mutex_object);
3932            
3933 4           int32_t isweak = SPVM_API_isweak_only_check_flag(env, stack, ref);
3934            
3935 4           SPVM_MUTEX_unlock(mutex_object);
3936            
3937 4           return isweak;
3938             }
3939              
3940 374           int32_t SPVM_API_weaken(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
3941            
3942 374 50         assert(ref);
3943            
3944 374 100         if (*ref == NULL) {
3945 2           return 0;
3946             }
3947            
3948 372           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
3949            
3950 372           SPVM_MUTEX* mutex_object = SPVM_API_get_object_mutex(env, stack, object);
3951            
3952 372           SPVM_MUTEX_lock(mutex_object);
3953            
3954 372           int32_t isweak = SPVM_API_isweak_only_check_flag(env, stack, ref);
3955            
3956 372           SPVM_OBJECT* destroied_referent = NULL;
3957 372 100         if (!isweak) {
3958            
3959 370           int32_t ref_count = SPVM_API_get_ref_count(env, stack, object);
3960            
3961 370 50         assert(ref_count > 0);
3962            
3963             // If reference count is 1, the object is destroied
3964 370 100         if (ref_count == 1) {
3965 2           destroied_referent = object;
3966 2           *ref = NULL;
3967             }
3968             else {
3969             // Weaken is implemented by tag pointer.
3970             // If pointer most right bit is 1, object is weaken.
3971 368           *ref = (SPVM_OBJECT*)((intptr_t)*ref | 1);
3972            
3973 368           SPVM_API_dec_ref_count(env, stack, object);
3974            
3975 368           SPVM_WEAKEN_BACKREF* new_weaken_backref = SPVM_API_new_memory_block(env, stack, sizeof(SPVM_WEAKEN_BACKREF));
3976 368           new_weaken_backref->ref = ref;
3977            
3978             // Create a new weaken back refference
3979 368 50         if (object->weaken_backref_head == NULL) {
3980 368           object->weaken_backref_head = new_weaken_backref;
3981             }
3982             // Add weaken back refference
3983             else {
3984 0           SPVM_WEAKEN_BACKREF* weaken_backref_next = object->weaken_backref_head;
3985            
3986 0 0         while (weaken_backref_next->next != NULL){
3987 0           weaken_backref_next = weaken_backref_next->next;
3988             }
3989 0           weaken_backref_next->next = new_weaken_backref;
3990             }
3991             }
3992             }
3993            
3994 372           SPVM_MUTEX_unlock(mutex_object);
3995            
3996 372 100         if (destroied_referent) {
3997 2           SPVM_API_assign_object(env, stack, &destroied_referent, NULL);
3998             }
3999            
4000 374           return 0;
4001             }
4002              
4003 5877192           void SPVM_API_unweaken_thread_unsafe(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
4004            
4005 5877192 50         assert(ref);
4006            
4007 5877192 100         if (*ref == NULL) {
4008 3979085           return;
4009             }
4010            
4011 1898107           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
4012            
4013 1898107           int32_t isweak = SPVM_API_isweak_only_check_flag(env, stack, ref);
4014            
4015 1898107 100         if (isweak) {
4016            
4017 356 50         assert(object->weaken_backref_head);
4018            
4019             // Drop weaken flag
4020 356           *ref = (SPVM_OBJECT*)((intptr_t)*ref & ~(intptr_t)1);
4021            
4022 356           SPVM_API_inc_ref_count(env, stack, object);
4023            
4024             // Remove a weaken back reference
4025 356 50         assert(object->weaken_backref_head);
4026 356           SPVM_WEAKEN_BACKREF** weaken_backref_next_ptr = &object->weaken_backref_head;
4027 356 50         while (*weaken_backref_next_ptr != NULL){
4028 356 50         if ((*weaken_backref_next_ptr)->ref == ref) {
4029 356           SPVM_WEAKEN_BACKREF* tmp = (*weaken_backref_next_ptr)->next;
4030            
4031 356           SPVM_WEAKEN_BACKREF* weaken_backref_next = *weaken_backref_next_ptr;
4032            
4033 356           SPVM_API_free_memory_block(env, stack, weaken_backref_next);
4034 356           weaken_backref_next = NULL;
4035            
4036 356           *weaken_backref_next_ptr = tmp;
4037 356           break;
4038             }
4039 0           *weaken_backref_next_ptr = (*weaken_backref_next_ptr)->next;
4040             }
4041             }
4042            
4043             }
4044              
4045 0           void SPVM_API_unweaken(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref) {
4046            
4047 0 0         assert(ref);
4048            
4049 0 0         if (*ref == NULL) {
4050 0           return;
4051             }
4052            
4053 0           SPVM_OBJECT* object = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
4054            
4055 0           SPVM_MUTEX* mutex_object = SPVM_API_get_object_mutex(env, stack, object);
4056            
4057 0           SPVM_MUTEX_lock(mutex_object);
4058            
4059 0           SPVM_API_unweaken_thread_unsafe(env, stack, ref);
4060            
4061 0           SPVM_MUTEX_unlock(mutex_object);
4062             }
4063              
4064 12           void SPVM_API_free_weaken_backrefs(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_WEAKEN_BACKREF* weaken_backref_head) {
4065            
4066 12           SPVM_WEAKEN_BACKREF* weaken_backref_head_cur = weaken_backref_head;
4067 12           SPVM_WEAKEN_BACKREF* weaken_backref_head_next = NULL;
4068 24 100         while (weaken_backref_head_cur != NULL){
4069 12           *(weaken_backref_head_cur->ref) = NULL;
4070 12           weaken_backref_head_next = weaken_backref_head_cur->next;
4071            
4072 12           SPVM_API_free_memory_block(env, stack, weaken_backref_head_cur);
4073 12           weaken_backref_head_cur = NULL;
4074 12           weaken_backref_head_cur = weaken_backref_head_next;
4075             }
4076 12           }
4077              
4078 5877192           void SPVM_API_assign_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT** ref, SPVM_OBJECT* object) {
4079            
4080 5877192           SPVM_RUNTIME* runtime = env->runtime;
4081            
4082 5877192           SPVM_MUTEX* runtime_mutex_update_object = runtime->mutex_update_object;
4083            
4084 5877192           SPVM_MUTEX_lock(runtime_mutex_update_object);
4085            
4086 5877192           SPVM_OBJECT* object_assign_off = SPVM_API_get_object_no_weaken_address(env, stack, *ref);
4087 5877192 100         if (object_assign_off) {
4088            
4089 1898107           SPVM_MUTEX* mutex_object_assign_off = SPVM_API_get_object_mutex(env, stack, object_assign_off);
4090            
4091 1898107           SPVM_MUTEX_lock(mutex_object_assign_off);
4092             }
4093            
4094 5877192 50         assert(!((intptr_t)object & 1));
4095            
4096 5877192           int32_t lock_object_mutex = 0;
4097 5877192 100         if (object && (object != object_assign_off)) {
    100          
4098 1898221           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, object);
4099            
4100 1898221           SPVM_MUTEX_lock(object_mutex);
4101 1898221           lock_object_mutex = 1;
4102             }
4103            
4104 5877192           SPVM_MUTEX_unlock(runtime_mutex_update_object);
4105            
4106 5877192           SPVM_API_unweaken_thread_unsafe(env, stack, ref);
4107            
4108 5877192 100         if (object) {
4109 1898771           SPVM_API_inc_ref_count(env, stack, object);
4110             }
4111            
4112 5877192           *ref = object;
4113            
4114 5877192 100         if (object) {
4115 1898771           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, object);
4116 1898771 100         if (lock_object_mutex) {
4117 1898221           SPVM_MUTEX_unlock(object_mutex);
4118             }
4119             }
4120            
4121 5877192 100         if (!object_assign_off) {
4122 3979085           return;
4123             }
4124            
4125 1898107           int32_t object_assign_off_ref_count = SPVM_API_get_ref_count(env, stack, object_assign_off);
4126            
4127 1898107 50         assert(object_assign_off_ref_count > 0);
4128            
4129 1898107           SPVM_MUTEX* mutex_object_assign_off = SPVM_API_get_object_mutex(env, stack, object_assign_off);
4130 1898107 100         if (object_assign_off_ref_count > 1) {
4131            
4132 1372178           SPVM_API_dec_ref_count(env, stack, object_assign_off);
4133 1372178           SPVM_MUTEX_unlock(mutex_object_assign_off);
4134            
4135 1372178           return;
4136             }
4137            
4138 525929           SPVM_MUTEX_unlock(mutex_object_assign_off);
4139            
4140             // Free object_assign_off array
4141 525929 100         if (SPVM_API_is_object_array(env, stack, object_assign_off)) {
4142 53502           int32_t length = SPVM_API_length(env, stack, object_assign_off);
4143 2260766 100         for (int32_t index = 0; index < length; index++) {
4144 2207264           SPVM_OBJECT** ref = &(((SPVM_OBJECT**)((intptr_t)object_assign_off + SPVM_API_RUNTIME_get_object_data_offset(env->runtime)))[index]);
4145 2207264           SPVM_API_assign_object(env, stack, ref, NULL);
4146             }
4147             }
4148             // Free object_assign_off
4149             else {
4150 472427           SPVM_RUNTIME_BASIC_TYPE* object_assign_off_basic_type = SPVM_API_get_object_basic_type(env, stack, object_assign_off);
4151 472427           int32_t object_assign_off_basic_type_category = object_assign_off_basic_type->category;
4152 472427 100         if (object_assign_off_basic_type_category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS) {
4153             // Class
4154 305547           SPVM_RUNTIME* runtime = env->runtime;
4155            
4156             // Call destructor
4157 305547 100         if (object_assign_off_basic_type->destructor_method) {
4158            
4159 686           SPVM_VALUE save_stack0 = stack[0];
4160 686           SPVM_OBJECT* save_exception = SPVM_API_get_exception(env, stack);
4161 686           SPVM_OBJECT* save_exception_referent = NULL;
4162 686           SPVM_API_assign_object(env, stack, &save_exception_referent, save_exception);
4163            
4164 686           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);
4165            
4166 686           stack[0].oval = object_assign_off;
4167 686           int32_t args_width = 1;
4168 686           int32_t error_id = SPVM_API_call_method_no_mortal(env, stack, destructor_method, args_width);
4169            
4170             // Exception in destructor is changed to warning
4171 686 100         if (error_id) {
4172 2           void* exception = SPVM_API_get_exception(env, stack);
4173 2           const char* exception_chars = SPVM_API_get_chars(env, stack, exception);
4174 2           fprintf(stderr, "[The following exception is coverted to a warning because it is thrown in the DESTROY method]\n%s\n", exception_chars);
4175             }
4176            
4177             // Restore stack and exception
4178 686           stack[0] = save_stack0;
4179 686           SPVM_API_set_exception(env, stack, save_exception);
4180 686           SPVM_API_assign_object(env, stack, &save_exception_referent, NULL);
4181             }
4182            
4183             // Free object_assign_off fields
4184 305547           int32_t object_assign_off_fields_length = object_assign_off_basic_type->fields_length;
4185 618631 100         for (int32_t field_index = 0; field_index < object_assign_off_fields_length; field_index++) {
4186 313084           SPVM_RUNTIME_FIELD* field = SPVM_API_BASIC_TYPE_get_field_by_index(runtime, object_assign_off_basic_type, field_index);
4187            
4188 313084           void* field_basic_type = field->basic_type;
4189 313084           int32_t field_type_dimension = field->type_dimension;
4190 313084           int32_t field_type_flag = field->type_flag;
4191 313084           int32_t field_type_is_object_assign_off = SPVM_API_TYPE_is_object_type(runtime, field_basic_type, field_type_dimension, field_type_flag);
4192            
4193 313084 100         if (field_type_is_object_assign_off) {
4194 256696           SPVM_OBJECT** ref = (SPVM_OBJECT**)((intptr_t)object_assign_off + (size_t)SPVM_API_RUNTIME_get_object_data_offset(env->runtime) + field->offset);
4195 256696           SPVM_API_assign_object(env, stack, ref, NULL);
4196             }
4197             }
4198             }
4199            
4200             }
4201            
4202 525929           SPVM_MUTEX_lock(mutex_object_assign_off);
4203            
4204 525929           SPVM_API_dec_ref_count(env, stack, object_assign_off);
4205            
4206 525929           object_assign_off_ref_count = SPVM_API_get_ref_count(env, stack, object_assign_off);
4207            
4208 525929 50         if (object_assign_off_ref_count > 0) {
4209 0           SPVM_MUTEX_unlock(mutex_object_assign_off);
4210             }
4211 525929 50         else if (object_assign_off_ref_count == 0) {
4212            
4213             // Free weak back refenreces
4214 525929 100         if (object_assign_off->weaken_backref_head != NULL) {
4215 12           SPVM_API_free_weaken_backrefs(env, stack, object_assign_off->weaken_backref_head);
4216 12           object_assign_off->weaken_backref_head = NULL;
4217             }
4218            
4219 525929           SPVM_MUTEX_unlock(mutex_object_assign_off);
4220 525929           SPVM_MUTEX_destroy(mutex_object_assign_off);
4221            
4222             // Free object_assign_off
4223 525929           SPVM_API_free_memory_block(env, stack, object_assign_off);
4224 525929           object_assign_off = NULL;
4225             }
4226             else {
4227 0           assert(0);
4228             }
4229             }
4230              
4231 2300955           void SPVM_API_inc_ref_count(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4232            
4233 2300955 50         if (object != NULL) {
4234 2300955           int32_t ref_count = SPVM_API_get_ref_count(env, stack, object);
4235 2300955 50         assert(ref_count >= 0);
4236            
4237 2300955           object->ref_count++;
4238             }
4239            
4240 2300955           }
4241              
4242 2300303           void SPVM_API_dec_ref_count(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4243            
4244 2300303           SPVM_RUNTIME* runtime = env->runtime;
4245            
4246 2300303 50         if (object != NULL) {
4247 2300303           int32_t ref_count = SPVM_API_get_ref_count(env, stack, object);
4248 2300303 50         assert(ref_count > 0);
4249            
4250 2300303           object->ref_count--;
4251             }
4252            
4253 2300303           }
4254              
4255 7025690           int32_t SPVM_API_get_ref_count(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4256            
4257 7025690           int32_t ref_count = object->ref_count;
4258            
4259 7025690           return ref_count;
4260             }
4261              
4262 9104353           SPVM_MUTEX* SPVM_API_get_object_mutex(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4263            
4264 9104353           SPVM_MUTEX* object_mutex = (SPVM_MUTEX*)((intptr_t)object + sizeof(SPVM_OBJECT));
4265            
4266 9104353           return object_mutex;
4267             }
4268              
4269 180534           void SPVM_API_lock_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4270            
4271 180534           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, object);
4272            
4273 180534           SPVM_MUTEX_lock(object_mutex);
4274 180534           }
4275              
4276 180534           void SPVM_API_unlock_object(SPVM_ENV* env, SPVM_VALUE* stack, SPVM_OBJECT* object) {
4277            
4278 180534           SPVM_MUTEX* object_mutex = SPVM_API_get_object_mutex(env, stack, object);
4279            
4280 180534           SPVM_MUTEX_unlock(object_mutex);
4281 180534           }
4282