aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fvm.c18
-rw-r--r--src/fvm.h11
2 files changed, 21 insertions, 8 deletions
diff --git a/src/fvm.c b/src/fvm.c
index 858bd4a..6326dc8 100644
--- a/src/fvm.c
+++ b/src/fvm.c
@@ -10,6 +10,7 @@ int fvm_init(struct fvm *vm, void *code, int64_t stack_size) {
vm->sp = (fvm_word_t)(stack_vm + stack_size);
vm->bp = vm->sp;
vm->pc = (fvm_word_t)code;
+ vm->rv = 0;
return 1;
}
@@ -74,14 +75,15 @@ void fvm_store8(struct fvm *vm, fvm_word_t addr, int8_t value) {
}
-int fvm_execute(struct fvm *vm) {
+int64_t fvm_execute(struct fvm *vm) {
fvm_word_t a, b, c;
fvm_float_t x, y, z;
while (1) {
enum fvm_op op = (enum fvm_op)(uint8_t)fvm_load8(vm, vm->pc);
switch (op) {
case FVM_OP_SP:
- fvm_push(vm, vm->sp);
+ a = vm->sp;
+ fvm_push(vm, a);
vm->pc++;
break;
case FVM_OP_SSP:
@@ -96,6 +98,15 @@ int fvm_execute(struct fvm *vm) {
vm->bp = fvm_pop(vm);
vm->pc++;
break;
+ case FVM_OP_RV:
+ a = vm->rv;
+ fvm_push(vm, a);
+ vm->pc++;
+ break;
+ case FVM_OP_SRV:
+ vm->rv = fvm_pop(vm);
+ vm->pc++;
+ break;
case FVM_OP_PC:
fvm_push(vm, vm->pc);
vm->pc++;
@@ -410,8 +421,7 @@ int fvm_execute(struct fvm *vm) {
vm->pc++;
break;
case FVM_OP_EXIT:
- a = fvm_pop(vm);
- return a;
+ return vm->rv;
default:
fprintf(stderr, "unknown opcode.\n");
break;
diff --git a/src/fvm.h b/src/fvm.h
index bfa5888..8d8cb87 100644
--- a/src/fvm.h
+++ b/src/fvm.h
@@ -12,9 +12,10 @@ struct fvm;
typedef int64_t (*fvm_syscall_fn_t)(struct fvm* vm);
struct fvm {
- fvm_word_t sp;
- fvm_word_t bp;
- fvm_word_t pc;
+ fvm_word_t sp; // stack pointer
+ fvm_word_t bp; // base pointer
+ fvm_word_t pc; // programm counter
+ fvm_word_t rv; // return value
fvm_syscall_fn_t *syscall_table;
};
@@ -24,6 +25,8 @@ enum fvm_op {
FVM_OP_BP,
FVM_OP_SBP,
FVM_OP_PC,
+ FVM_OP_RV,
+ FVM_OP_SRV,
FVM_OP_IMM,
@@ -95,7 +98,7 @@ enum fvm_op {
};
int fvm_init(struct fvm *vm, void *code, int64_t stack_size);
-int fvm_execute(struct fvm *vm);
+int64_t fvm_execute(struct fvm *vm);
void fvm_push(struct fvm *vm, fvm_word_t value);
int64_t fvm_pop(struct fvm *vm);