Compare commits

..

No commits in common. "ca544088d64e43a8565b7c16ad37220c11bd761c" and "d22e4b06112b7858bf9e310eb213e08fb0997419" have entirely different histories.

7 changed files with 37 additions and 100 deletions

View File

@ -231,7 +231,6 @@ typedef union {
struct { struct {
char *class_name; char *class_name;
char *field_name; char *field_name;
void *cached_ptr;
} field; } field;
struct { struct {
int local_index; int local_index;
@ -267,8 +266,8 @@ typedef union {
typedef struct { typedef struct {
RavaOpCode_e opcode; RavaOpCode_e opcode;
int line;
RavaOperand_u operand; RavaOperand_u operand;
int line;
} RavaInstruction_t; } RavaInstruction_t;
typedef struct { typedef struct {

View File

@ -270,7 +270,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
instr.opcode = RAVA_OP_STORE_STATIC; instr.opcode = RAVA_OP_STORE_STATIC;
instr.operand.field.class_name = strdup(obj_name); instr.operand.field.class_name = strdup(obj_name);
instr.operand.field.field_name = strdup(target_member->data.member_access.member); instr.operand.field.field_name = strdup(target_member->data.member_access.member);
instr.operand.field.cached_ptr = NULL;
_rava_ir_emit(gen, instr); _rava_ir_emit(gen, instr);
break; break;
} }
@ -302,7 +301,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
instr.opcode = RAVA_OP_LOAD_STATIC; instr.opcode = RAVA_OP_LOAD_STATIC;
instr.operand.field.class_name = strdup(obj_name); instr.operand.field.class_name = strdup(obj_name);
instr.operand.field.field_name = strdup(expr->data.member_access.member); instr.operand.field.field_name = strdup(expr->data.member_access.member);
instr.operand.field.cached_ptr = NULL;
_rava_ir_emit(gen, instr); _rava_ir_emit(gen, instr);
break; break;
} }

View File

@ -17,12 +17,12 @@
typedef struct { typedef struct {
RavaMethod_t* method; RavaMethod_t* method;
size_t pc;
size_t stack_top;
bool has_this;
RavaNanboxValue_t this_ref;
RavaNanboxValue_t locals[RAVA_MAX_LOCALS_FIXED]; RavaNanboxValue_t locals[RAVA_MAX_LOCALS_FIXED];
RavaNanboxValue_t stack[RAVA_MAX_STACK_FIXED]; RavaNanboxValue_t stack[RAVA_MAX_STACK_FIXED];
size_t stack_top;
size_t pc;
bool has_this;
RavaNanboxValue_t this_ref;
} FastFrame_t; } FastFrame_t;
typedef struct { typedef struct {

View File

@ -157,23 +157,4 @@ static inline bool rava_nanbox_to_bool(RavaNanboxValue_t v) {
return true; return true;
} }
#define RAVA_NANBOX_BOTH_INT(a, b) (((a | b) & RAVA_TAG_MASK) == RAVA_TAG_LONG)
#define RAVA_NANBOX_BOTH_LONG(a, b) (((a | b) & RAVA_TAG_MASK) == RAVA_TAG_LONG)
static inline int64_t rava_nanbox_as_int_unchecked(RavaNanboxValue_t v) {
int64_t payload = (int64_t)(v & RAVA_PAYLOAD_MASK);
if (payload & 0x800000000000ULL) {
payload |= (int64_t)0xFFFF000000000000ULL;
}
return payload;
}
static inline int64_t rava_nanbox_as_long_unchecked(RavaNanboxValue_t v) {
int64_t payload = (int64_t)(v & RAVA_PAYLOAD_MASK);
if (payload & 0x800000000000ULL) {
payload |= (int64_t)0xFFFF000000000000ULL;
}
return payload;
}
#endif #endif

View File

@ -145,14 +145,10 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
snprintf(buf_b, sizeof(buf_b), "%ld", (long)rava_value_as_int(b)); snprintf(buf_b, sizeof(buf_b), "%ld", (long)rava_value_as_int(b));
str_b = buf_b; str_b = buf_b;
} }
size_t len_a = strlen(str_a); size_t len = strlen(str_a) + strlen(str_b) + 1;
size_t len_b = strlen(str_b);
size_t len = len_a + len_b + 1;
char *result = malloc(len); char *result = malloc(len);
if (result) { strcpy(result, str_a);
memcpy(result, str_a, len_a); strcat(result, str_b);
memcpy(result + len_a, str_b, len_b + 1);
}
rava_stack_push(stack, rava_value_string(result)); rava_stack_push(stack, rava_value_string(result));
free(result); free(result);
} else if (a.type == RAVA_VAL_LONG || b.type == RAVA_VAL_LONG) { } else if (a.type == RAVA_VAL_LONG || b.type == RAVA_VAL_LONG) {
@ -2030,14 +2026,8 @@ op_load_field: {
} }
op_load_static: { op_load_static: {
RavaValue_t *field_val = (RavaValue_t*)instr->operand.field.cached_ptr; RavaValue_t *field_val = rava_static_field_table_get(vm->static_fields,
instr->operand.field.class_name, instr->operand.field.field_name);
if (!field_val) {
field_val = rava_static_field_table_get(vm->static_fields,
instr->operand.field.class_name, instr->operand.field.field_name);
instr->operand.field.cached_ptr = field_val;
}
STACK_PUSH(stack, field_val ? *field_val : rava_value_int(0)); STACK_PUSH(stack, field_val ? *field_val : rava_value_int(0));
DISPATCH(); DISPATCH();
} }
@ -2110,19 +2100,8 @@ op_store_field: {
op_store_static: { op_store_static: {
RavaValue_t value = STACK_POP(stack); RavaValue_t value = STACK_POP(stack);
RavaValue_t *field_val = (RavaValue_t*)instr->operand.field.cached_ptr; rava_static_field_table_set(vm->static_fields, instr->operand.field.class_name,
instr->operand.field.field_name, value);
if (!field_val) {
rava_static_field_table_set(vm->static_fields, instr->operand.field.class_name,
instr->operand.field.field_name, value);
field_val = rava_static_field_table_get(vm->static_fields,
instr->operand.field.class_name, instr->operand.field.field_name);
if (field_val) {
instr->operand.field.cached_ptr = field_val;
}
} else {
*field_val = value;
}
DISPATCH(); DISPATCH();
} }
@ -3416,8 +3395,8 @@ uf_store_local:
uf_add: { uf_add: {
RavaNanboxValue_t b = UF_POP(); RavaNanboxValue_t b = UF_POP();
RavaNanboxValue_t a = UF_POP(); RavaNanboxValue_t a = UF_POP();
if (LIKELY(RAVA_NANBOX_BOTH_INT(a, b))) { if (LIKELY(rava_nanbox_is_int(a) && rava_nanbox_is_int(b))) {
UF_PUSH(rava_nanbox_int(rava_nanbox_as_int_unchecked(a) + rava_nanbox_as_int_unchecked(b))); UF_PUSH(rava_nanbox_int(rava_nanbox_as_int(a) + rava_nanbox_as_int(b)));
} else if (UNLIKELY(rava_nanbox_is_string(a) || rava_nanbox_is_string(b))) { } else if (UNLIKELY(rava_nanbox_is_string(a) || rava_nanbox_is_string(b))) {
char buf_a[64], buf_b[64]; char buf_a[64], buf_b[64];
const char *str_a, *str_b; const char *str_a, *str_b;
@ -3455,8 +3434,8 @@ uf_add: {
uf_sub: { uf_sub: {
RavaNanboxValue_t b = UF_POP(); RavaNanboxValue_t b = UF_POP();
RavaNanboxValue_t a = UF_POP(); RavaNanboxValue_t a = UF_POP();
if (LIKELY(RAVA_NANBOX_BOTH_INT(a, b))) { if (LIKELY(rava_nanbox_is_int(a) && rava_nanbox_is_int(b))) {
UF_PUSH(rava_nanbox_int(rava_nanbox_as_int_unchecked(a) - rava_nanbox_as_int_unchecked(b))); UF_PUSH(rava_nanbox_int(rava_nanbox_as_int(a) - rava_nanbox_as_int(b)));
} else if (UNLIKELY(rava_nanbox_is_long(a) || rava_nanbox_is_long(b))) { } else if (UNLIKELY(rava_nanbox_is_long(a) || rava_nanbox_is_long(b))) {
UF_PUSH(rava_nanbox_long(rava_nanbox_to_long(a) - rava_nanbox_to_long(b))); UF_PUSH(rava_nanbox_long(rava_nanbox_to_long(a) - rava_nanbox_to_long(b)));
} else { } else {
@ -3468,8 +3447,8 @@ uf_sub: {
uf_mul: { uf_mul: {
RavaNanboxValue_t b = UF_POP(); RavaNanboxValue_t b = UF_POP();
RavaNanboxValue_t a = UF_POP(); RavaNanboxValue_t a = UF_POP();
if (LIKELY(RAVA_NANBOX_BOTH_INT(a, b))) { if (LIKELY(rava_nanbox_is_int(a) && rava_nanbox_is_int(b))) {
UF_PUSH(rava_nanbox_int(rava_nanbox_as_int_unchecked(a) * rava_nanbox_as_int_unchecked(b))); UF_PUSH(rava_nanbox_int(rava_nanbox_as_int(a) * rava_nanbox_as_int(b)));
} else if (UNLIKELY(rava_nanbox_is_long(a) || rava_nanbox_is_long(b))) { } else if (UNLIKELY(rava_nanbox_is_long(a) || rava_nanbox_is_long(b))) {
UF_PUSH(rava_nanbox_long(rava_nanbox_to_long(a) * rava_nanbox_to_long(b))); UF_PUSH(rava_nanbox_long(rava_nanbox_to_long(a) * rava_nanbox_to_long(b)));
} else { } else {
@ -3483,8 +3462,8 @@ uf_div: {
RavaNanboxValue_t a = UF_POP(); RavaNanboxValue_t a = UF_POP();
int64_t bv = rava_nanbox_to_long(b); int64_t bv = rava_nanbox_to_long(b);
if (UNLIKELY(bv == 0)) { UF_PUSH(rava_nanbox_int(0)); UF_DISPATCH(); } if (UNLIKELY(bv == 0)) { UF_PUSH(rava_nanbox_int(0)); UF_DISPATCH(); }
if (LIKELY(RAVA_NANBOX_BOTH_INT(a, b))) { if (LIKELY(rava_nanbox_is_int(a) && rava_nanbox_is_int(b))) {
UF_PUSH(rava_nanbox_int(rava_nanbox_as_int_unchecked(a) / bv)); UF_PUSH(rava_nanbox_int(rava_nanbox_as_int(a) / rava_nanbox_as_int(b)));
} else { } else {
UF_PUSH(rava_nanbox_long(rava_nanbox_to_long(a) / bv)); UF_PUSH(rava_nanbox_long(rava_nanbox_to_long(a) / bv));
} }
@ -3496,8 +3475,8 @@ uf_mod: {
RavaNanboxValue_t a = UF_POP(); RavaNanboxValue_t a = UF_POP();
int64_t bv = rava_nanbox_to_long(b); int64_t bv = rava_nanbox_to_long(b);
if (bv == 0) { UF_PUSH(rava_nanbox_int(0)); UF_DISPATCH(); } if (bv == 0) { UF_PUSH(rava_nanbox_int(0)); UF_DISPATCH(); }
if (RAVA_NANBOX_BOTH_INT(a, b)) { if (rava_nanbox_is_int(a) && rava_nanbox_is_int(b)) {
UF_PUSH(rava_nanbox_int(rava_nanbox_as_int_unchecked(a) % bv)); UF_PUSH(rava_nanbox_int(rava_nanbox_as_int(a) % rava_nanbox_as_int(b)));
} else { } else {
UF_PUSH(rava_nanbox_long(rava_nanbox_to_long(a) % bv)); UF_PUSH(rava_nanbox_long(rava_nanbox_to_long(a) % bv));
} }
@ -3999,33 +3978,14 @@ uf_store_field: {
} }
uf_load_static: { uf_load_static: {
RavaValue_t *v = (RavaValue_t*)instr->operand.field.cached_ptr; RavaValue_t *v = rava_static_field_table_get(vm->static_fields, instr->operand.field.class_name, instr->operand.field.field_name);
if (!v) {
v = rava_static_field_table_get(vm->static_fields, instr->operand.field.class_name, instr->operand.field.field_name);
instr->operand.field.cached_ptr = v;
}
UF_PUSH(v ? rava_value_to_nanbox(*v) : rava_nanbox_null()); UF_PUSH(v ? rava_value_to_nanbox(*v) : rava_nanbox_null());
UF_DISPATCH(); UF_DISPATCH();
} }
uf_store_static: { uf_store_static: {
RavaNanboxValue_t val = UF_POP(); RavaNanboxValue_t val = UF_POP();
RavaValue_t *field_val = (RavaValue_t*)instr->operand.field.cached_ptr; rava_static_field_table_set(vm->static_fields, instr->operand.field.class_name, instr->operand.field.field_name, rava_nanbox_to_value(val));
if (!field_val) {
RavaValue_t value = rava_nanbox_to_value(val);
rava_static_field_table_set(vm->static_fields, instr->operand.field.class_name,
instr->operand.field.field_name, value);
field_val = rava_static_field_table_get(vm->static_fields,
instr->operand.field.class_name, instr->operand.field.field_name);
if (field_val) {
instr->operand.field.cached_ptr = field_val;
}
} else {
*field_val = rava_nanbox_to_value(val);
}
UF_DISPATCH(); UF_DISPATCH();
} }
@ -4458,8 +4418,8 @@ uf_add_local_to_local: {
int src = instr->operand.add_locals.src_index; int src = instr->operand.add_locals.src_index;
RavaNanboxValue_t d = frame->locals[dest]; RavaNanboxValue_t d = frame->locals[dest];
RavaNanboxValue_t s = frame->locals[src]; RavaNanboxValue_t s = frame->locals[src];
if (RAVA_NANBOX_BOTH_INT(d, s)) { if (rava_nanbox_is_int(d) && rava_nanbox_is_int(s)) {
frame->locals[dest] = rava_nanbox_int(rava_nanbox_as_int_unchecked(d) + rava_nanbox_as_int_unchecked(s)); frame->locals[dest] = rava_nanbox_int(rava_nanbox_as_int(d) + rava_nanbox_as_int(s));
} else { } else {
frame->locals[dest] = rava_nanbox_long(rava_nanbox_to_long(d) + rava_nanbox_to_long(s)); frame->locals[dest] = rava_nanbox_long(rava_nanbox_to_long(d) + rava_nanbox_to_long(s));
} }

View File

@ -99,9 +99,9 @@ struct RavaArrayList_t {
#define RAVA_HASHMAP_BUCKET_SIZE 32 #define RAVA_HASHMAP_BUCKET_SIZE 32
typedef struct { typedef struct {
bool occupied;
char *key; char *key;
RavaValue_t value; RavaValue_t value;
bool occupied;
} RavaHashMapEntry_t; } RavaHashMapEntry_t;
struct RavaHashMap_t { struct RavaHashMap_t {

View File

@ -54,9 +54,8 @@ RavaValue_t rava_arraylist_remove(RavaArrayList_t *list, size_t index) {
return rava_value_null(); return rava_value_null();
} }
RavaValue_t removed = list->data[index]; RavaValue_t removed = list->data[index];
if (index < list->size - 1) { for (size_t i = index; i < list->size - 1; i++) {
memmove(&list->data[index], &list->data[index + 1], list->data[i] = list->data[i + 1];
(list->size - index - 1) * sizeof(RavaValue_t));
} }
list->size--; list->size--;
return removed; return removed;
@ -125,14 +124,14 @@ void rava_hashmap_put(RavaHashMap_t *map, const char *key, RavaValue_t value) {
} }
unsigned int hash = _rava_hash_string(key); unsigned int hash = _rava_hash_string(key);
size_t index = hash & (map->bucket_count - 1); size_t index = hash % map->bucket_count;
while (map->buckets[index].occupied) { while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) { if (strcmp(map->buckets[index].key, key) == 0) {
map->buckets[index].value = value; map->buckets[index].value = value;
return; return;
} }
index = (index + 1) & (map->bucket_count - 1); index = (index + 1) % map->bucket_count;
} }
map->buckets[index].key = strdup(key); map->buckets[index].key = strdup(key);
@ -143,14 +142,14 @@ 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_get(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key); unsigned int hash = _rava_hash_string(key);
size_t index = hash & (map->bucket_count - 1); size_t index = hash % map->bucket_count;
size_t start = index; size_t start = index;
while (map->buckets[index].occupied) { while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) { if (strcmp(map->buckets[index].key, key) == 0) {
return map->buckets[index].value; return map->buckets[index].value;
} }
index = (index + 1) & (map->bucket_count - 1); index = (index + 1) % map->bucket_count;
if (index == start) break; if (index == start) break;
} }
@ -159,7 +158,7 @@ RavaValue_t rava_hashmap_get(RavaHashMap_t *map, const char *key) {
RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key) { RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key); unsigned int hash = _rava_hash_string(key);
size_t index = hash & (map->bucket_count - 1); size_t index = hash % map->bucket_count;
size_t start = index; size_t start = index;
while (map->buckets[index].occupied) { while (map->buckets[index].occupied) {
@ -171,7 +170,7 @@ RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key) {
map->size--; map->size--;
return removed; return removed;
} }
index = (index + 1) & (map->bucket_count - 1); index = (index + 1) % map->bucket_count;
if (index == start) break; if (index == start) break;
} }
@ -184,14 +183,14 @@ size_t rava_hashmap_size(RavaHashMap_t *map) {
bool rava_hashmap_containskey(RavaHashMap_t *map, const char *key) { bool rava_hashmap_containskey(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key); unsigned int hash = _rava_hash_string(key);
size_t index = hash & (map->bucket_count - 1); size_t index = hash % map->bucket_count;
size_t start = index; size_t start = index;
while (map->buckets[index].occupied) { while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) { if (strcmp(map->buckets[index].key, key) == 0) {
return true; return true;
} }
index = (index + 1) & (map->bucket_count - 1); index = (index + 1) % map->bucket_count;
if (index == start) break; if (index == start) break;
} }