diff --git a/runtime/runtime.c b/runtime/runtime.c index 36ba247..2276bd2 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -2730,7 +2730,7 @@ op_instanceof: { RavaValue_t val = STACK_POP(stack); bool result = false; if (val.type == RAVA_VAL_OBJECT && val.data.object_val) { - result = strcmp(val.data.object_val->class_name, instr->operand.string_value) == 0; + result = _rava_vm_instanceof(vm, val.data.object_val->class_name, instr->operand.string_value); } STACK_PUSH(stack, rava_value_boolean(result)); DISPATCH(); @@ -4364,7 +4364,7 @@ uf_instanceof: { if (rava_nanbox_is_object(val)) { RavaObject_t *obj = rava_nanbox_as_object(val); if (obj) { - result = strcmp(obj->class_name, instr->operand.string_value) == 0; + result = _rava_vm_instanceof(vm, obj->class_name, instr->operand.string_value); } } UF_PUSH(rava_nanbox_bool(result)); diff --git a/runtime/runtime_internal.h b/runtime/runtime_internal.h index 3da58a3..c0c56e1 100644 --- a/runtime/runtime_internal.h +++ b/runtime/runtime_internal.h @@ -151,6 +151,7 @@ const char* _rava_intern_string(RavaVM_t *vm, const char *str); void _rava_object_set_field_vm(RavaObject_t *obj, const char *name, RavaValue_t value, RavaVM_t *vm); RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name); +bool _rava_vm_instanceof(RavaVM_t *vm, const char *object_class, const char *target_class); RavaMethod_t* _rava_vm_find_method(RavaVM_t *vm, const char *class_name, const char *method_name); RavaMethod_t* _rava_vm_find_method_cached(RavaVM_t *vm, const char *class_name, const char *method_name); 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); diff --git a/runtime/runtime_lookup.c b/runtime/runtime_lookup.c index cbe8d3e..9eef3e6 100644 --- a/runtime/runtime_lookup.c +++ b/runtime/runtime_lookup.c @@ -19,6 +19,19 @@ RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name) { return NULL; } +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; +} + 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;