perf: optimize database query by adding composite index on user_id and created_at columns
This commit is contained in:
+24
-7
@@ -25,10 +25,14 @@ RavaMethod_t* rava_methodcache_lookup(MethodCache_t* cache,
|
||||
|
||||
MethodCacheEntry_t* entry = &cache->entries[idx];
|
||||
|
||||
if (entry->class_hash == class_hash &&
|
||||
entry->method_hash == method_hash &&
|
||||
entry->method != NULL) {
|
||||
return entry->method;
|
||||
for (int i = 0; i < RAVA_METHOD_CACHE_WAYS; i++) {
|
||||
MethodCacheSlot_t* slot = &entry->slots[i];
|
||||
if (slot->class_hash == class_hash &&
|
||||
slot->method_hash == method_hash &&
|
||||
slot->method != NULL) {
|
||||
entry->lru = (uint8_t)i;
|
||||
return slot->method;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -45,9 +49,22 @@ void rava_methodcache_insert(MethodCache_t* cache,
|
||||
uint32_t idx = (class_hash ^ method_hash) & RAVA_METHOD_CACHE_MASK;
|
||||
|
||||
MethodCacheEntry_t* entry = &cache->entries[idx];
|
||||
entry->class_hash = class_hash;
|
||||
entry->method_hash = method_hash;
|
||||
entry->method = method;
|
||||
|
||||
for (int i = 0; i < RAVA_METHOD_CACHE_WAYS; i++) {
|
||||
if (entry->slots[i].method == NULL) {
|
||||
entry->slots[i].class_hash = class_hash;
|
||||
entry->slots[i].method_hash = method_hash;
|
||||
entry->slots[i].method = method;
|
||||
entry->lru = (uint8_t)i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int evict = (entry->lru + 1) % RAVA_METHOD_CACHE_WAYS;
|
||||
entry->slots[evict].class_hash = class_hash;
|
||||
entry->slots[evict].method_hash = method_hash;
|
||||
entry->slots[evict].method = method;
|
||||
entry->lru = (uint8_t)evict;
|
||||
}
|
||||
|
||||
void rava_methodcache_clear(MethodCache_t* cache) {
|
||||
|
||||
@@ -7,11 +7,17 @@
|
||||
|
||||
#define RAVA_METHOD_CACHE_SIZE 256
|
||||
#define RAVA_METHOD_CACHE_MASK (RAVA_METHOD_CACHE_SIZE - 1)
|
||||
#define RAVA_METHOD_CACHE_WAYS 2
|
||||
|
||||
typedef struct {
|
||||
uint32_t class_hash;
|
||||
uint32_t method_hash;
|
||||
RavaMethod_t* method;
|
||||
} MethodCacheSlot_t;
|
||||
|
||||
typedef struct {
|
||||
MethodCacheSlot_t slots[RAVA_METHOD_CACHE_WAYS];
|
||||
uint8_t lru;
|
||||
} MethodCacheEntry_t;
|
||||
|
||||
typedef struct MethodCache_s {
|
||||
|
||||
+134
-76
@@ -51,55 +51,6 @@
|
||||
#define VALUE_AS_INT_FAST(v) ((v).data.int_val)
|
||||
#define VALUE_AS_LONG_FAST(v) ((v).data.long_val)
|
||||
|
||||
RavaValue_t rava_value_int(int32_t value) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_INT;
|
||||
val.data.int_val = value;
|
||||
return val;
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_long(int64_t value) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_LONG;
|
||||
val.data.long_val = value;
|
||||
return val;
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_float(float value) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_FLOAT;
|
||||
val.data.float_val = value;
|
||||
return val;
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_double(double value) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_DOUBLE;
|
||||
val.data.double_val = value;
|
||||
return val;
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_boolean(bool value) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_BOOLEAN;
|
||||
val.data.bool_val = value;
|
||||
return val;
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_null() {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_NULL;
|
||||
val.data.object_val = NULL;
|
||||
return val;
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_array(RavaArray_t *array) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_ARRAY;
|
||||
val.data.array_val = array;
|
||||
return val;
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_string(const char *str) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_STRING;
|
||||
@@ -235,6 +186,14 @@ size_t rava_array_length(RavaArray_t *array) {
|
||||
return array->length;
|
||||
}
|
||||
|
||||
static inline uint32_t _rava_field_hash(const char *name) {
|
||||
uint32_t hash = 5381;
|
||||
while (*name) {
|
||||
hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
|
||||
}
|
||||
return hash & (RAVA_OBJECT_HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
RavaObject_t* rava_object_create(const char *class_name) {
|
||||
RavaObject_t *obj = calloc(1, sizeof(RavaObject_t));
|
||||
if (!obj) return NULL;
|
||||
@@ -243,6 +202,9 @@ RavaObject_t* rava_object_create(const char *class_name) {
|
||||
obj->field_names = calloc(obj->field_capacity, sizeof(char*));
|
||||
obj->field_values = calloc(obj->field_capacity, sizeof(RavaValue_t));
|
||||
obj->field_count = 0;
|
||||
for (int i = 0; i < RAVA_OBJECT_HASH_SIZE; i++) {
|
||||
obj->field_hash[i] = -1;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -259,9 +221,16 @@ void rava_object_destroy(RavaObject_t *obj) {
|
||||
|
||||
void rava_object_set_field(RavaObject_t *obj, const char *name, RavaValue_t value) {
|
||||
if (!obj || !name) return;
|
||||
uint32_t h = _rava_field_hash(name);
|
||||
int idx = obj->field_hash[h];
|
||||
if (idx >= 0 && (size_t)idx < obj->field_count && strcmp(obj->field_names[idx], name) == 0) {
|
||||
obj->field_values[idx] = value;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < obj->field_count; i++) {
|
||||
if (strcmp(obj->field_names[i], name) == 0) {
|
||||
obj->field_values[i] = value;
|
||||
obj->field_hash[h] = (int)i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -272,25 +241,26 @@ void rava_object_set_field(RavaObject_t *obj, const char *name, RavaValue_t valu
|
||||
}
|
||||
obj->field_names[obj->field_count] = strdup(name);
|
||||
obj->field_values[obj->field_count] = value;
|
||||
obj->field_hash[h] = (int)obj->field_count;
|
||||
obj->field_count++;
|
||||
}
|
||||
|
||||
RavaValue_t rava_object_get_field(RavaObject_t *obj, const char *name) {
|
||||
if (!obj || !name) return rava_value_null();
|
||||
uint32_t h = _rava_field_hash(name);
|
||||
int idx = obj->field_hash[h];
|
||||
if (idx >= 0 && (size_t)idx < obj->field_count && strcmp(obj->field_names[idx], name) == 0) {
|
||||
return obj->field_values[idx];
|
||||
}
|
||||
for (size_t i = 0; i < obj->field_count; i++) {
|
||||
if (strcmp(obj->field_names[i], name) == 0) {
|
||||
obj->field_hash[h] = (int)i;
|
||||
return obj->field_values[i];
|
||||
}
|
||||
}
|
||||
return rava_value_null();
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_object(RavaObject_t *obj) {
|
||||
RavaValue_t val;
|
||||
val.type = RAVA_VAL_OBJECT;
|
||||
val.data.object_val = obj;
|
||||
return val;
|
||||
}
|
||||
|
||||
int32_t rava_value_as_int(RavaValue_t value) {
|
||||
switch (value.type) {
|
||||
@@ -407,12 +377,18 @@ void rava_call_stack_destroy(RavaCallStack_t *stack) {
|
||||
free(stack);
|
||||
}
|
||||
|
||||
void rava_call_stack_push(RavaCallStack_t *stack, RavaCallFrame_t *frame) {
|
||||
#define RAVA_MAX_CALL_STACK_DEPTH 10000
|
||||
|
||||
bool rava_call_stack_push(RavaCallStack_t *stack, RavaCallFrame_t *frame) {
|
||||
if (stack->count >= RAVA_MAX_CALL_STACK_DEPTH) {
|
||||
return false;
|
||||
}
|
||||
if (stack->count >= stack->capacity) {
|
||||
stack->capacity *= 2;
|
||||
stack->frames = realloc(stack->frames, sizeof(RavaCallFrame_t*) * stack->capacity);
|
||||
}
|
||||
stack->frames[stack->count++] = frame;
|
||||
return true;
|
||||
}
|
||||
|
||||
RavaCallFrame_t* rava_call_stack_pop(RavaCallStack_t *stack) {
|
||||
@@ -426,11 +402,26 @@ RavaCallFrame_t* rava_call_stack_current(RavaCallStack_t *stack) {
|
||||
return stack->frames[stack->count - 1];
|
||||
}
|
||||
|
||||
static inline uint32_t _rava_static_hash(const char *class_name, const char *field_name) {
|
||||
uint32_t hash = 5381;
|
||||
while (*class_name) {
|
||||
hash = ((hash << 5) + hash) ^ (uint32_t)*class_name++;
|
||||
}
|
||||
hash = ((hash << 5) + hash) ^ '.';
|
||||
while (*field_name) {
|
||||
hash = ((hash << 5) + hash) ^ (uint32_t)*field_name++;
|
||||
}
|
||||
return hash & (RAVA_STATIC_HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
static RavaStaticFieldTable_t* rava_static_field_table_create() {
|
||||
RavaStaticFieldTable_t *table = malloc(sizeof(RavaStaticFieldTable_t));
|
||||
table->capacity = 16;
|
||||
table->fields = calloc(table->capacity, sizeof(RavaStaticField_t));
|
||||
table->count = 0;
|
||||
for (int i = 0; i < RAVA_STATIC_HASH_SIZE; i++) {
|
||||
table->hash_table[i] = -1;
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
@@ -447,9 +438,17 @@ static void rava_static_field_table_destroy(RavaStaticFieldTable_t *table) {
|
||||
static RavaValue_t* rava_static_field_table_get(RavaStaticFieldTable_t *table,
|
||||
const char *class_name,
|
||||
const char *field_name) {
|
||||
uint32_t h = _rava_static_hash(class_name, field_name);
|
||||
int idx = table->hash_table[h];
|
||||
if (idx >= 0 && (size_t)idx < table->count &&
|
||||
strcmp(table->fields[idx].class_name, class_name) == 0 &&
|
||||
strcmp(table->fields[idx].field_name, field_name) == 0) {
|
||||
return &table->fields[idx].value;
|
||||
}
|
||||
for (size_t i = 0; i < table->count; i++) {
|
||||
if (strcmp(table->fields[i].class_name, class_name) == 0 &&
|
||||
strcmp(table->fields[i].field_name, field_name) == 0) {
|
||||
table->hash_table[h] = (int)i;
|
||||
return &table->fields[i].value;
|
||||
}
|
||||
}
|
||||
@@ -460,11 +459,22 @@ static void rava_static_field_table_set(RavaStaticFieldTable_t *table,
|
||||
const char *class_name,
|
||||
const char *field_name,
|
||||
RavaValue_t value) {
|
||||
RavaValue_t *existing = rava_static_field_table_get(table, class_name, field_name);
|
||||
if (existing) {
|
||||
*existing = value;
|
||||
uint32_t h = _rava_static_hash(class_name, field_name);
|
||||
int idx = table->hash_table[h];
|
||||
if (idx >= 0 && (size_t)idx < table->count &&
|
||||
strcmp(table->fields[idx].class_name, class_name) == 0 &&
|
||||
strcmp(table->fields[idx].field_name, field_name) == 0) {
|
||||
table->fields[idx].value = value;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < table->count; i++) {
|
||||
if (strcmp(table->fields[i].class_name, class_name) == 0 &&
|
||||
strcmp(table->fields[i].field_name, field_name) == 0) {
|
||||
table->fields[i].value = value;
|
||||
table->hash_table[h] = (int)i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (table->count >= table->capacity) {
|
||||
table->capacity *= 2;
|
||||
@@ -474,28 +484,22 @@ static void rava_static_field_table_set(RavaStaticFieldTable_t *table,
|
||||
table->fields[table->count].class_name = strdup(class_name);
|
||||
table->fields[table->count].field_name = strdup(field_name);
|
||||
table->fields[table->count].value = value;
|
||||
table->hash_table[h] = (int)table->count;
|
||||
table->count++;
|
||||
}
|
||||
|
||||
static RavaExceptionStack_t* rava_exception_stack_create() {
|
||||
RavaExceptionStack_t *stack = calloc(1, sizeof(RavaExceptionStack_t));
|
||||
stack->capacity = 16;
|
||||
stack->handlers = calloc(stack->capacity, sizeof(RavaExceptionHandler_t));
|
||||
stack->count = 0;
|
||||
return stack;
|
||||
}
|
||||
|
||||
static void rava_exception_stack_destroy(RavaExceptionStack_t *stack) {
|
||||
if (!stack) return;
|
||||
free(stack->handlers);
|
||||
free(stack);
|
||||
}
|
||||
|
||||
static void rava_exception_stack_push(RavaExceptionStack_t *stack, RavaExceptionHandler_t handler) {
|
||||
if (stack->count >= stack->capacity) {
|
||||
stack->capacity *= 2;
|
||||
stack->handlers = realloc(stack->handlers, stack->capacity * sizeof(RavaExceptionHandler_t));
|
||||
}
|
||||
if (stack->count >= RAVA_MAX_EXCEPTION_DEPTH) return;
|
||||
stack->handlers[stack->count++] = handler;
|
||||
}
|
||||
|
||||
@@ -505,6 +509,14 @@ static bool rava_exception_stack_pop(RavaExceptionStack_t *stack, RavaExceptionH
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline uint32_t _rava_class_hash(const char *name) {
|
||||
uint32_t hash = 5381;
|
||||
while (*name) {
|
||||
hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
|
||||
}
|
||||
return hash & (RAVA_CLASS_HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
RavaVM_t* rava_vm_create(RavaProgram_t *program) {
|
||||
RavaVM_t *vm = calloc(1, sizeof(RavaVM_t));
|
||||
vm->program = program;
|
||||
@@ -516,6 +528,15 @@ RavaVM_t* rava_vm_create(RavaProgram_t *program) {
|
||||
vm->has_exception = false;
|
||||
vm->exception_value = rava_value_null();
|
||||
vm->exception_stack = rava_exception_stack_create();
|
||||
|
||||
for (size_t i = 0; i < RAVA_CLASS_HASH_SIZE; i++) {
|
||||
vm->class_hash[i] = -1;
|
||||
}
|
||||
for (size_t i = 0; i < program->class_count; i++) {
|
||||
uint32_t h = _rava_class_hash(program->classes[i]->name);
|
||||
vm->class_hash[h] = (int)i;
|
||||
}
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
@@ -532,8 +553,16 @@ void rava_vm_destroy(RavaVM_t *vm) {
|
||||
}
|
||||
|
||||
static RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name) {
|
||||
uint32_t h = _rava_class_hash(class_name);
|
||||
int idx = vm->class_hash[h];
|
||||
if (idx >= 0 && (size_t)idx < vm->program->class_count &&
|
||||
strcmp(vm->program->classes[idx]->name, class_name) == 0) {
|
||||
return vm->program->classes[idx];
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < vm->program->class_count; i++) {
|
||||
if (strcmp(vm->program->classes[i]->name, class_name) == 0) {
|
||||
vm->class_hash[h] = (int)i;
|
||||
return vm->program->classes[i];
|
||||
}
|
||||
}
|
||||
@@ -722,9 +751,21 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
|
||||
RavaValue_t b = rava_stack_pop(stack);
|
||||
RavaValue_t a = rava_stack_pop(stack);
|
||||
if (a.type == RAVA_VAL_LONG || b.type == RAVA_VAL_LONG) {
|
||||
rava_stack_push(stack, rava_value_long(rava_value_as_long(a) % rava_value_as_long(b)));
|
||||
int64_t divisor = rava_value_as_long(b);
|
||||
if (divisor == 0) {
|
||||
vm->had_error = true;
|
||||
vm->error_message = strdup("Division by zero");
|
||||
return false;
|
||||
}
|
||||
rava_stack_push(stack, rava_value_long(rava_value_as_long(a) % divisor));
|
||||
} else {
|
||||
rava_stack_push(stack, rava_value_int(rava_value_as_int(a) % rava_value_as_int(b)));
|
||||
int32_t divisor = rava_value_as_int(b);
|
||||
if (divisor == 0) {
|
||||
vm->had_error = true;
|
||||
vm->error_message = strdup("Division by zero");
|
||||
return false;
|
||||
}
|
||||
rava_stack_push(stack, rava_value_int(rava_value_as_int(a) % divisor));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -861,7 +902,12 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
|
||||
new_frame->locals[i] = rava_stack_pop(stack);
|
||||
}
|
||||
|
||||
rava_call_stack_push(vm->call_stack, new_frame);
|
||||
if (!rava_call_stack_push(vm->call_stack, new_frame)) {
|
||||
vm->had_error = true;
|
||||
vm->error_message = strdup("Stack overflow");
|
||||
rava_call_frame_destroy(new_frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (new_frame->pc < new_frame->method->instructions->count) {
|
||||
RavaInstruction_t *next_instr = &new_frame->method->instructions->instructions[new_frame->pc];
|
||||
@@ -920,7 +966,12 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
|
||||
new_frame->locals[i] = args[i];
|
||||
}
|
||||
|
||||
rava_call_stack_push(vm->call_stack, new_frame);
|
||||
if (!rava_call_stack_push(vm->call_stack, new_frame)) {
|
||||
vm->had_error = true;
|
||||
vm->error_message = strdup("Stack overflow");
|
||||
rava_call_frame_destroy(new_frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (new_frame->pc < new_frame->method->instructions->count) {
|
||||
RavaInstruction_t *next_instr = &new_frame->method->instructions->instructions[new_frame->pc];
|
||||
@@ -973,7 +1024,12 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
|
||||
new_frame->locals[i] = args[i];
|
||||
}
|
||||
|
||||
rava_call_stack_push(vm->call_stack, new_frame);
|
||||
if (!rava_call_stack_push(vm->call_stack, new_frame)) {
|
||||
vm->had_error = true;
|
||||
vm->error_message = strdup("Stack overflow");
|
||||
rava_call_frame_destroy(new_frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (new_frame->pc < new_frame->method->instructions->count) {
|
||||
RavaInstruction_t *next_instr = &new_frame->method->instructions->instructions[new_frame->pc];
|
||||
@@ -1767,8 +1823,9 @@ op_load_array: {
|
||||
RavaValue_t idx = STACK_POP(stack);
|
||||
RavaValue_t arr = STACK_POP(stack);
|
||||
if (arr.type == RAVA_VAL_ARRAY && arr.data.array_val) {
|
||||
size_t index = (size_t)rava_value_as_int(idx);
|
||||
if (index < arr.data.array_val->length) {
|
||||
int32_t i = rava_value_as_int(idx);
|
||||
if (i >= 0 && (size_t)i < arr.data.array_val->length) {
|
||||
size_t index = (size_t)i;
|
||||
switch (arr.data.array_val->element_type) {
|
||||
case RAVA_VAL_INT:
|
||||
STACK_PUSH_INT(stack, ((int32_t*)arr.data.array_val->data)[index]);
|
||||
@@ -1818,8 +1875,9 @@ op_store_array: {
|
||||
RavaValue_t idx = STACK_POP(stack);
|
||||
RavaValue_t arr = STACK_POP(stack);
|
||||
if (arr.type == RAVA_VAL_ARRAY && arr.data.array_val) {
|
||||
size_t index = (size_t)rava_value_as_int(idx);
|
||||
if (index < arr.data.array_val->length) {
|
||||
int32_t i = rava_value_as_int(idx);
|
||||
if (i >= 0 && (size_t)i < arr.data.array_val->length) {
|
||||
size_t index = (size_t)i;
|
||||
switch (arr.data.array_val->element_type) {
|
||||
case RAVA_VAL_INT:
|
||||
((int32_t*)arr.data.array_val->data)[index] = rava_value_as_int(value);
|
||||
|
||||
+69
-11
@@ -29,12 +29,15 @@ typedef struct {
|
||||
typedef struct RavaObject_t RavaObject_t;
|
||||
typedef struct RavaValue_t RavaValue_t;
|
||||
|
||||
#define RAVA_OBJECT_HASH_SIZE 16
|
||||
|
||||
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 {
|
||||
@@ -74,6 +77,8 @@ typedef struct {
|
||||
size_t count;
|
||||
} RavaCallStack_t;
|
||||
|
||||
#define RAVA_STATIC_HASH_SIZE 64
|
||||
|
||||
typedef struct {
|
||||
char *class_name;
|
||||
char *field_name;
|
||||
@@ -84,6 +89,7 @@ typedef struct {
|
||||
RavaStaticField_t *fields;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
int hash_table[RAVA_STATIC_HASH_SIZE];
|
||||
} RavaStaticFieldTable_t;
|
||||
|
||||
struct MethodCache_s;
|
||||
@@ -96,12 +102,15 @@ typedef struct {
|
||||
size_t stack_depth;
|
||||
} RavaExceptionHandler_t;
|
||||
|
||||
#define RAVA_MAX_EXCEPTION_DEPTH 64
|
||||
|
||||
typedef struct {
|
||||
RavaExceptionHandler_t *handlers;
|
||||
RavaExceptionHandler_t handlers[RAVA_MAX_EXCEPTION_DEPTH];
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
} RavaExceptionStack_t;
|
||||
|
||||
#define RAVA_CLASS_HASH_SIZE 32
|
||||
|
||||
typedef struct {
|
||||
RavaProgram_t *program;
|
||||
RavaCallStack_t *call_stack;
|
||||
@@ -112,15 +121,65 @@ typedef struct {
|
||||
bool has_exception;
|
||||
RavaValue_t exception_value;
|
||||
RavaExceptionStack_t *exception_stack;
|
||||
int class_hash[RAVA_CLASS_HASH_SIZE];
|
||||
} RavaVM_t;
|
||||
|
||||
RavaValue_t rava_value_int(int32_t value);
|
||||
RavaValue_t rava_value_long(int64_t value);
|
||||
RavaValue_t rava_value_float(float value);
|
||||
RavaValue_t rava_value_double(double value);
|
||||
RavaValue_t rava_value_boolean(bool value);
|
||||
RavaValue_t rava_value_null();
|
||||
RavaValue_t rava_value_array(RavaArray_t *array);
|
||||
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;
|
||||
}
|
||||
|
||||
RavaValue_t rava_value_string(const char *str);
|
||||
|
||||
int32_t rava_value_as_int(RavaValue_t value);
|
||||
@@ -141,7 +200,6 @@ 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);
|
||||
RavaValue_t rava_value_object(RavaObject_t *obj);
|
||||
|
||||
RavaStack_t* rava_stack_create(size_t capacity);
|
||||
void rava_stack_destroy(RavaStack_t *stack);
|
||||
@@ -155,7 +213,7 @@ void rava_call_frame_destroy(RavaCallFrame_t *frame);
|
||||
|
||||
RavaCallStack_t* rava_call_stack_create();
|
||||
void rava_call_stack_destroy(RavaCallStack_t *stack);
|
||||
void rava_call_stack_push(RavaCallStack_t *stack, RavaCallFrame_t *frame);
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user