49 lines
1.1 KiB
C
49 lines
1.1 KiB
C
#pragma once
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
#include "vector.h"
|
|
#include "stack.h"
|
|
|
|
#define FLAG_REF (1ULL << 63)
|
|
|
|
struct vm_value;
|
|
|
|
static inline uint64_t encode_ref(struct vm_value *ref) {
|
|
uintptr_t addr = (uintptr_t) ref;
|
|
assert(!(addr & 1));
|
|
if (sizeof(uintptr_t) == 8) {
|
|
return (addr >> 1) | FLAG_REF;
|
|
} else {
|
|
assert(0 && "TODO");
|
|
}
|
|
}
|
|
|
|
struct vm_state {
|
|
struct stack data_stack;
|
|
struct stack call_stack;
|
|
|
|
struct vector units;
|
|
size_t lp, fp, ip;
|
|
};
|
|
|
|
int vm_state_init(struct vm_state *vm, size_t stack_size);
|
|
void vm_state_free(struct vm_state *vm);
|
|
|
|
struct vm_unit *vm_add_unit(struct vm_state *vm, size_t stack_size);
|
|
|
|
// Bytecode interpretation
|
|
int vm_eval_step(struct vm_state *vm);
|
|
int vm_eval_unit(struct vm_state *vm, size_t index);
|
|
|
|
// Stack operation
|
|
int vm_pop(struct vm_state *vm, uint64_t *w);
|
|
int vm_pop_integer(struct vm_state *vm, int64_t *v);
|
|
|
|
int vm_push_integer(struct vm_state *vm, int64_t v);
|
|
int vm_push_bool(struct vm_state *vm, int v);
|
|
int vm_push_ref(struct vm_state *vm, struct vm_value *obj);
|
|
|
|
uint64_t vm_get_arg(struct vm_state *vm, size_t index);
|