#ifndef RAVA_RUNTIME_H
#define RAVA_RUNTIME_H
#include "../ir/ir.h"
#include "../types/types.h"
#include "../loader/loader.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
typedef enum {
RAVA_VAL_INT,
RAVA_VAL_LONG,
RAVA_VAL_FLOAT,
RAVA_VAL_DOUBLE,
RAVA_VAL_BOOLEAN,
RAVA_VAL_CHAR,
RAVA_VAL_NULL,
RAVA_VAL_OBJECT,
RAVA_VAL_ARRAY,
RAVA_VAL_STRING,
RAVA_VAL_ARRAYLIST,
RAVA_VAL_HASHMAP,
RAVA_VAL_SOCKET,
RAVA_VAL_STREAM,
RAVA_VAL_METHOD_REF
} RavaValueType_e;
typedef struct {
RavaValueType_e element_type;
size_t length;
void *data;
} RavaArray_t;
typedef struct RavaObject_t RavaObject_t;
typedef struct RavaValue_t RavaValue_t;
typedef struct RavaArrayList_t RavaArrayList_t;
typedef struct RavaHashMap_t RavaHashMap_t;
typedef struct RavaSocket_t RavaSocket_t;
typedef struct RavaStream_t RavaStream_t;
typedef struct RavaMethodRef_t RavaMethodRef_t;
#define RAVA_OBJECT_HASH_SIZE 32
struct RavaObject_t {
char *class_name;
char **field_names;
RavaValue_t *field_values;
size_t field_count;
size_t field_capacity;
int field_hash[RAVA_OBJECT_HASH_SIZE];
};
struct RavaValue_t {
RavaValueType_e type;
union {
int32_t int_val;
int64_t long_val;
float float_val;
double double_val;
bool bool_val;
char char_val;
RavaObject_t *object_val;
RavaArray_t *array_val;
char *string_val;
RavaArrayList_t *arraylist_val;
RavaHashMap_t *hashmap_val;
RavaSocket_t *socket_val;
RavaStream_t *stream_val;
RavaMethodRef_t *method_ref_val;
} data;
};
#define RAVA_COLLECTION_ARRAYLIST 1
#define RAVA_COLLECTION_HASHMAP 2
struct RavaArrayList_t {
int collection_type;
RavaValue_t *data;
size_t size;
size_t capacity;
};
#define RAVA_HASHMAP_BUCKET_SIZE 32
typedef struct {
char *key;
RavaValue_t value;
bool occupied;
} RavaHashMapEntry_t;
struct RavaHashMap_t {
int collection_type;
RavaHashMapEntry_t *buckets;
size_t bucket_count;
size_t size;
};
#define RAVA_SOCKET_TYPE_CLIENT 1
#define RAVA_SOCKET_TYPE_SERVER 2
struct RavaSocket_t {
int socket_type;
int fd;
bool connected;
bool closed;
};
#define RAVA_STREAM_TYPE_INPUT 1
#define RAVA_STREAM_TYPE_OUTPUT 2
struct RavaStream_t {
int stream_type;
int fd;
bool closed;
};
struct RavaMethodRef_t {
char *class_name;
char *method_name;
bool is_constructor;
bool is_static;
RavaValue_t target;
bool has_target;
};
typedef struct {
RavaValue_t *values;
size_t capacity;
size_t top;
} RavaStack_t;
typedef struct {
RavaMethod_t *method;
RavaValue_t *locals;
size_t local_count;
size_t pc;
RavaStack_t *operand_stack;
RavaValue_t this_ref;
bool has_this;
} RavaCallFrame_t;
typedef struct {
RavaCallFrame_t **frames;
size_t capacity;
size_t count;
} RavaCallStack_t;
#define RAVA_STATIC_HASH_SIZE 128
typedef struct {
char *class_name;
char *field_name;
RavaValue_t value;
} RavaStaticField_t;
typedef struct {
RavaStaticField_t *fields;
size_t count;
size_t capacity;
int hash_table[RAVA_STATIC_HASH_SIZE];
} RavaStaticFieldTable_t;
struct MethodCache_s;
typedef struct {
int catch_label;
int finally_label;
int end_label;
int exception_local;
size_t stack_depth;
} RavaExceptionHandler_t;
#define RAVA_MAX_EXCEPTION_DEPTH 64
typedef struct {
RavaExceptionHandler_t handlers[RAVA_MAX_EXCEPTION_DEPTH];
size_t count;
} RavaExceptionStack_t;
#define RAVA_CLASS_HASH_SIZE 64
#define RAVA_STRING_BUFFER_SIZE 4096
#define RAVA_STRING_BUFFER_COUNT 4
typedef struct {
char buffers[RAVA_STRING_BUFFER_COUNT][RAVA_STRING_BUFFER_SIZE];
int current;
} RavaStringPool_t;
#define RAVA_INTERN_TABLE_SIZE 1024
typedef struct {
char *strings[RAVA_INTERN_TABLE_SIZE];
size_t count;
} RavaInternTable_t;
typedef struct {
RavaProgram_t *program;
RavaCallStack_t *call_stack;
RavaStaticFieldTable_t *static_fields;
struct MethodCache_s *method_cache;
RavaNativeRegistry_t *native_registry;
char *error_message;
bool had_error;
bool has_exception;
RavaValue_t exception_value;
RavaExceptionStack_t *exception_stack;
int class_hash[RAVA_CLASS_HASH_SIZE];
RavaStringPool_t string_pool;
RavaInternTable_t intern_table;
} RavaVM_t;
static inline RavaValue_t rava_value_int(int32_t value) {
RavaValue_t val;
val.type = RAVA_VAL_INT;
val.data.int_val = value;
return val;
}
static inline RavaValue_t rava_value_long(int64_t value) {
RavaValue_t val;
val.type = RAVA_VAL_LONG;
val.data.long_val = value;
return val;
}
static inline RavaValue_t rava_value_float(float value) {
RavaValue_t val;
val.type = RAVA_VAL_FLOAT;
val.data.float_val = value;
return val;
}
static inline RavaValue_t rava_value_double(double value) {
RavaValue_t val;
val.type = RAVA_VAL_DOUBLE;
val.data.double_val = value;
return val;
}
static inline RavaValue_t rava_value_boolean(bool value) {
RavaValue_t val;
val.type = RAVA_VAL_BOOLEAN;
val.data.bool_val = value;
return val;
}
static inline RavaValue_t rava_value_null(void) {
RavaValue_t val;
val.type = RAVA_VAL_NULL;
val.data.object_val = NULL;
return val;
}
static inline RavaValue_t rava_value_array(RavaArray_t *array) {
RavaValue_t val;
val.type = RAVA_VAL_ARRAY;
val.data.array_val = array;
return val;
}
static inline RavaValue_t rava_value_object(RavaObject_t *obj) {
RavaValue_t val;
val.type = RAVA_VAL_OBJECT;
val.data.object_val = obj;
return val;
}
static inline RavaValue_t rava_value_arraylist(RavaArrayList_t *list) {
RavaValue_t val;
val.type = RAVA_VAL_ARRAYLIST;
val.data.arraylist_val = list;
return val;
}
static inline RavaValue_t rava_value_hashmap(RavaHashMap_t *map) {
RavaValue_t val;
val.type = RAVA_VAL_HASHMAP;
val.data.hashmap_val = map;
return val;
}
RavaValue_t rava_value_string(const char *str);
int32_t rava_value_as_int(RavaValue_t value);
int64_t rava_value_as_long(RavaValue_t value);
double rava_value_as_double(RavaValue_t value);
bool rava_value_as_boolean(RavaValue_t value);
const char* rava_value_as_string(RavaValue_t value);
RavaArray_t* rava_array_create(RavaValueType_e element_type, size_t length);
void rava_array_destroy(RavaArray_t *array);
void rava_array_set_int(RavaArray_t *array, size_t index, int32_t value);
int32_t rava_array_get_int(RavaArray_t *array, size_t index);
void rava_array_set_long(RavaArray_t *array, size_t index, int64_t value);
int64_t rava_array_get_long(RavaArray_t *array, size_t index);
void rava_array_set_double(RavaArray_t *array, size_t index, double value);
double rava_array_get_double(RavaArray_t *array, size_t index);
void rava_array_set_value(RavaArray_t *array, size_t index, RavaValue_t value);
RavaValue_t rava_array_get_value(RavaArray_t *array, size_t index);
size_t rava_array_length(RavaArray_t *array);
RavaObject_t* rava_object_create(const char *class_name);
void rava_object_destroy(RavaObject_t *obj);
void rava_object_set_field(RavaObject_t *obj, const char *name, RavaValue_t value);
RavaValue_t rava_object_get_field(RavaObject_t *obj, const char *name);
int rava_object_get_field_index(RavaObject_t *obj, const char *name);
RavaValue_t rava_object_get_field_by_index(RavaObject_t *obj, int index);
void rava_object_set_field_by_index(RavaObject_t *obj, int index, RavaValue_t value);
int32_t rava_object_hashcode(RavaValue_t value);
bool rava_object_equals(RavaValue_t a, RavaValue_t b);
char* rava_object_tostring(RavaValue_t value);
const char* rava_object_getclass(RavaValue_t value);
RavaArrayList_t* rava_arraylist_create(void);
void rava_arraylist_destroy(RavaArrayList_t *list);
void rava_arraylist_add(RavaArrayList_t *list, RavaValue_t value);
RavaValue_t rava_arraylist_get(RavaArrayList_t *list, size_t index);
void rava_arraylist_set(RavaArrayList_t *list, size_t index, RavaValue_t value);
size_t rava_arraylist_size(RavaArrayList_t *list);
RavaValue_t rava_arraylist_remove(RavaArrayList_t *list, size_t index);
void rava_arraylist_clear(RavaArrayList_t *list);
bool rava_arraylist_isempty(RavaArrayList_t *list);
RavaHashMap_t* rava_hashmap_create(void);
void rava_hashmap_destroy(RavaHashMap_t *map);
void rava_hashmap_put(RavaHashMap_t *map, const char *key, RavaValue_t value);
RavaValue_t rava_hashmap_get(RavaHashMap_t *map, const char *key);
RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key);
size_t rava_hashmap_size(RavaHashMap_t *map);
bool rava_hashmap_containskey(RavaHashMap_t *map, const char *key);
void rava_hashmap_clear(RavaHashMap_t *map);
RavaSocket_t* rava_socket_create(void);
RavaSocket_t* rava_socket_create_connected(const char *host, int port);
RavaSocket_t* rava_server_socket_create(int port);
void rava_socket_destroy(RavaSocket_t *socket);
bool rava_socket_connect(RavaSocket_t *socket, const char *host, int port);
RavaSocket_t* rava_server_socket_accept(RavaSocket_t *server);
RavaStream_t* rava_socket_get_input_stream(RavaSocket_t *socket);
RavaStream_t* rava_socket_get_output_stream(RavaSocket_t *socket);
void rava_socket_close(RavaSocket_t *socket);
RavaStream_t* rava_stream_create(int fd, int stream_type);
void rava_stream_destroy(RavaStream_t *stream);
char* rava_stream_read(RavaStream_t *stream);
int rava_stream_read_byte(RavaStream_t *stream);
void rava_stream_write(RavaStream_t *stream, const char *data);
void rava_stream_write_byte(RavaStream_t *stream, int byte);
void rava_stream_close(RavaStream_t *stream);
static inline RavaValue_t rava_value_socket(RavaSocket_t *socket) {
RavaValue_t val;
val.type = RAVA_VAL_SOCKET;
val.data.socket_val = socket;
return val;
}
static inline RavaValue_t rava_value_stream(RavaStream_t *stream) {
RavaValue_t val;
val.type = RAVA_VAL_STREAM;
val.data.stream_val = stream;
return val;
}
RavaMethodRef_t* rava_method_ref_create(const char *class_name, const char *method_name, bool is_constructor, bool is_static);
void rava_method_ref_destroy(RavaMethodRef_t *ref);
static inline RavaValue_t rava_value_method_ref(RavaMethodRef_t *ref) {
RavaValue_t val;
val.type = RAVA_VAL_METHOD_REF;
val.data.method_ref_val = ref;
return val;
}
RavaStack_t* rava_stack_create(size_t capacity);
void rava_stack_destroy(RavaStack_t *stack);
void rava_stack_push(RavaStack_t *stack, RavaValue_t value);
RavaValue_t rava_stack_pop(RavaStack_t *stack);
RavaValue_t rava_stack_peek(RavaStack_t *stack);
bool rava_stack_is_empty(RavaStack_t *stack);
RavaCallFrame_t* rava_call_frame_create(RavaMethod_t *method);
void rava_call_frame_destroy(RavaCallFrame_t *frame);
RavaCallStack_t* rava_call_stack_create();
void rava_call_stack_destroy(RavaCallStack_t *stack);
bool rava_call_stack_push(RavaCallStack_t *stack, RavaCallFrame_t *frame);
RavaCallFrame_t* rava_call_stack_pop(RavaCallStack_t *stack);
RavaCallFrame_t* rava_call_stack_current(RavaCallStack_t *stack);
RavaVM_t* rava_vm_create(RavaProgram_t *program);
void rava_vm_destroy(RavaVM_t *vm);
bool rava_vm_execute(RavaVM_t *vm, const char *class_name, const char *method_name);
RavaValue_t rava_vm_get_result(RavaVM_t *vm);
bool rava_vm_load_native_library(RavaVM_t *vm, const char *path);
bool rava_vm_register_native(RavaVM_t *vm, const char *class_name, const char *method_name,
RavaNativeType_e return_type, RavaNativeType_e *param_types,
size_t param_count, RavaNativeFunction_fn function, void *user_data);
RavaValue_t rava_vm_call_native(RavaVM_t *vm, const char *class_name, const char *method_name,
RavaValue_t *args, size_t arg_count);
RavaNativeValue_t rava_value_to_native(RavaValue_t value);
RavaValue_t rava_native_to_value(RavaNativeValue_t native);
#endif