This commit is contained in:
retoor 2025-12-05 01:12:25 +01:00
parent de7f824feb
commit e33fa20c60
8 changed files with 121 additions and 29 deletions

View File

@ -17,7 +17,10 @@ SEMANTIC_OBJECTS = $(SEMANTIC_SOURCES:.c=.o)
IR_SOURCES = ir/ir.c ir/ir_gen.c IR_SOURCES = ir/ir.c ir/ir_gen.c
IR_OBJECTS = $(IR_SOURCES:.c=.o) IR_OBJECTS = $(IR_SOURCES:.c=.o)
RUNTIME_SOURCES = runtime/runtime.c runtime/runtime_array.c runtime/runtime_object.c runtime/runtime_collections.c runtime/runtime_socket.c runtime/runtime_method_ref.c runtime/labeltable.c runtime/methodcache.c runtime/fastframe.c runtime/superinst.c GC_SOURCES = runtime/gc/gc.c runtime/gc/gc_heap.c runtime/gc/gc_mark.c runtime/gc/gc_sweep.c runtime/gc/gc_roots.c
GC_OBJECTS = $(GC_SOURCES:.c=.o)
RUNTIME_SOURCES = runtime/runtime.c runtime/runtime_array.c runtime/runtime_object.c runtime/runtime_collections.c runtime/runtime_socket.c runtime/runtime_method_ref.c runtime/labeltable.c runtime/methodcache.c runtime/fastframe.c runtime/superinst.c $(GC_SOURCES)
RUNTIME_OBJECTS = $(RUNTIME_SOURCES:.c=.o) RUNTIME_OBJECTS = $(RUNTIME_SOURCES:.c=.o)
LOADER_SOURCES = loader/loader.c LOADER_SOURCES = loader/loader.c
@ -143,6 +146,9 @@ TEST_SOCKETS_OBJECTS = $(TEST_SOCKETS_SOURCES:.c=.o)
TEST_METHOD_REF_SOURCES = tests/test_method_ref.c TEST_METHOD_REF_SOURCES = tests/test_method_ref.c
TEST_METHOD_REF_OBJECTS = $(TEST_METHOD_REF_SOURCES:.c=.o) TEST_METHOD_REF_OBJECTS = $(TEST_METHOD_REF_SOURCES:.c=.o)
TEST_GC_SOURCES = tests/test_gc.c
TEST_GC_OBJECTS = $(TEST_GC_SOURCES:.c=.o)
UNITTEST_SOURCES = tests/unittest.c UNITTEST_SOURCES = tests/unittest.c
UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o) UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o)
@ -268,6 +274,9 @@ test_sockets: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJ
test_method_ref: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_METHOD_REF_OBJECTS) test_method_ref: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_METHOD_REF_OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
test_gc: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_GC_OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
test_unittest_demo: $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) test_unittest_demo: $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

View File

