// Copyright (c) 2023 Yuki Kimoto // MIT License #include "spvm_native.h" #include <assert.h> static const char* FILE_NAME = "Native::Runtime.c"; int32_t SPVM__Native__Runtime__build_precompile_class_source(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type = stack[1].oval; void* self = env->get_pointer(env, stack, obj_self); void* basic_type = env->get_pointer(env, stack, obj_basic_type); void* allocator = env->api->allocator->new_instance(); void* string_buffer = env->api->string_buffer->new_instance(allocator, 0); env->api->runtime->build_precompile_class_source(self, string_buffer, basic_type); const char* string_buffer_value = env->api->string_buffer->get_string(string_buffer); int32_t string_buffer_length = env->api->string_buffer->get_length(string_buffer); void* obj_precompile_source = env->new_string(env, stack, string_buffer_value, string_buffer_length); env->api->string_buffer->free_instance(string_buffer); env->api->allocator->free_instance(allocator); stack[0].oval = obj_precompile_source; return 0; } int32_t SPVM__Native__Runtime__build_precompile_method_source(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_method = stack[1].oval; void* self = env->get_pointer(env, stack, obj_self); void* method = env->get_pointer(env, stack, obj_method); void* allocator = env->api->allocator->new_instance(); void* string_buffer = env->api->string_buffer->new_instance(allocator, 0); env->api->runtime->build_precompile_method_source(self, string_buffer, method); const char* string_buffer_value = env->api->string_buffer->get_string(string_buffer); int32_t string_buffer_length = env->api->string_buffer->get_length(string_buffer); void* obj_precompile_method_source = env->new_string(env, stack, string_buffer_value, string_buffer_length); env->api->string_buffer->free_instance(string_buffer); env->api->allocator->free_instance(allocator); stack[0].oval = obj_precompile_method_source; return 0; } int32_t SPVM__Native__Runtime__set_native_method_address(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type_name = stack[1].oval; const char* basic_type_name = env->get_chars(env, stack, obj_basic_type_name); void* obj_method_name = stack[2].oval; const char* method_name = env->get_chars(env, stack, obj_method_name); void* obj_address = stack[3].oval; void* self = env->get_pointer(env, stack, obj_self); // Method id void* basic_type = env->api->runtime->get_basic_type_by_name(self, basic_type_name); void* method = env->api->basic_type->get_method_by_name(self, basic_type, method_name); // Native address void* address = env->get_pointer(env, stack, obj_address); env->api->method->set_native_address(self, method, address); return 0; } int32_t SPVM__Native__Runtime__get_native_method_address(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type_name = stack[1].oval; void* obj_method_name = stack[2].oval; void* self = env->get_pointer(env, stack, obj_self); // Basic type name const char* basic_type_name = env->get_chars(env, stack, obj_basic_type_name); // Method name const char* method_name = env->get_chars(env, stack, obj_method_name); // Method id void* basic_type = env->api->runtime->get_basic_type_by_name(self, basic_type_name); void* method = env->api->basic_type->get_method_by_name(self, basic_type, method_name); void* address = env->api->method->get_native_address(self, method); // Native address void* obj_address = env->new_pointer_object_by_name(env, stack, "Native::Address", address, &error_id, __func__, FILE_NAME, __LINE__); stack[0].oval = obj_address; return 0; } int32_t SPVM__Native__Runtime__get_method_is_class_method(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type_name = stack[1].oval; void* obj_method_name = stack[2].oval; void* self = env->get_pointer(env, stack, obj_self); // Basic type name const char* basic_type_name = env->get_chars(env, stack, obj_basic_type_name); // Method name const char* method_name = env->get_chars(env, stack, obj_method_name); // Method id void* basic_type = env->api->runtime->get_basic_type_by_name(self, basic_type_name); void* method = env->api->basic_type->get_method_by_name(self, basic_type, method_name); int32_t is_class_method = env->api->method->is_class_method(self, method); stack[0].ival = is_class_method; return 0; } int32_t SPVM__Native__Runtime__get_precompile_method_address(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type_name = stack[1].oval; void* obj_method_name = stack[2].oval; void* self = env->get_pointer(env, stack, obj_self); // Basic type name const char* basic_type_name = env->get_chars(env, stack, obj_basic_type_name); // Method name const char* method_name = env->get_chars(env, stack, obj_method_name); // Method id void* basic_type = env->api->runtime->get_basic_type_by_name(self, basic_type_name); void* method = env->api->basic_type->get_method_by_name(self, basic_type, method_name); void* address = env->api->method->get_precompile_address(self, method); // Native address void* obj_address = env->new_pointer_object_by_name(env, stack, "Native::Address", address, &error_id, __func__, FILE_NAME, __LINE__); stack[0].oval = obj_address; return 0; } int32_t SPVM__Native__Runtime__set_precompile_method_address(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type_name = stack[1].oval; const char* basic_type_name = env->get_chars(env, stack, obj_basic_type_name); void* obj_method_name = stack[2].oval; const char* method_name = env->get_chars(env, stack, obj_method_name); void* obj_address = stack[3].oval; void* self = env->get_pointer(env, stack, obj_self); // Method id void* basic_type = env->api->runtime->get_basic_type_by_name(self, basic_type_name); void* method = env->api->basic_type->get_method_by_name(self, basic_type, method_name); // Native address void* address = env->get_pointer(env, stack, obj_address); env->api->method->set_precompile_address(self, method, address); return 0; } int32_t SPVM__Native__Runtime__get_basic_types_length(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* self = env->get_pointer(env, stack, obj_self); int32_t basic_types_length = env->api->runtime->get_basic_types_length(self); stack[0].ival = basic_types_length; return 0; } int32_t SPVM__Native__Runtime__get_basic_type_by_id(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; int32_t index = stack[1].ival; void* self = env->get_pointer(env, stack, obj_self); void* basic_type = env->api->runtime->get_basic_type_by_id(self, index); if (!basic_type) { return env->die(env, stack, "The basic type cannot be found.", __func__, FILE_NAME, __LINE__); } void* obj_address_basic_type = env->new_pointer_object_by_name(env, stack, "Address", basic_type, &error_id, __func__, FILE_NAME, __LINE__); if (error_id) { return error_id; } stack[0].oval = obj_address_basic_type; env->call_class_method_by_name(env, stack, "Native::BasicType", "new_with_pointer", 1, &error_id, __func__, FILE_NAME, __LINE__); if (error_id) { return error_id; } void* obj_basic_type = stack[0].oval; env->set_no_free(env, stack, obj_basic_type, 1); env->set_field_object_by_name(env, stack, obj_basic_type, "runtime", obj_self, &error_id, __func__, FILE_NAME, __LINE__); if (error_id) { return error_id; } stack[0].oval = obj_basic_type; return 0; } int32_t SPVM__Native__Runtime__get_basic_type_by_name(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_name = stack[1].oval; if (!obj_name) { return env->die(env, stack, "The basic type cannot be found.", __func__, FILE_NAME, __LINE__); } const char* name = env->get_chars(env, stack, obj_name); void* self = env->get_pointer(env, stack, obj_self); void* basic_type = env->api->runtime->get_basic_type_by_name(self, name); if (!basic_type) { return env->die(env, stack, "The basic type cannot be found.", __func__, FILE_NAME, __LINE__); } void* obj_address_basic_type = env->new_pointer_object_by_name(env, stack, "Address", basic_type, &error_id, __func__, FILE_NAME, __LINE__); if (error_id) { return error_id; } stack[0].oval = obj_address_basic_type; env->call_class_method_by_name(env, stack, "Native::BasicType", "new_with_pointer", 1, &error_id, __func__, FILE_NAME, __LINE__); if (error_id) { return error_id; } void* obj_basic_type = stack[0].oval; env->set_no_free(env, stack, obj_basic_type, 1); env->set_field_object_by_name(env, stack, obj_basic_type, "runtime", obj_self, &error_id, __func__, FILE_NAME, __LINE__); if (error_id) { return error_id; } stack[0].oval = obj_basic_type; return 0; } int32_t SPVM__Native__Runtime__get_basic_type_parent_name(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type_name = stack[1].oval; const char* basic_type_name = env->get_chars(env, stack, obj_basic_type_name); void* self = env->get_pointer(env, stack, obj_self); void* basic_type = env->api->runtime->get_basic_type_by_name(self, basic_type_name); void* parent_basic_type = env->api->basic_type->get_parent(self, basic_type); void* obj_parent_basic_type_name = NULL; if (parent_basic_type) { const char* parent_basic_type_name = env->api->basic_type->get_name(self, parent_basic_type); obj_parent_basic_type_name = env->new_string_nolen(env, stack, parent_basic_type_name); } stack[0].oval = obj_parent_basic_type_name; return 0; } int32_t SPVM__Native__Runtime___get_method_names(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type_name = stack[1].oval; const char* basic_type_name = env->get_chars(env, stack, obj_basic_type_name); int32_t native_flag = stack[2].ival; int32_t precompile_flag = stack[3].ival; int32_t enum_flag = stack[4].ival; void* self = env->get_pointer(env, stack, obj_self); void* basic_type = env->api->runtime->get_basic_type_by_name(self, basic_type_name); int32_t methods_length = env->api->basic_type->get_methods_length(self, basic_type); int32_t match_methodes_length = 0; for (int32_t method_index = 0; method_index < methods_length; method_index++) { void* method = env->api->basic_type->get_method_by_index(self, basic_type, method_index); int32_t match = 0; if (native_flag) { if (env->api->method->is_native(self, method)) { match = 1; } } else if (precompile_flag) { if (env->api->method->is_precompile(self, method)) { match = 1; } } else if (enum_flag) { if (env->api->method->is_enum(self, method)) { match = 1; } } else { match = 1; } if (match) { match_methodes_length++; } } void* obj_method_names = env->new_string_array(env, stack, match_methodes_length); int32_t match_method_index = 0; for (int32_t method_index = 0; method_index < methods_length; method_index++) { void* method = env->api->basic_type->get_method_by_index(self, basic_type, method_index); int32_t match = 0; if (native_flag) { if (env->api->method->is_native(self, method)) { match = 1; } } else if (precompile_flag) { if (env->api->method->is_precompile(self, method)) { match = 1; } } else if (enum_flag) { if (env->api->method->is_enum(self, method)) { match = 1; } } else { match = 1; } if (match) { const char* method_name = env->api->method->get_name(self, method); void* obj_method_name = env->new_string_nolen(env, stack, method_name); env->set_elem_object(env, stack, obj_method_names, match_method_index, obj_method_name); match_method_index++; } } stack[0].oval = obj_method_names; return 0; } int32_t SPVM__Native__Runtime__get_compiler(SPVM_ENV* env, SPVM_VALUE* stack) { int32_t error_id = 0; void* obj_self = stack[0].oval; void* obj_basic_type = stack[1].oval; void* self = env->get_pointer(env, stack, obj_self); void* obj_compiler = env->get_field_object_by_name(env, stack, obj_self, "compiler", &error_id, __func__, FILE_NAME, __LINE__); if (error_id) { return error_id; } stack[0].oval = obj_compiler; return 0; }