Permalink
Browse files

Implement interpreter loop rather than indirect jumps

  • Loading branch information...
1 parent eed60f1 commit 1e4989ccf6d76a13c888a122be8c9b1f79ce99e3 @tadeuzagallo committed May 4, 2016
Showing with 72 additions and 165 deletions.
  1. +71 −10 compiler/interpreter.S
  2. +1 −155 compiler/vm.cc
@@ -12,7 +12,7 @@
.macro skip
mov $0, %rax
lea (BYTECODE, %rax, 8), BYTECODE
- jmp *(BYTECODE)
+ jmp _loop
.endmacro
.macro unmask
@@ -29,7 +29,7 @@
pop %r15
.endmacro
- .globl _execute
+.globl _execute
_execute:
push %rbp
push BYTECODE
@@ -39,9 +39,54 @@ _execute:
mov %rdi, BYTECODE
mov %rsi, STRINGS
mov %rdx, VM
- jmp *(BYTECODE)
-.globl _op_exit
+_loop:
+ mov (BYTECODE), %rax // 0..10
+ lea (%rip), %rdi
+ lea 0x7(%rdi, %rax, 8), %rdi
+ jmp *%rdi
+ jmp _op_ret
+ nop
+ nop
+ nop
+ jmp _op_bind
+ nop
+ nop
+ nop
+ jmp _op_push
+ nop
+ nop
+ nop
+ jmp _op_call
+ nop
+ nop
+ nop
+ jmp _op_jz
+ nop
+ nop
+ nop
+ jmp _op_jmp
+ nop
+ nop
+ nop
+ jmp _op_create_closure
+ nop
+ nop
+ nop
+ jmp _op_load_string
+ nop
+ nop
+ nop
+ jmp _op_push_arg
+ nop
+ nop
+ nop
+ jmp _op_lookup
+ nop
+ nop
+ nop
+ jmp _op_exit
+
_op_exit:
mov %rbp, %rsp
pop VM
@@ -50,13 +95,11 @@ _op_exit:
pop %rbp
ret
-.globl _op_push
_op_push:
read $1, %rdi
push %rdi
skip $2
-.globl _op_lookup
_op_lookup:
mov VM, %rdi
read $1, %rsi
@@ -65,22 +108,22 @@ _op_lookup:
push %rax
skip $2
-.globl _op_call
_op_call:
+ // pop the callee from the stack
+ pop %r8
+
// setup args
read $1, %rdi //argc
- lea (%rsp, %rdi, 8), %rsi // argv
+ mov %rsp, %rsi // argv just live in the stack
mov VM, %rdx
// setup callee
- pop %r8
unmask %r8
ccall *%r8
push %rax
skip $2
-.globl _op_load_string
_op_load_string:
read $1, %rdi
mov (STRINGS, %rdi, 8), %rdi
@@ -89,3 +132,21 @@ _op_load_string:
ror $8, %rdi
push %rdi
skip $2
+
+_op_create_closure:
+ hlt
+
+_op_bind:
+ hlt
+
+_op_jz:
+ hlt
+
+_op_jmp:
+ hlt
+
+_op_ret:
+ hlt
+
+_op_push_arg:
+ hlt
View
@@ -5,12 +5,6 @@
#include <cassert>
-extern "C" void op_push();
-extern "C" void op_lookup();
-extern "C" void op_call();
-extern "C" void op_load_string();
-extern "C" void op_exit();
-
namespace ceos {
extern "C" void execute(
@@ -64,7 +58,7 @@ uint64_t prepareClosure(unsigned argc, Value *args, Value fnAddress, VM *vm) {
loadFunctions();
break;
case Section::Text:
- run();
+ ::ceos::execute(m_bytecode + pc, m_stringTable.data(), this);
return;
default:
std::cerr << "Unknown section: `0x0" << std::hex << section << "`\n";
@@ -113,154 +107,6 @@ uint64_t prepareClosure(unsigned argc, Value *args, Value fnAddress, VM *vm) {
}
}
- void VM::run() {
- inflate();
- ::ceos::execute(m_bytecode + pc, m_stringTable.data(), this);
- }
-
- void VM::inflate() {
- auto _pc = pc;
- while (true) {
- auto opcode = (int)read<uint64_t>();
-
- if (pc > length) {
- break;
- }
-
-#define LINK(opcode, argc) \
- case Opcode:: opcode : \
- *((uint64_t *)(m_bytecode + pc - 8)) = (uint64_t)op_##opcode; \
- pc += argc * sizeof(uint64_t); \
- break;
-
- switch (opcode) {
- LINK(push, 1)
- LINK(lookup, 1)
- LINK(call, 1)
- LINK(load_string, 1)
- LINK(exit, 0)
- //LINK(bind, 0)
- default:
- std::cerr << "Unhandled opcode: " << Opcode::typeName(static_cast<Opcode::Type>(opcode)) << "\n";
- throw;
- }
- }
- pc = _pc;
- }
- //while (true) {
- //auto opcode = read<int>();
-
- //if (pc > length) {
- //return;
- //}
-
- //switch (opcode) {
- //case Opcode::push: {
- //auto value = read<int>();
- //stack_push(value);
- //break;
- //}
- //case Opcode::call: {
- //auto nargs = read<unsigned>();
- //Value fn_address = stack_pop();
-
- //stack_push(pc);
- //stack_push(nargs);
- //stack_push(ebp);
- //ebp = esp;
-
- //if (fn_address.isClosure()) {
- //auto closure = fn_address.asClosure();
-
- //m_scope = m_scope->create(closure->scope);
-
- //for (unsigned i = 0; i < nargs; i++) {
- //m_scope->set(closure->fn->arg(i), arg(i));
- //}
-
- //pc = closure->fn->offset;
- //break;
- //} else {
- //m_scope = m_scope->create();
-
- //Builtin fn = fn_address.asBuiltin();
- //Value ret = fn(*this, nargs);
- //stack_push(ret);
- //}
- //}
- //case Opcode::ret: {
- //Value ret = stack_pop();
-
- //esp = ebp;
-
- //ebp = stack_pop().asInt();
- //unsigned nargs = stack_pop().asInt();
- //auto ret_addr = stack_pop().asInt();
-
- //esp -= nargs;
-
- //stack_push(ret);
- //pc = ret_addr;
-
- //m_scope = m_scope->restore();
-
- //break;
- //}
- //case Opcode::load_string: {
- //auto stringID = read<int>();
- //stack_push(Value(&m_stringTable[stringID]));
- //break;
- //}
- //case Opcode::lookup: {
- //auto id = read<int>();
- //auto name = m_stringTable[id];
- //auto value = m_scope->get(name);
- //if (value.isUndefined()) {
- //std::cerr << "Symbol not found: " << name << "\n";
- //throw;
- //}
- //stack_push(value);
- //break;
- //}
- //case Opcode::jmp: {
- //auto target = read<int>();
- //pc += target;
- //break;
- //}
- //case Opcode::jz: {
- //auto target = read<int>();
- //int value = stack_pop().asInt();
- //if (value == 0) {
- //pc += target;
- //}
- //break;
- //}
- //case Opcode::push_arg: {
- //auto index = read<int>();
- //stack_push(arg(index));
- //break;
- //}
- //case Opcode::create_closure: {
- //auto fnID = read<int>();
- //auto closure = new Closure();
- //trackAllocation(closure, sizeof(Closure));
- //closure->fn = &m_userFunctions[fnID];
- //closure->scope = m_scope;
- //stack_push(Value(closure));
- //break;
- //}
- //case Opcode::bind: {
- //auto address = stack_pop();
- //auto closure = address.asClosure();
- //m_scope->set(closure->fn->name(this), address);
- //break;
- //}
- //default:
- //std::cerr << "Unhandled opcode: " << Opcode::typeName(static_cast<Opcode::Type>(opcode)) << "\n";
- //throw;
- //}
- //}
-
void VM::trackAllocation(void *ptr, size_t size) {
heapSize += size;

0 comments on commit 1e4989c

Please sign in to comment.