.
This commit is contained in:
2
Makefile
2
Makefile
@@ -87,7 +87,7 @@ lib/compiler.o: lib/compiler.c lib/compiler/compiler.lua.h
|
|||||||
# executable files
|
# executable files
|
||||||
#
|
#
|
||||||
|
|
||||||
LIB_SRC=lib/value.o lib/stack.o lib/array.o lib/table.o lib/heap.o lib/vm.o lib/compiler.o lib/code.o lib/utils.o
|
LIB_SRC=lib/value.o lib/stack.o lib/array.o lib/table.o lib/heap.o lib/vm.o lib/step.o lib/compiler.o lib/code.o lib/utils.o
|
||||||
|
|
||||||
tyche: CFLAGS += ${RELEASE_CFLAGS}
|
tyche: CFLAGS += ${RELEASE_CFLAGS}
|
||||||
tyche: LDFLAGS += ${RELEASE_LDFLAGS}
|
tyche: LDFLAGS += ${RELEASE_LDFLAGS}
|
||||||
|
|||||||
@@ -225,4 +225,10 @@ const char* code_const_string(Code const* code, size_t n);
|
|||||||
uint32_t code_n_functions(Code const* code);
|
uint32_t code_n_functions(Code const* code);
|
||||||
Instruction code_next_instruction(Code const* code, uint32_t function_id, uint32_t pc);
|
Instruction code_next_instruction(Code const* code, uint32_t function_id, uint32_t pc);
|
||||||
|
|
||||||
|
//
|
||||||
|
// VM
|
||||||
|
//
|
||||||
|
|
||||||
|
TYC_RESULT step(TycheVM* T);
|
||||||
|
|
||||||
#endif //TYCHE_PRIV_H
|
#endif //TYCHE_PRIV_H
|
||||||
|
|||||||
10
lib/step.c
Normal file
10
lib/step.c
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include "priv.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
TYC_RESULT step(TycheVM* T)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
return T_OK;
|
||||||
|
}
|
||||||
|
|
||||||
103
lib/vm.c
103
lib/vm.c
@@ -2,39 +2,138 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct Location {
|
||||||
|
uint32_t function_id;
|
||||||
|
uint32_t pc;
|
||||||
|
} Location;
|
||||||
|
|
||||||
|
typedef struct LocationStack {
|
||||||
|
Location* locations;
|
||||||
|
size_t sz;
|
||||||
|
size_t cap;
|
||||||
|
} LocationStack;
|
||||||
|
|
||||||
struct TycheVM {
|
struct TycheVM {
|
||||||
Stack* stack;
|
Stack* stack;
|
||||||
Heap* heap;
|
Heap* heap;
|
||||||
Code* code;
|
Code* code;
|
||||||
|
LocationStack location_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// CREATE/DESTROY VM
|
||||||
|
//
|
||||||
|
|
||||||
TycheVM* tyc_new(void)
|
TycheVM* tyc_new(void)
|
||||||
{
|
{
|
||||||
TycheVM* t = xcalloc(1, sizeof(TycheVM));
|
TycheVM* t = xcalloc(1, sizeof(TycheVM));
|
||||||
t->stack = stack_new();
|
t->stack = stack_new();
|
||||||
t->heap = heap_new();
|
t->heap = heap_new();
|
||||||
t->code = code_new();
|
t->code = code_new();
|
||||||
|
t->location_stack = (LocationStack) {
|
||||||
|
.locations = xmalloc(4 * sizeof(Location)),
|
||||||
|
.cap = 4,
|
||||||
|
.sz = 0,
|
||||||
|
};
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tyc_destroy(TycheVM* t)
|
void tyc_destroy(TycheVM* t)
|
||||||
{
|
{
|
||||||
|
free(t->location_stack.locations);
|
||||||
code_destroy(t->code);
|
code_destroy(t->code);
|
||||||
heap_destroy(t->heap);
|
heap_destroy(t->heap);
|
||||||
stack_destroy(t->stack);
|
stack_destroy(t->stack);
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LOCATION STACK
|
||||||
|
//
|
||||||
|
|
||||||
|
static void push_location(TycheVM* T, uint32_t function_id, uint32_t pc)
|
||||||
|
{
|
||||||
|
if (T->location_stack.sz == T->location_stack.cap) {
|
||||||
|
T->location_stack.cap *= 2;
|
||||||
|
T->location_stack.locations = xrealloc(T->location_stack.locations, T->location_stack.cap * sizeof(Location));
|
||||||
|
}
|
||||||
|
|
||||||
|
T->location_stack.locations[T->location_stack.sz] = (Location) {
|
||||||
|
.function_id = function_id,
|
||||||
|
.pc = pc,
|
||||||
|
};
|
||||||
|
++T->location_stack.sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// CODE LOADING AND EXECUTION
|
||||||
|
//
|
||||||
|
|
||||||
TYC_RESULT tyc_load_bytecode(TycheVM* T, uint8_t const* bytecode, size_t bytecode_sz)
|
TYC_RESULT tyc_load_bytecode(TycheVM* T, uint8_t const* bytecode, size_t bytecode_sz)
|
||||||
{
|
{
|
||||||
return code_load_bytecode(T->code, bytecode, bytecode_sz);
|
TYC_RESULT r;
|
||||||
|
if ((r = code_load_bytecode(T->code, bytecode, bytecode_sz)) != T_OK)
|
||||||
|
return r;
|
||||||
|
if ((r = stack_push(T->stack, create_value_idx(TT_FUNCTION, 0 /* main */))) != T_OK)
|
||||||
|
return r;
|
||||||
|
return T_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TYC_RESULT enter_function(TycheVM* T, uint16_t n_pars)
|
||||||
|
{
|
||||||
|
TYC_RESULT r;
|
||||||
|
|
||||||
|
// get parameters
|
||||||
|
VALUE params[n_pars + 1];
|
||||||
|
for (uint16_t i = 0; i < n_pars; ++i)
|
||||||
|
if ((r = stack_pop(T->stack, ¶ms[i])) != T_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
// get function
|
||||||
|
VALUE function;
|
||||||
|
if ((r = stack_pop(T->stack, &function)) != T_OK)
|
||||||
|
return r;
|
||||||
|
if (value_type(function) != TT_FUNCTION)
|
||||||
|
return T_ERR_TYPE_UNEXPECTED;
|
||||||
|
|
||||||
|
// enter function
|
||||||
|
push_location(T, value_idx(function), 0);
|
||||||
|
stack_push_fp(T->stack);
|
||||||
|
|
||||||
|
// pass parameters
|
||||||
|
for (int i = n_pars-1; i >= 0; --i)
|
||||||
|
if ((r = stack_push(T->stack, params[i])) != T_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return T_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TYC_RESULT run_until_return(TycheVM* T)
|
||||||
|
{
|
||||||
|
TYC_RESULT r;
|
||||||
|
|
||||||
|
size_t level = stack_fp_level(T->stack);
|
||||||
|
while (stack_fp_level(T->stack) >= level)
|
||||||
|
if ((r = step(T)) != T_OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return T_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYC_RESULT tyc_call(TycheVM* T, uint16_t n_pars)
|
TYC_RESULT tyc_call(TycheVM* T, uint16_t n_pars)
|
||||||
{
|
{
|
||||||
abort(); // TODO
|
TYC_RESULT r;
|
||||||
|
if ((r = enter_function(T, n_pars)) != T_OK)
|
||||||
|
return r;
|
||||||
|
if ((r = run_until_return(T)) != T_OK)
|
||||||
|
return r;
|
||||||
|
return T_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// STACK MANIPULATION AND QUERY
|
||||||
|
//
|
||||||
|
|
||||||
size_t tyc_stack_size(TycheVM* T)
|
size_t tyc_stack_size(TycheVM* T)
|
||||||
{
|
{
|
||||||
return stack_len(T->stack);
|
return stack_len(T->stack);
|
||||||
|
|||||||
Reference in New Issue
Block a user