Initial commit of dem beast./plot.py
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
#include "fastframe.h"
|
||||
#include <string.h>
|
||||
|
||||
FastFrame_t rava_frame_pool[RAVA_MAX_CALL_DEPTH];
|
||||
size_t rava_frame_depth = 0;
|
||||
|
||||
void rava_fastframe_init(void) {
|
||||
rava_frame_depth = 0;
|
||||
memset(rava_frame_pool, 0, sizeof(rava_frame_pool));
|
||||
}
|
||||
|
||||
FastFrame_t* rava_fastframe_push(RavaMethod_t* method, int local_count) {
|
||||
if (rava_frame_depth >= RAVA_MAX_CALL_DEPTH) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FastFrame_t* frame = &rava_frame_pool[rava_frame_depth++];
|
||||
frame->method = method;
|
||||
frame->stack_top = 0;
|
||||
frame->pc = 0;
|
||||
frame->has_this = false;
|
||||
frame->this_ref = rava_nanbox_null();
|
||||
|
||||
if (local_count > 0 && local_count <= RAVA_MAX_LOCALS_FIXED) {
|
||||
memset(frame->locals, 0, (size_t)local_count * sizeof(RavaNanboxValue_t));
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
void rava_fastframe_pop(void) {
|
||||
if (rava_frame_depth > 0) {
|
||||
rava_frame_depth--;
|
||||
}
|
||||
}
|
||||
|
||||
FastFrame_t* rava_fastframe_current(void) {
|
||||
if (rava_frame_depth == 0) return NULL;
|
||||
return &rava_frame_pool[rava_frame_depth - 1];
|
||||
}
|
||||
|
||||
size_t rava_fastframe_get_depth(void) {
|
||||
return rava_frame_depth;
|
||||
}
|
||||
|
||||
void rava_fastframe_reset(void) {
|
||||
rava_frame_depth = 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef RAVA_FASTFRAME_H
|
||||
#define RAVA_FASTFRAME_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "nanbox.h"
|
||||
#include "../ir/ir.h"
|
||||
|
||||
#define RAVA_MAX_CALL_DEPTH 1024
|
||||
#define RAVA_MAX_LOCALS_FIXED 64
|
||||
#define RAVA_MAX_STACK_FIXED 512
|
||||
|
||||
typedef struct {
|
||||
RavaMethod_t* method;
|
||||
RavaNanboxValue_t locals[RAVA_MAX_LOCALS_FIXED];
|
||||
RavaNanboxValue_t stack[RAVA_MAX_STACK_FIXED];
|
||||
size_t stack_top;
|
||||
size_t pc;
|
||||
bool has_this;
|
||||
RavaNanboxValue_t this_ref;
|
||||
} FastFrame_t;
|
||||
|
||||
extern FastFrame_t rava_frame_pool[RAVA_MAX_CALL_DEPTH];
|
||||
extern size_t rava_frame_depth;
|
||||
|
||||
void rava_fastframe_init(void);
|
||||
FastFrame_t* rava_fastframe_push(RavaMethod_t* method, int local_count);
|
||||
void rava_fastframe_pop(void);
|
||||
FastFrame_t* rava_fastframe_current(void);
|
||||
size_t rava_fastframe_get_depth(void);
|
||||
void rava_fastframe_reset(void);
|
||||
|
||||
static inline void rava_fastframe_stack_push(FastFrame_t* frame, RavaNanboxValue_t v) {
|
||||
if (frame->stack_top < RAVA_MAX_STACK_FIXED) {
|
||||
frame->stack[frame->stack_top++] = v;
|
||||
}
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_fastframe_stack_pop(FastFrame_t* frame) {
|
||||
if (frame->stack_top > 0) {
|
||||
return frame->stack[--frame->stack_top];
|
||||
}
|
||||
return rava_nanbox_null();
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_fastframe_stack_peek(FastFrame_t* frame) {
|
||||
if (frame->stack_top > 0) {
|
||||
return frame->stack[frame->stack_top - 1];
|
||||
}
|
||||
return rava_nanbox_null();
|
||||
}
|
||||
|
||||
static inline void rava_fastframe_stack_clear(FastFrame_t* frame) {
|
||||
frame->stack_top = 0;
|
||||
}
|
||||
|
||||
static inline bool rava_fastframe_stack_is_empty(FastFrame_t* frame) {
|
||||
return frame->stack_top == 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "labeltable.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
LabelTable_t* rava_labeltable_create(RavaInstructionList_t* instructions) {
|
||||
if (!instructions) return NULL;
|
||||
|
||||
LabelTable_t* table = malloc(sizeof(LabelTable_t));
|
||||
if (!table) return NULL;
|
||||
|
||||
int max_label = 0;
|
||||
for (size_t i = 0; i < instructions->count; i++) {
|
||||
if (instructions->instructions[i].opcode == RAVA_OP_LABEL) {
|
||||
int lid = instructions->instructions[i].operand.label_id;
|
||||
if (lid > max_label) max_label = lid;
|
||||
}
|
||||
}
|
||||
|
||||
table->max_label_id = (size_t)max_label;
|
||||
table->label_to_pc = calloc((size_t)(max_label + 1), sizeof(int));
|
||||
if (!table->label_to_pc) {
|
||||
free(table);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= max_label; i++) {
|
||||
table->label_to_pc[i] = -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < instructions->count; i++) {
|
||||
if (instructions->instructions[i].opcode == RAVA_OP_LABEL) {
|
||||
int lid = instructions->instructions[i].operand.label_id;
|
||||
table->label_to_pc[lid] = (int)(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
void rava_labeltable_destroy(LabelTable_t* table) {
|
||||
if (!table) return;
|
||||
free(table->label_to_pc);
|
||||
free(table);
|
||||
}
|
||||
|
||||
size_t rava_labeltable_lookup(LabelTable_t* table, int label_id) {
|
||||
if (!table || label_id < 0 || (size_t)label_id > table->max_label_id) {
|
||||
return 0;
|
||||
}
|
||||
int pc = table->label_to_pc[label_id];
|
||||
return (pc >= 0) ? (size_t)pc : 0;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef RAVA_LABELTABLE_H
|
||||
#define RAVA_LABELTABLE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "../ir/ir.h"
|
||||
|
||||
typedef struct LabelTable_s {
|
||||
int* label_to_pc;
|
||||
size_t max_label_id;
|
||||
} LabelTable_t;
|
||||
|
||||
LabelTable_t* rava_labeltable_create(RavaInstructionList_t* instructions);
|
||||
void rava_labeltable_destroy(LabelTable_t* table);
|
||||
size_t rava_labeltable_lookup(LabelTable_t* table, int label_id);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "methodcache.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
MethodCache_t* rava_methodcache_create(void) {
|
||||
MethodCache_t* cache = malloc(sizeof(MethodCache_t));
|
||||
if (cache) {
|
||||
memset(cache, 0, sizeof(MethodCache_t));
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
void rava_methodcache_destroy(MethodCache_t* cache) {
|
||||
if (cache) free(cache);
|
||||
}
|
||||
|
||||
RavaMethod_t* rava_methodcache_lookup(MethodCache_t* cache,
|
||||
const char* classname,
|
||||
const char* methodname) {
|
||||
if (!cache || !classname || !methodname) return NULL;
|
||||
|
||||
uint32_t class_hash = rava_methodcache_hash(classname);
|
||||
uint32_t method_hash = rava_methodcache_hash(methodname);
|
||||
uint32_t idx = (class_hash ^ method_hash) & RAVA_METHOD_CACHE_MASK;
|
||||
|
||||
MethodCacheEntry_t* entry = &cache->entries[idx];
|
||||
|
||||
if (entry->class_hash == class_hash &&
|
||||
entry->method_hash == method_hash &&
|
||||
entry->method != NULL) {
|
||||
return entry->method;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rava_methodcache_insert(MethodCache_t* cache,
|
||||
const char* classname,
|
||||
const char* methodname,
|
||||
RavaMethod_t* method) {
|
||||
if (!cache || !classname || !methodname) return;
|
||||
|
||||
uint32_t class_hash = rava_methodcache_hash(classname);
|
||||
uint32_t method_hash = rava_methodcache_hash(methodname);
|
||||
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;
|
||||
}
|
||||
|
||||
void rava_methodcache_clear(MethodCache_t* cache) {
|
||||
if (cache) {
|
||||
memset(cache->entries, 0, sizeof(cache->entries));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef RAVA_METHODCACHE_H
|
||||
#define RAVA_METHODCACHE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "../ir/ir.h"
|
||||
|
||||
#define RAVA_METHOD_CACHE_SIZE 256
|
||||
#define RAVA_METHOD_CACHE_MASK (RAVA_METHOD_CACHE_SIZE - 1)
|
||||
|
||||
typedef struct {
|
||||
uint32_t class_hash;
|
||||
uint32_t method_hash;
|
||||
RavaMethod_t* method;
|
||||
} MethodCacheEntry_t;
|
||||
|
||||
typedef struct MethodCache_s {
|
||||
MethodCacheEntry_t entries[RAVA_METHOD_CACHE_SIZE];
|
||||
} MethodCache_t;
|
||||
|
||||
static inline uint32_t rava_methodcache_hash(const char* str) {
|
||||
uint32_t hash = 5381;
|
||||
while (*str) {
|
||||
hash = ((hash << 5) + hash) ^ (uint32_t)*str;
|
||||
str++;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
MethodCache_t* rava_methodcache_create(void);
|
||||
void rava_methodcache_destroy(MethodCache_t* cache);
|
||||
RavaMethod_t* rava_methodcache_lookup(MethodCache_t* cache,
|
||||
const char* classname,
|
||||
const char* methodname);
|
||||
void rava_methodcache_insert(MethodCache_t* cache,
|
||||
const char* classname,
|
||||
const char* methodname,
|
||||
RavaMethod_t* method);
|
||||
void rava_methodcache_clear(MethodCache_t* cache);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,156 @@
|
||||
#ifndef RAVA_NANBOX_H
|
||||
#define RAVA_NANBOX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef uint64_t RavaNanboxValue_t;
|
||||
|
||||
#define RAVA_SIGN_BIT 0x8000000000000000ULL
|
||||
#define RAVA_EXPONENT_MASK 0x7FF0000000000000ULL
|
||||
#define RAVA_QNAN 0x7FF8000000000000ULL
|
||||
#define RAVA_TAG_MASK 0xFFFF000000000000ULL
|
||||
#define RAVA_PAYLOAD_MASK 0x0000FFFFFFFFFFFFULL
|
||||
|
||||
#define RAVA_TAG_INT (RAVA_QNAN | 0x0001000000000000ULL)
|
||||
#define RAVA_TAG_LONG (RAVA_QNAN | 0x0002000000000000ULL)
|
||||
#define RAVA_TAG_BOOL (RAVA_QNAN | 0x0003000000000000ULL)
|
||||
#define RAVA_TAG_NULL (RAVA_QNAN | 0x0004000000000000ULL)
|
||||
#define RAVA_TAG_OBJECT (RAVA_QNAN | 0x0005000000000000ULL)
|
||||
#define RAVA_TAG_STRING (RAVA_QNAN | 0x0006000000000000ULL)
|
||||
#define RAVA_TAG_ARRAY (RAVA_QNAN | 0x0007000000000000ULL)
|
||||
|
||||
static inline RavaNanboxValue_t rava_nanbox_int(int32_t v) {
|
||||
return RAVA_TAG_INT | (uint64_t)(uint32_t)v;
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_nanbox_long(int64_t v) {
|
||||
return RAVA_TAG_LONG | ((uint64_t)v & RAVA_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_nanbox_bool(bool v) {
|
||||
return RAVA_TAG_BOOL | (v ? 1ULL : 0ULL);
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_nanbox_null(void) {
|
||||
return RAVA_TAG_NULL;
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_nanbox_double(double v) {
|
||||
union { double d; uint64_t u; } u = {.d = v};
|
||||
return u.u;
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_nanbox_object(void* ptr) {
|
||||
return RAVA_TAG_OBJECT | ((uint64_t)(uintptr_t)ptr & RAVA_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_nanbox_string(const char* ptr) {
|
||||
return RAVA_TAG_STRING | ((uint64_t)(uintptr_t)ptr & RAVA_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline RavaNanboxValue_t rava_nanbox_array(void* ptr) {
|
||||
return RAVA_TAG_ARRAY | ((uint64_t)(uintptr_t)ptr & RAVA_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_is_int(RavaNanboxValue_t v) {
|
||||
return (v & RAVA_TAG_MASK) == RAVA_TAG_INT;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_is_long(RavaNanboxValue_t v) {
|
||||
return (v & RAVA_TAG_MASK) == RAVA_TAG_LONG;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_is_bool(RavaNanboxValue_t v) {
|
||||
return (v & RAVA_TAG_MASK) == RAVA_TAG_BOOL;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_is_null(RavaNanboxValue_t v) {
|
||||
return v == RAVA_TAG_NULL;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_is_object(RavaNanboxValue_t v) {
|
||||
return (v & RAVA_TAG_MASK) == RAVA_TAG_OBJECT;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_is_string(RavaNanboxValue_t v) {
|
||||
return (v & RAVA_TAG_MASK) == RAVA_TAG_STRING;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_is_array(RavaNanboxValue_t v) {
|
||||
return (v & RAVA_TAG_MASK) == RAVA_TAG_ARRAY;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_is_double(RavaNanboxValue_t v) {
|
||||
return (v & RAVA_QNAN) != RAVA_QNAN;
|
||||
}
|
||||
|
||||
static inline int32_t rava_nanbox_as_int(RavaNanboxValue_t v) {
|
||||
return (int32_t)(v & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static inline int64_t rava_nanbox_as_long(RavaNanboxValue_t v) {
|
||||
int64_t payload = (int64_t)(v & RAVA_PAYLOAD_MASK);
|
||||
if (payload & 0x800000000000ULL) {
|
||||
payload |= (int64_t)0xFFFF000000000000ULL;
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_as_bool(RavaNanboxValue_t v) {
|
||||
return (v & 1) != 0;
|
||||
}
|
||||
|
||||
static inline double rava_nanbox_as_double(RavaNanboxValue_t v) {
|
||||
union { double d; uint64_t u; } u = {.u = v};
|
||||
return u.d;
|
||||
}
|
||||
|
||||
static inline void* rava_nanbox_as_object(RavaNanboxValue_t v) {
|
||||
return (void*)(uintptr_t)(v & RAVA_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline const char* rava_nanbox_as_string(RavaNanboxValue_t v) {
|
||||
return (const char*)(uintptr_t)(v & RAVA_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline void* rava_nanbox_as_array(RavaNanboxValue_t v) {
|
||||
return (void*)(uintptr_t)(v & RAVA_PAYLOAD_MASK);
|
||||
}
|
||||
|
||||
static inline int32_t rava_nanbox_to_int(RavaNanboxValue_t v) {
|
||||
if (rava_nanbox_is_int(v)) return rava_nanbox_as_int(v);
|
||||
if (rava_nanbox_is_long(v)) return (int32_t)rava_nanbox_as_long(v);
|
||||
if (rava_nanbox_is_bool(v)) return rava_nanbox_as_bool(v) ? 1 : 0;
|
||||
if (rava_nanbox_is_double(v)) return (int32_t)rava_nanbox_as_double(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int64_t rava_nanbox_to_long(RavaNanboxValue_t v) {
|
||||
if (rava_nanbox_is_int(v)) return (int64_t)rava_nanbox_as_int(v);
|
||||
if (rava_nanbox_is_long(v)) return rava_nanbox_as_long(v);
|
||||
if (rava_nanbox_is_bool(v)) return rava_nanbox_as_bool(v) ? 1 : 0;
|
||||
if (rava_nanbox_is_double(v)) return (int64_t)rava_nanbox_as_double(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline double rava_nanbox_to_double(RavaNanboxValue_t v) {
|
||||
if (rava_nanbox_is_double(v)) return rava_nanbox_as_double(v);
|
||||
if (rava_nanbox_is_int(v)) return (double)rava_nanbox_as_int(v);
|
||||
if (rava_nanbox_is_long(v)) return (double)rava_nanbox_as_long(v);
|
||||
if (rava_nanbox_is_bool(v)) return rava_nanbox_as_bool(v) ? 1.0 : 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static inline bool rava_nanbox_to_bool(RavaNanboxValue_t v) {
|
||||
if (rava_nanbox_is_null(v)) return false;
|
||||
if (rava_nanbox_is_bool(v)) return rava_nanbox_as_bool(v);
|
||||
if (rava_nanbox_is_int(v)) return rava_nanbox_as_int(v) != 0;
|
||||
if (rava_nanbox_is_long(v)) return rava_nanbox_as_long(v) != 0;
|
||||
if (rava_nanbox_is_double(v)) return rava_nanbox_as_double(v) != 0.0;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
+2810
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,149 @@
|
||||
#ifndef RAVA_RUNTIME_H
|
||||
#define RAVA_RUNTIME_H
|
||||
|
||||
#include "../ir/ir.h"
|
||||
#include "../types/types.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
|
||||
} 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;
|
||||
|
||||
struct RavaObject_t {
|
||||
char *class_name;
|
||||
char **field_names;
|
||||
RavaValue_t *field_values;
|
||||
size_t field_count;
|
||||
size_t field_capacity;
|
||||
};
|
||||
|
||||
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;
|
||||
} data;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
typedef struct {
|
||||
char *class_name;
|
||||
char *field_name;
|
||||
RavaValue_t value;
|
||||
} RavaStaticField_t;
|
||||
|
||||
typedef struct {
|
||||
RavaStaticField_t *fields;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
} RavaStaticFieldTable_t;
|
||||
|
||||
struct MethodCache_s;
|
||||
|
||||
typedef struct {
|
||||
RavaProgram_t *program;
|
||||
RavaCallStack_t *call_stack;
|
||||
RavaStaticFieldTable_t *static_fields;
|
||||
struct MethodCache_s *method_cache;
|
||||
char *error_message;
|
||||
bool had_error;
|
||||
} 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);
|
||||
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);
|
||||
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);
|
||||
RavaValue_t rava_value_object(RavaObject_t *obj);
|
||||
|
||||
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);
|
||||
void 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);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,149 @@
|
||||
#include "superinst.h"
|
||||
#include <string.h>
|
||||
|
||||
static void optimize_inc_dec_local(RavaInstruction_t *instrs, size_t count) {
|
||||
for (size_t i = 0; i + 3 < count; i++) {
|
||||
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+1].opcode == RAVA_OP_LOAD_CONST &&
|
||||
instrs[i+1].operand.int_value == 1 &&
|
||||
instrs[i+2].opcode == RAVA_OP_ADD &&
|
||||
instrs[i+3].opcode == RAVA_OP_STORE_LOCAL &&
|
||||
instrs[i].operand.var.index == instrs[i+3].operand.var.index) {
|
||||
|
||||
instrs[i].opcode = RAVA_OP_INC_LOCAL;
|
||||
instrs[i+1].opcode = RAVA_OP_NOP;
|
||||
instrs[i+2].opcode = RAVA_OP_NOP;
|
||||
instrs[i+3].opcode = RAVA_OP_NOP;
|
||||
}
|
||||
|
||||
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+1].opcode == RAVA_OP_LOAD_CONST &&
|
||||
instrs[i+1].operand.int_value == 1 &&
|
||||
instrs[i+2].opcode == RAVA_OP_SUB &&
|
||||
instrs[i+3].opcode == RAVA_OP_STORE_LOCAL &&
|
||||
instrs[i].operand.var.index == instrs[i+3].operand.var.index) {
|
||||
|
||||
instrs[i].opcode = RAVA_OP_DEC_LOCAL;
|
||||
instrs[i+1].opcode = RAVA_OP_NOP;
|
||||
instrs[i+2].opcode = RAVA_OP_NOP;
|
||||
instrs[i+3].opcode = RAVA_OP_NOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void optimize_loop_comparison(RavaInstruction_t *instrs, size_t count) {
|
||||
for (size_t i = 0; i + 3 < count; i++) {
|
||||
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+1].opcode == RAVA_OP_LOAD_CONST &&
|
||||
instrs[i+2].opcode == RAVA_OP_LT &&
|
||||
instrs[i+3].opcode == RAVA_OP_JUMP_IF_FALSE) {
|
||||
|
||||
int local_idx = instrs[i].operand.var.index;
|
||||
int64_t const_val = instrs[i+1].operand.int_value;
|
||||
int label = instrs[i+3].operand.label_id;
|
||||
|
||||
instrs[i].opcode = RAVA_OP_LOAD_LOCAL_CONST_LT_JUMPFALSE;
|
||||
instrs[i].operand.super.local_index = local_idx;
|
||||
instrs[i].operand.super.const_value = const_val;
|
||||
instrs[i].operand.super.label_id = label;
|
||||
|
||||
instrs[i+1].opcode = RAVA_OP_NOP;
|
||||
instrs[i+2].opcode = RAVA_OP_NOP;
|
||||
instrs[i+3].opcode = RAVA_OP_NOP;
|
||||
}
|
||||
|
||||
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+1].opcode == RAVA_OP_LOAD_CONST &&
|
||||
instrs[i+2].opcode == RAVA_OP_LE &&
|
||||
instrs[i+3].opcode == RAVA_OP_JUMP_IF_FALSE) {
|
||||
|
||||
int local_idx = instrs[i].operand.var.index;
|
||||
int64_t const_val = instrs[i+1].operand.int_value;
|
||||
int label = instrs[i+3].operand.label_id;
|
||||
|
||||
instrs[i].opcode = RAVA_OP_LOAD_LOCAL_CONST_LE_JUMPFALSE;
|
||||
instrs[i].operand.super.local_index = local_idx;
|
||||
instrs[i].operand.super.const_value = const_val;
|
||||
instrs[i].operand.super.label_id = label;
|
||||
|
||||
instrs[i+1].opcode = RAVA_OP_NOP;
|
||||
instrs[i+2].opcode = RAVA_OP_NOP;
|
||||
instrs[i+3].opcode = RAVA_OP_NOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void optimize_two_locals(RavaInstruction_t *instrs, size_t count) {
|
||||
for (size_t i = 0; i + 1 < count; i++) {
|
||||
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+1].opcode == RAVA_OP_LOAD_LOCAL) {
|
||||
|
||||
int idx1 = instrs[i].operand.var.index;
|
||||
int idx2 = instrs[i+1].operand.var.index;
|
||||
|
||||
instrs[i].opcode = RAVA_OP_LOAD_TWO_LOCALS;
|
||||
instrs[i].operand.two_locals.index1 = idx1;
|
||||
instrs[i].operand.two_locals.index2 = idx2;
|
||||
|
||||
instrs[i+1].opcode = RAVA_OP_NOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void optimize_add_local_to_local(RavaInstruction_t *instrs, size_t count) {
|
||||
for (size_t i = 0; i + 3 < count; i++) {
|
||||
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+1].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+2].opcode == RAVA_OP_ADD &&
|
||||
instrs[i+3].opcode == RAVA_OP_STORE_LOCAL &&
|
||||
instrs[i].operand.var.index == instrs[i+3].operand.var.index) {
|
||||
|
||||
int dest_idx = instrs[i].operand.var.index;
|
||||
int src_idx = instrs[i+1].operand.var.index;
|
||||
|
||||
instrs[i].opcode = RAVA_OP_ADD_LOCAL_TO_LOCAL;
|
||||
instrs[i].operand.add_locals.dest_index = dest_idx;
|
||||
instrs[i].operand.add_locals.src_index = src_idx;
|
||||
|
||||
instrs[i+1].opcode = RAVA_OP_NOP;
|
||||
instrs[i+2].opcode = RAVA_OP_NOP;
|
||||
instrs[i+3].opcode = RAVA_OP_NOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void optimize_local_lt_local_jump(RavaInstruction_t *instrs, size_t count) {
|
||||
for (size_t i = 0; i + 3 < count; i++) {
|
||||
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+1].opcode == RAVA_OP_LOAD_LOCAL &&
|
||||
instrs[i+2].opcode == RAVA_OP_LT &&
|
||||
instrs[i+3].opcode == RAVA_OP_JUMP_IF_FALSE) {
|
||||
|
||||
int local1 = instrs[i].operand.var.index;
|
||||
int local2 = instrs[i+1].operand.var.index;
|
||||
int label = instrs[i+3].operand.label_id;
|
||||
|
||||
instrs[i].opcode = RAVA_OP_LOAD_LOCAL_LT_LOCAL_JUMPFALSE;
|
||||
instrs[i].operand.cmp_locals.local1 = local1;
|
||||
instrs[i].operand.cmp_locals.local2 = local2;
|
||||
instrs[i].operand.cmp_locals.label_id = label;
|
||||
|
||||
instrs[i+1].opcode = RAVA_OP_NOP;
|
||||
instrs[i+2].opcode = RAVA_OP_NOP;
|
||||
instrs[i+3].opcode = RAVA_OP_NOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rava_optimize_superinstructions(RavaMethod_t* method) {
|
||||
if (!method || !method->instructions) return;
|
||||
|
||||
RavaInstruction_t *instrs = method->instructions->instructions;
|
||||
size_t count = method->instructions->count;
|
||||
|
||||
optimize_add_local_to_local(instrs, count);
|
||||
optimize_local_lt_local_jump(instrs, count);
|
||||
optimize_inc_dec_local(instrs, count);
|
||||
optimize_loop_comparison(instrs, count);
|
||||
optimize_two_locals(instrs, count);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef RAVA_SUPERINST_H
|
||||
#define RAVA_SUPERINST_H
|
||||
|
||||
#include "../ir/ir.h"
|
||||
|
||||
void rava_optimize_superinstructions(RavaMethod_t* method);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user