147 lines
5.4 KiB
C
Raw Normal View History

2025-12-07 16:31:49 +01:00
#include "runtime_internal.h"
bool g_gc_initialized = false;
RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name) {
uint32_t h = _rava_class_hash(class_name);
int idx = vm->class_hash[h];
if (idx >= 0 && (size_t)idx < vm->program->class_count &&
strcmp(vm->program->classes[idx]->name, class_name) == 0) {
return vm->program->classes[idx];
}
for (size_t i = 0; i < vm->program->class_count; i++) {
if (strcmp(vm->program->classes[i]->name, class_name) == 0) {
vm->class_hash[h] = (int)i;
return vm->program->classes[i];
}
}
return NULL;
}
2025-12-09 20:47:28 +01:00
bool _rava_vm_instanceof(RavaVM_t *vm, const char *object_class, const char *target_class) {
if (!object_class || !target_class) return false;
if (strcmp(object_class, target_class) == 0) return true;
const char *current = object_class;
while (current) {
RavaClass_t *cls = _rava_vm_find_class(vm, current);
if (!cls) break;
if (cls->superclass && strcmp(cls->superclass, target_class) == 0) return true;
current = cls->superclass;
}
return false;
}
2025-12-09 15:09:16 +01:00
static bool _rava_vm_method_signature_matches(RavaMethod_t *method, RavaValue_t *args, size_t arg_count) {
if (!method) return false;
if (method->param_count != arg_count) return false;
for (size_t i = 0; i < arg_count; i++) {
RavaValue_t arg = args[i];
RavaType_t *param_type = method->param_types[i];
RavaType_t *arg_type = NULL;
switch (arg.type) {
case RAVA_VAL_INT:
arg_type = rava_type_create_primitive(RAVA_TYPE_INT);
break;
case RAVA_VAL_LONG:
arg_type = rava_type_create_primitive(RAVA_TYPE_LONG);
break;
case RAVA_VAL_DOUBLE:
arg_type = rava_type_create_primitive(RAVA_TYPE_DOUBLE);
break;
case RAVA_VAL_FLOAT:
arg_type = rava_type_create_primitive(RAVA_TYPE_FLOAT);
break;
case RAVA_VAL_BOOLEAN:
arg_type = rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
break;
case RAVA_VAL_CHAR:
arg_type = rava_type_create_primitive(RAVA_TYPE_CHAR);
break;
case RAVA_VAL_OBJECT:
case RAVA_VAL_STRING:
case RAVA_VAL_ARRAY:
arg_type = rava_type_create_primitive(RAVA_TYPE_CLASS);
break;
default:
arg_type = NULL;
break;
}
bool assignable = arg_type && rava_type_is_assignable_to(arg_type, param_type);
if (arg_type && arg_type->kind != RAVA_TYPE_CLASS) {
rava_type_destroy(arg_type);
}
if (!assignable) return false;
}
return true;
}
2025-12-07 16:31:49 +01:00
RavaMethod_t* _rava_vm_find_method(RavaVM_t *vm, const char *class_name, const char *method_name) {
const char *current_class = class_name;
while (current_class) {
RavaClass_t *class = _rava_vm_find_class(vm, current_class);
if (!class) break;
uint32_t h = _rava_method_hash(method_name);
int idx = class->method_hash[h];
if (idx >= 0 && (size_t)idx < class->method_count &&
strcmp(class->methods[idx]->name, method_name) == 0) {
return class->methods[idx];
}
for (size_t j = 0; j < class->method_count; j++) {
if (strcmp(class->methods[j]->name, method_name) == 0) {
class->method_hash[h] = (int)j;
return class->methods[j];
}
}
current_class = class->superclass;
}
return NULL;
}
2025-12-09 15:09:16 +01:00
RavaMethod_t* _rava_vm_find_method_overload(RavaVM_t *vm, const char *class_name, const char *method_name, RavaValue_t *args, size_t arg_count) {
const char *current_class = class_name;
while (current_class) {
RavaClass_t *class = _rava_vm_find_class(vm, current_class);
if (!class) break;
RavaMethod_t *best_match = NULL;
for (size_t j = 0; j < class->method_count; j++) {
if (strcmp(class->methods[j]->name, method_name) == 0) {
if (_rava_vm_method_signature_matches(class->methods[j], args, arg_count)) {
best_match = class->methods[j];
break;
}
}
}
if (best_match) return best_match;
current_class = class->superclass;
}
return NULL;
}
2025-12-07 16:31:49 +01:00
RavaMethod_t* _rava_vm_find_method_cached(RavaVM_t *vm, const char *class_name, const char *method_name) {
MethodCache_t *cache = (MethodCache_t*)vm->method_cache;
RavaMethod_t *cached = rava_methodcache_lookup(cache, class_name, method_name);
if (cached) return cached;
RavaMethod_t *method = _rava_vm_find_method(vm, class_name, method_name);
if (method) {
rava_methodcache_insert(cache, class_name, method_name, method);
}
return method;
}
2025-12-09 19:41:05 +01:00
RavaMethod_t* _rava_vm_find_method_overload_nb(RavaVM_t *vm, const char *class_name, const char *method_name, RavaNanboxValue_t *args, size_t arg_count) {
if (arg_count == 0) {
return _rava_vm_find_method_overload(vm, class_name, method_name, NULL, 0);
}
RavaValue_t converted_args[16];
size_t count = arg_count > 16 ? 16 : arg_count;
for (size_t i = 0; i < count; i++) {
converted_args[i] = rava_nanbox_to_value(args[i]);
}
return _rava_vm_find_method_overload(vm, class_name, method_name, converted_args, count);
}