2009-02-02 8 views

Antwort

9

Okay, zuerst nehmen Sie alle Ihre Code-Snippets und Refactor sie in ihre eigenen Funktionen. Ihr Code lautet also:

void addOpcode(uint32_t *result, uint32_t L, uint32_t R) { 
    *result = L + R; 
} 

switch (opcode) { 
    case ADD: 
      addOpcode(&result, L, R); 
      break; 
    .... 

Okay, also sollte Ihr Dolmetscher nach diesem Schritt noch laufen. Nehmen Sie nun alle neuen Funktionen und legen Sie sie in eine eigene Datei. Kompilieren Sie diese Datei nun entweder mit llvm-gcc oder mit clang und kompilieren Sie sie nicht mit dem nativen Code, sondern verwenden Sie die "cpp" backend (-march -cpp). Das erzeugt C++ - Code, der den Bytecode für die Kompilierungseinheit instanziiert. Sie können Optionen angeben, um sie auf bestimmte Funktionen usw. zu beschränken. Wahrscheinlich möchten Sie "-cppgen module" verwenden.

Jetzt zurück Ihre Interpreter-Schleife Leim zusammen Aufrufe an die generierte C++ - Code statt direkt Ausführen des ursprünglichen Codes, dann übergeben Sie es an einige Optimierer und einen nativen Codegenerator. Gratz auf der JIT ;-) Sie können ein Beispiel dafür in ein paar LLVM-Projekten sehen, wie die vm_ops in llvm-lua.

+0

Wunderbar! Ich dachte, es wäre so etwas, mit LLVM inline alle Funktionen. – joeforker

+0

Wie sieht das mit einem Call-Threaded-Interpreter, wo Sie nur eine Reihe von CALL-Anweisungen zu jeder Bytecode-Implementierung JIT, die Implementierung von nur ein paar Opcodes wahrscheinlich BRANCH Opcodes, und jede Opcode-Implementierung endet mit RET? – joeforker

+0

Dem folge ich nicht ganz. Wollen Sie alle Opcode-Funktionen an LLVM übergeben, und wenn Sie es wieder an C ausgeben, wird automatisch ein JIT eingebaut? – Unknown