#include "gc_roots.h"
#include "gc_mark.h"
#include "../runtime.h"
#include "../fastframe.h"
#include "../nanbox.h"
void rava_gc_mark_value(RavaValue_t value) {
switch (value.type) {
case RAVA_VAL_OBJECT:
if (value.data.object_val) {
rava_gc_mark_object(&value.data.object_val->gc);
}
break;
case RAVA_VAL_ARRAY:
if (value.data.array_val) {
rava_gc_mark_object(&value.data.array_val->gc);
}
break;
case RAVA_VAL_ARRAYLIST:
if (value.data.arraylist_val) {
rava_gc_mark_object(&value.data.arraylist_val->gc);
}
break;
case RAVA_VAL_HASHMAP:
if (value.data.hashmap_val) {
rava_gc_mark_object(&value.data.hashmap_val->gc);
}
break;
case RAVA_VAL_SOCKET:
if (value.data.socket_val) {
rava_gc_mark_object(&value.data.socket_val->gc);
}
break;
case RAVA_VAL_STREAM:
if (value.data.stream_val) {
rava_gc_mark_object(&value.data.stream_val->gc);
}
break;
case RAVA_VAL_METHOD_REF:
if (value.data.method_ref_val) {
rava_gc_mark_object(&value.data.method_ref_val->gc);
}
break;
default:
break;
}
}
void rava_gc_mark_nanbox(uint64_t v) {
if (rava_nanbox_is_object(v)) {
void *ptr = rava_nanbox_as_object(v);
if (ptr) {
RavaObject_t *obj = (RavaObject_t*)ptr;
rava_gc_mark_object(&obj->gc);
}
} else if (rava_nanbox_is_array(v)) {
void *ptr = rava_nanbox_as_array(v);
if (ptr) {
RavaArray_t *arr = (RavaArray_t*)ptr;
rava_gc_mark_object(&arr->gc);
}
}
}
void rava_gc_mark_string(const char *str) {
(void)str;
}
void rava_gc_scan_roots(RavaVM_t *vm) {
if (!vm) return;
if (vm->call_stack) {
for (size_t i = 0; i < vm->call_stack->count; i++) {
RavaCallFrame_t *frame = vm->call_stack->frames[i];
if (!frame) continue;
for (size_t j = 0; j < frame->local_count; j++) {
rava_gc_mark_value(frame->locals[j]);
}
if (frame->operand_stack) {
for (size_t j = 0; j < frame->operand_stack->top; j++) {
rava_gc_mark_value(frame->operand_stack->values[j]);
}
}
if (frame->has_this) {
rava_gc_mark_value(frame->this_ref);
}
}
}
extern size_t rava_frame_depth;
extern FastFrame_t rava_frame_pool[];
for (size_t i = 0; i < rava_frame_depth; i++) {
FastFrame_t *frame = &rava_frame_pool[i];
for (size_t j = 0; j < RAVA_MAX_LOCALS_FIXED; j++) {
rava_gc_mark_nanbox(frame->locals[j]);
}
for (size_t j = 0; j < frame->stack_top; j++) {
rava_gc_mark_nanbox(frame->stack[j]);
}
if (frame->has_this) {
rava_gc_mark_nanbox(frame->this_ref);
}
}
if (vm->static_fields) {
for (size_t i = 0; i < vm->static_fields->count; i++) {
rava_gc_mark_value(vm->static_fields->fields[i].value);
}
}
for (size_t i = 0; i < RAVA_INTERN_TABLE_SIZE; i++) {
if (vm->intern_table.strings[i]) {
rava_gc_mark_string(vm->intern_table.strings[i]);
}
}
if (vm->has_exception) {
rava_gc_mark_value(vm->exception_value);
}
}