#pragma once #include #include #include typedef enum { GC_BLACK, GC_GREY, GC_WHITE, } js_gc_state_t; typedef struct { // Whether the node is a root bool root; } js_gc_data_t; typedef enum { JS_GC_OBJECT, JS_GC_STRING, JS_GC_CAPTURE, JS_GC_FRAME, } js_gc_node_type_t; typedef struct { js_gc_data_t *data; void *ptr; js_gc_node_type_t type; } js_gc_node_t; typedef struct js_gc_table_node { struct js_gc_table_node *next; js_gc_node_t node; } js_gc_table_node_t; typedef struct { size_t cap, n; js_gc_table_node_t **buckets; } js_gc_table_t; typedef struct { void **prev_ref; js_gc_node_t node; } js_gc_task_node_t; typedef struct { size_t cap, n; js_gc_task_node_t *tasks; } js_gc_task_stack_t; void js_gc_stack_push(js_gc_task_stack_t *stack, js_gc_task_node_t task); bool js_gc_stack_pop(js_gc_task_stack_t *stack, js_gc_task_node_t *pout); static void js_gc_dryrun_table(js_gc_task_stack_t *stack, void **ref, js_ctx_t obj); static void js_gc_reclaim_table(js_gc_task_stack_t *stack, void **ref, js_ctx_t obj);