@ -496,7 +496,14 @@ static inline uint32_t _rava_class_hash(const char *name) {
return hash & (RAVA_CLASS_HASH_SIZE - 1); return hash & (RAVA_CLASS_HASH_SIZE - 1);
} }
static bool g_gc_initialized = false;
RavaVM_t* rava_vm_create(RavaProgram_t *program) { RavaVM_t* rava_vm_create(RavaProgram_t *program) {
if (!g_gc_initialized) {
rava_gc_init();
g_gc_initialized = true;
}
RavaVM_t *vm = calloc(1, sizeof(RavaVM_t)); RavaVM_t *vm = calloc(1, sizeof(RavaVM_t));
if (!vm) return NULL; if (!vm) return NULL;
vm->program = program; vm->program = program;
@ -522,6 +529,8 @@ RavaVM_t* rava_vm_create(RavaProgram_t *program) {
vm->class_hash[h] = (int)i; vm->class_hash[h] = (int)i;
} }
rava_gc_set_vm(vm);
return vm; return vm;
} }
@ -4712,10 +4721,10 @@ uf_arraylist_size: {
RavaNanboxValue_t coll_nb = UF_POP(); RavaNanboxValue_t coll_nb = UF_POP();
void *ptr = rava_nanbox_as_object(coll_nb); void *ptr = rava_nanbox_as_object(coll_nb);
if (ptr) { if (ptr) {
int type = *(int*)ptr; uint8_t gc_type = ((RavaGCHeader_t*)ptr)->gc_type;
if (type == RAVA_COLLECTION_ARRAYLIST) { if (gc_type == RAVA_GC_TYPE_ARRAYLIST) {
UF_PUSH(rava_nanbox_int((int32_t)rava_arraylist_size((RavaArrayList_t*)ptr))); UF_PUSH(rava_nanbox_int((int32_t)rava_arraylist_size((RavaArrayList_t*)ptr)));
} else if (type == RAVA_COLLECTION_HASHMAP) { } else if (gc_type == RAVA_GC_TYPE_HASHMAP) {
UF_PUSH(rava_nanbox_int((int32_t)rava_hashmap_size((RavaHashMap_t*)ptr))); UF_PUSH(rava_nanbox_int((int32_t)rava_hashmap_size((RavaHashMap_t*)ptr)));
} else { } else {
UF_PUSH(rava_nanbox_int(0)); UF_PUSH(rava_nanbox_int(0));
@ -4731,15 +4740,15 @@ uf_arraylist_remove: {
RavaNanboxValue_t coll_nb = UF_POP(); RavaNanboxValue_t coll_nb = UF_POP();
void *ptr = rava_nanbox_as_object(coll_nb); void *ptr = rava_nanbox_as_object(coll_nb);
if (ptr) { if (ptr) {
int type = *(int*)ptr; uint8_t gc_type = ((RavaGCHeader_t*)ptr)->gc_type;
if (type == RAVA_COLLECTION_ARRAYLIST && rava_nanbox_is_int(idx_or_key)) { if (gc_type == RAVA_GC_TYPE_ARRAYLIST && rava_nanbox_is_int(idx_or_key)) {
RavaValue_t v = rava_arraylist_remove((RavaArrayList_t*)ptr, (size_t)rava_nanbox_to_int(idx_or_key)); RavaValue_t v = rava_arraylist_remove((RavaArrayList_t*)ptr, (size_t)rava_nanbox_to_int(idx_or_key));
if (v.type == RAVA_VAL_INT) { if (v.type == RAVA_VAL_INT) {
UF_PUSH(rava_nanbox_int(v.data.int_val)); UF_PUSH(rava_nanbox_int(v.data.int_val));
} else { } else {
UF_PUSH(rava_nanbox_null()); UF_PUSH(rava_nanbox_null());
} }
} else if (type == RAVA_COLLECTION_HASHMAP && rava_nanbox_is_string(idx_or_key)) { } else if (gc_type == RAVA_GC_TYPE_HASHMAP && rava_nanbox_is_string(idx_or_key)) {
RavaValue_t v = rava_hashmap_remove((RavaHashMap_t*)ptr, rava_nanbox_as_string(idx_or_key)); RavaValue_t v = rava_hashmap_remove((RavaHashMap_t*)ptr, rava_nanbox_as_string(idx_or_key));
if (v.type == RAVA_VAL_INT) { if (v.type == RAVA_VAL_INT) {
UF_PUSH(rava_nanbox_int(v.data.int_val)); UF_PUSH(rava_nanbox_int(v.data.int_val));
@ -4759,10 +4768,10 @@ uf_arraylist_clear: {
RavaNanboxValue_t coll_nb = UF_POP(); RavaNanboxValue_t coll_nb = UF_POP();
void *ptr = rava_nanbox_as_object(coll_nb); void *ptr = rava_nanbox_as_object(coll_nb);
if (ptr) { if (ptr) {
int type = *(int*)ptr; uint8_t gc_type = ((RavaGCHeader_t*)ptr)->gc_type;
if (type == RAVA_COLLECTION_ARRAYLIST) { if (gc_type == RAVA_GC_TYPE_ARRAYLIST) {
rava_arraylist_clear((RavaArrayList_t*)ptr); rava_arraylist_clear((RavaArrayList_t*)ptr);
} else if (type == RAVA_COLLECTION_HASHMAP) { } else if (gc_type == RAVA_GC_TYPE_HASHMAP) {
rava_hashmap_clear((RavaHashMap_t*)ptr); rava_hashmap_clear((RavaHashMap_t*)ptr);
} }
} }

View File

@ -8,6 +8,15 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
typedef struct RavaGCHeader {
uint8_t gc_type;
uint8_t gc_mark;
uint8_t gc_age;
uint8_t gc_flags;
uint32_t gc_size;
struct RavaGCHeader *gc_next;
} RavaGCHeader_t;
typedef enum { typedef enum {
RAVA_VAL_INT, RAVA_VAL_INT,
RAVA_VAL_LONG, RAVA_VAL_LONG,
@ -27,6 +36,7 @@ typedef enum {
} RavaValueType_e; } RavaValueType_e;
typedef struct { typedef struct {
RavaGCHeader_t gc;
RavaValueType_e element_type; RavaValueType_e element_type;
size_t length; size_t length;
void *data; void *data;
@ -43,6 +53,7 @@ typedef struct RavaMethodRef_t RavaMethodRef_t;
#define RAVA_OBJECT_HASH_SIZE 32 #define RAVA_OBJECT_HASH_SIZE 32
struct RavaObject_t { struct RavaObject_t {
RavaGCHeader_t gc;
char *class_name; char *class_name;
char **field_names; char **field_names;
RavaValue_t *field_values; RavaValue_t *field_values;
@ -75,6 +86,7 @@ struct RavaValue_t {
#define RAVA_COLLECTION_HASHMAP 2 #define RAVA_COLLECTION_HASHMAP 2
struct RavaArrayList_t { struct RavaArrayList_t {
RavaGCHeader_t gc;
int collection_type; int collection_type;
RavaValue_t *data; RavaValue_t *data;
size_t size; size_t size;
@ -90,6 +102,7 @@ typedef struct {
} RavaHashMapEntry_t; } RavaHashMapEntry_t;
struct RavaHashMap_t { struct RavaHashMap_t {
RavaGCHeader_t gc;
int collection_type; int collection_type;
RavaHashMapEntry_t *buckets; RavaHashMapEntry_t *buckets;
size_t bucket_count; size_t bucket_count;
@ -100,6 +113,7 @@ struct RavaHashMap_t {
#define RAVA_SOCKET_TYPE_SERVER 2 #define RAVA_SOCKET_TYPE_SERVER 2
struct RavaSocket_t { struct RavaSocket_t {
RavaGCHeader_t gc;
int socket_type; int socket_type;
int fd; int fd;
bool connected; bool connected;
@ -110,12 +124,14 @@ struct RavaSocket_t {
#define RAVA_STREAM_TYPE_OUTPUT 2 #define RAVA_STREAM_TYPE_OUTPUT 2
struct RavaStream_t { struct RavaStream_t {
RavaGCHeader_t gc;
int stream_type; int stream_type;
int fd; int fd;
bool closed; bool closed;
}; };
struct RavaMethodRef_t { struct RavaMethodRef_t {
RavaGCHeader_t gc;
char *class_name; char *class_name;
char *method_name; char *method_name;
bool is_constructor; bool is_constructor;
@ -406,4 +422,29 @@ RavaValue_t rava_vm_call_native(RavaVM_t *vm, const char *class_name, const char
RavaNativeValue_t rava_value_to_native(RavaValue_t value); RavaNativeValue_t rava_value_to_native(RavaValue_t value);
RavaValue_t rava_native_to_value(RavaNativeValue_t native); RavaValue_t rava_native_to_value(RavaNativeValue_t native);
#define RAVA_GC_WHITE 0
#define RAVA_GC_GRAY 1
#define RAVA_GC_BLACK 2
#define RAVA_GC_FLAG_PINNED 0x01
#define RAVA_GC_FLAG_FINALIZER 0x02
#define RAVA_GC_TYPE_OBJECT 1
#define RAVA_GC_TYPE_ARRAY 2
#define RAVA_GC_TYPE_ARRAYLIST 3
#define RAVA_GC_TYPE_HASHMAP 4
#define RAVA_GC_TYPE_STRING 5
#define RAVA_GC_TYPE_SOCKET 6
#define RAVA_GC_TYPE_STREAM 7
#define RAVA_GC_TYPE_METHODREF 8
void rava_gc_init(void);
void rava_gc_shutdown(void);
void rava_gc_set_vm(RavaVM_t *vm);
void* rava_gc_alloc(size_t size, uint8_t type);
void rava_gc_collect(void);
void rava_gc_collect_if_needed(void);
void rava_gc_enable(void);
void rava_gc_disable(void);
#endif #endif

View File

@ -1,7 +1,9 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include "runtime.h" #include "runtime.h"
#include "gc/gc.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#define RAVA_MAX_ARRAY_LENGTH 1000000 #define RAVA_MAX_ARRAY_LENGTH 1000000
@ -12,9 +14,11 @@ RavaArray_t* rava_array_create(RavaValueType_e element_type, size_t length) {
length = RAVA_MAX_ARRAY_LENGTH; length = RAVA_MAX_ARRAY_LENGTH;
} }
RavaArray_t *array = malloc(sizeof(RavaArray_t)); RavaArray_t *array = rava_gc_alloc(sizeof(RavaArray_t), RAVA_GC_TYPE_ARRAY);
if (!array) return NULL; if (!array) return NULL;
memset((char*)array + sizeof(RavaGCHeader_t), 0, sizeof(RavaArray_t) - sizeof(RavaGCHeader_t));
array->element_type = element_type; array->element_type = element_type;
array->length = length; array->length = length;
array->data = NULL; array->data = NULL;
@ -42,7 +46,6 @@ RavaArray_t* rava_array_create(RavaValueType_e element_type, size_t length) {
} }
if (!array->data && length > 0) { if (!array->data && length > 0) {
free(array);
return NULL; return NULL;
} }
@ -52,7 +55,6 @@ RavaArray_t* rava_array_create(RavaValueType_e element_type, size_t length) {
void rava_array_destroy(RavaArray_t *array) { void rava_array_destroy(RavaArray_t *array) {
if (!array) return; if (!array) return;
free(array->data); free(array->data);
free(array);
} }
void rava_array_set_int(RavaArray_t *array, size_t index, int32_t value) { void rava_array_set_int(RavaArray_t *array, size_t index, int32_t value) {

View File

@ -1,12 +1,17 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include "runtime.h" #include "runtime.h"
#include "gc/gc.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define ARRAYLIST_INITIAL_CAPACITY 16 #define ARRAYLIST_INITIAL_CAPACITY 16
RavaArrayList_t* rava_arraylist_create(void) { RavaArrayList_t* rava_arraylist_create(void) {
RavaArrayList_t *list = calloc(1, sizeof(RavaArrayList_t)); RavaArrayList_t *list = rava_gc_alloc(sizeof(RavaArrayList_t), RAVA_GC_TYPE_ARRAYLIST);
if (!list) return NULL;
memset((char*)list + sizeof(RavaGCHeader_t), 0, sizeof(RavaArrayList_t) - sizeof(RavaGCHeader_t));
list->collection_type = RAVA_COLLECTION_ARRAYLIST; list->collection_type = RAVA_COLLECTION_ARRAYLIST;
list->data = calloc(ARRAYLIST_INITIAL_CAPACITY, sizeof(RavaValue_t)); list->data = calloc(ARRAYLIST_INITIAL_CAPACITY, sizeof(RavaValue_t));
list->size = 0; list->size = 0;
@ -17,7 +22,6 @@ RavaArrayList_t* rava_arraylist_create(void) {
void rava_arraylist_destroy(RavaArrayList_t *list) { void rava_arraylist_destroy(RavaArrayList_t *list) {
if (!list) return; if (!list) return;
free(list->data); free(list->data);
free(list);
} }
void rava_arraylist_add(RavaArrayList_t *list, RavaValue_t value) { void rava_arraylist_add(RavaArrayList_t *list, RavaValue_t value) {
@ -75,7 +79,11 @@ static unsigned int _rava_hash_string(const char *str) {
} }
RavaHashMap_t* rava_hashmap_create(void) { RavaHashMap_t* rava_hashmap_create(void) {
RavaHashMap_t *map = calloc(1, sizeof(RavaHashMap_t)); RavaHashMap_t *map = rava_gc_alloc(sizeof(RavaHashMap_t), RAVA_GC_TYPE_HASHMAP);
if (!map) return NULL;
memset((char*)map + sizeof(RavaGCHeader_t), 0, sizeof(RavaHashMap_t) - sizeof(RavaGCHeader_t));
map->collection_type = RAVA_COLLECTION_HASHMAP; map->collection_type = RAVA_COLLECTION_HASHMAP;
map->bucket_count = RAVA_HASHMAP_BUCKET_SIZE; map->bucket_count = RAVA_HASHMAP_BUCKET_SIZE;
map->buckets = calloc(map->bucket_count, sizeof(RavaHashMapEntry_t)); map->buckets = calloc(map->bucket_count, sizeof(RavaHashMapEntry_t));
@ -91,7 +99,6 @@ void rava_hashmap_destroy(RavaHashMap_t *map) {
} }
} }
free(map->buckets); free(map->buckets);
free(map);
} }
static void _rava_hashmap_resize(RavaHashMap_t *map) { static void _rava_hashmap_resize(RavaHashMap_t *map) {

View File

@ -1,11 +1,14 @@
#include "runtime.h" #include "runtime.h"
#include "gc/gc.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
RavaMethodRef_t* rava_method_ref_create(const char *class_name, const char *method_name, bool is_constructor, bool is_static) { RavaMethodRef_t* rava_method_ref_create(const char *class_name, const char *method_name, bool is_constructor, bool is_static) {
RavaMethodRef_t *ref = calloc(1, sizeof(RavaMethodRef_t)); RavaMethodRef_t *ref = rava_gc_alloc(sizeof(RavaMethodRef_t), RAVA_GC_TYPE_METHODREF);
if (!ref) return NULL; if (!ref) return NULL;
memset((char*)ref + sizeof(RavaGCHeader_t), 0, sizeof(RavaMethodRef_t) - sizeof(RavaGCHeader_t));
ref->class_name = class_name ? strdup(class_name) : NULL; ref->class_name = class_name ? strdup(class_name) : NULL;
ref->method_name = method_name ? strdup(method_name) : NULL; ref->method_name = method_name ? strdup(method_name) : NULL;
ref->is_constructor = is_constructor; ref->is_constructor = is_constructor;
@ -19,5 +22,4 @@ void rava_method_ref_destroy(RavaMethodRef_t *ref) {
if (!ref) return; if (!ref) return;
free(ref->class_name); free(ref->class_name);
free(ref->method_name); free(ref->method_name);
free(ref);
} }

View File

@ -1,5 +1,7 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include "runtime.h" #include "runtime.h"
#include "gc/gc.h"
#include "gc/gc_heap.h"
#include "../utils/safe_alloc.h" #include "../utils/safe_alloc.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -15,8 +17,11 @@ static inline uint32_t _rava_field_hash(const char *name) {
} }
RavaObject_t* rava_object_create(const char *class_name) { RavaObject_t* rava_object_create(const char *class_name) {
RavaObject_t *obj = calloc(1, sizeof(RavaObject_t)); RavaObject_t *obj = rava_gc_alloc(sizeof(RavaObject_t), RAVA_GC_TYPE_OBJECT);
if (!obj) return NULL; if (!obj) return NULL;
memset((char*)obj + sizeof(RavaGCHeader_t), 0, sizeof(RavaObject_t) - sizeof(RavaGCHeader_t));
obj->class_name = strdup(class_name); obj->class_name = strdup(class_name);
obj->field_capacity = 8; obj->field_capacity = 8;
obj->field_names = calloc(obj->field_capacity, sizeof(char*)); obj->field_names = calloc(obj->field_capacity, sizeof(char*));
@ -25,7 +30,6 @@ RavaObject_t* rava_object_create(const char *class_name) {
free(obj->field_names); free(obj->field_names);
free(obj->field_values); free(obj->field_values);
free(obj->class_name); free(obj->class_name);
free(obj);
return NULL; return NULL;
} }
obj->field_count = 0; obj->field_count = 0;
@ -43,7 +47,6 @@ void rava_object_destroy(RavaObject_t *obj) {
} }
free(obj->field_names); free(obj->field_names);
free(obj->field_values); free(obj->field_values);
free(obj);
} }
void rava_object_set_field(RavaObject_t *obj, const char *name, RavaValue_t value) { void rava_object_set_field(RavaObject_t *obj, const char *name, RavaValue_t value) {

View File

@ -1,5 +1,6 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include "runtime.h" #include "runtime.h"
#include "gc/gc.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -10,7 +11,11 @@
#include <errno.h> #include <errno.h>
RavaSocket_t* rava_socket_create(void) { RavaSocket_t* rava_socket_create(void) {
RavaSocket_t *sock = calloc(1, sizeof(RavaSocket_t)); RavaSocket_t *sock = rava_gc_alloc(sizeof(RavaSocket_t), RAVA_GC_TYPE_SOCKET);
if (!sock) return NULL;
memset((char*)sock + sizeof(RavaGCHeader_t), 0, sizeof(RavaSocket_t) - sizeof(RavaGCHeader_t));
sock->socket_type = RAVA_SOCKET_TYPE_CLIENT; sock->socket_type = RAVA_SOCKET_TYPE_CLIENT;
sock->fd = socket(AF_INET, SOCK_STREAM, 0); sock->fd = socket(AF_INET, SOCK_STREAM, 0);
sock->connected = false; sock->connected = false;
@ -20,6 +25,7 @@ RavaSocket_t* rava_socket_create(void) {
RavaSocket_t* rava_socket_create_connected(const char *host, int port) { RavaSocket_t* rava_socket_create_connected(const char *host, int port) {
RavaSocket_t *sock = rava_socket_create(); RavaSocket_t *sock = rava_socket_create();
if (!sock) return NULL;
if (sock->fd < 0) return sock; if (sock->fd < 0) return sock;
if (rava_socket_connect(sock, host, port)) { if (rava_socket_connect(sock, host, port)) {
@ -29,7 +35,11 @@ RavaSocket_t* rava_socket_create_connected(const char *host, int port) {
} }
RavaSocket_t* rava_server_socket_create(int port) { RavaSocket_t* rava_server_socket_create(int port) {
RavaSocket_t *sock = calloc(1, sizeof(RavaSocket_t)); RavaSocket_t *sock = rava_gc_alloc(sizeof(RavaSocket_t), RAVA_GC_TYPE_SOCKET);
if (!sock) return NULL;
memset((char*)sock + sizeof(RavaGCHeader_t), 0, sizeof(RavaSocket_t) - sizeof(RavaGCHeader_t));
sock->socket_type = RAVA_SOCKET_TYPE_SERVER; sock->socket_type = RAVA_SOCKET_TYPE_SERVER;
sock->fd = socket(AF_INET, SOCK_STREAM, 0); sock->fd = socket(AF_INET, SOCK_STREAM, 0);
sock->connected = false; sock->connected = false;
@ -66,7 +76,6 @@ void rava_socket_destroy(RavaSocket_t *socket) {
if (!socket->closed && socket->fd >= 0) { if (!socket->closed && socket->fd >= 0) {
close(socket->fd); close(socket->fd);
} }
free(socket);
} }
bool rava_socket_connect(RavaSocket_t *socket, const char *host, int port) { bool rava_socket_connect(RavaSocket_t *socket, const char *host, int port) {
@ -100,7 +109,14 @@ RavaSocket_t* rava_server_socket_accept(RavaSocket_t *server) {
int client_fd = accept(server->fd, (struct sockaddr*)&client_addr, &client_len); int client_fd = accept(server->fd, (struct sockaddr*)&client_addr, &client_len);
if (client_fd < 0) return NULL; if (client_fd < 0) return NULL;
RavaSocket_t *client = calloc(1, sizeof(RavaSocket_t)); RavaSocket_t *client = rava_gc_alloc(sizeof(RavaSocket_t), RAVA_GC_TYPE_SOCKET);
if (!client) {
close(client_fd);
return NULL;
}
memset((char*)client + sizeof(RavaGCHeader_t), 0, sizeof(RavaSocket_t) - sizeof(RavaGCHeader_t));
client->socket_type = RAVA_SOCKET_TYPE_CLIENT; client->socket_type = RAVA_SOCKET_TYPE_CLIENT;
client->fd = client_fd; client->fd = client_fd;
client->connected = true; client->connected = true;
@ -129,7 +145,11 @@ void rava_socket_close(RavaSocket_t *socket) {
} }
RavaStream_t* rava_stream_create(int fd, int stream_type) { RavaStream_t* rava_stream_create(int fd, int stream_type) {
RavaStream_t *stream = calloc(1, sizeof(RavaStream_t)); RavaStream_t *stream = rava_gc_alloc(sizeof(RavaStream_t), RAVA_GC_TYPE_STREAM);
if (!stream) return NULL;
memset((char*)stream + sizeof(RavaGCHeader_t), 0, sizeof(RavaStream_t) - sizeof(RavaGCHeader_t));
stream->stream_type = stream_type; stream->stream_type = stream_type;
stream->fd = fd; stream->fd = fd;
stream->closed = false; stream->closed = false;
@ -137,8 +157,7 @@ RavaStream_t* rava_stream_create(int fd, int stream_type) {
} }
void rava_stream_destroy(RavaStream_t *stream) { void rava_stream_destroy(RavaStream_t *stream) {
if (!stream) return; (void)stream;
free(stream);
} }
char* rava_stream_read(RavaStream_t *stream) { char* rava_stream_read(RavaStream_t *stream) {