Created
November 30, 2018 00:43
-
-
Save thedeemon/980442af0ef5619fe5ae8a8dafcb8db7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "lvm2jit.h" | |
#include <stdio.h> | |
#include <vector> | |
LVM2jit::LVM2jit(int stacksize, int heapsize) | |
: fun(NULL) | |
{ | |
frame = (int*)calloc(stacksize, 1); | |
heap = (BYTE*)calloc(heapsize, 1); | |
callstack = (context_t*)calloc(10000, sizeof(context_t)); | |
//a.setLogger(&logger); | |
} | |
LVM2jit::~LVM2jit() | |
{ | |
free(frame); | |
free(heap); | |
free(callstack); | |
} | |
char logname[1024] = {0}; | |
FILE *f = NULL; | |
void print_int(int x) | |
{ | |
if (!f) f = fopen(logname, "a"); | |
fprintf(f, "%d ", x); | |
} | |
void print_char(char c) | |
{ | |
if (!f) f = fopen(logname, "a"); | |
fprintf(f, "%c", c); | |
} | |
int LVM2jit::Compile(const int *code, int codelen) | |
{ | |
int ip = 0, hp = 0, fp = 0, csp = 0; | |
const int frame_addr = (int)frame; | |
const int arg_offset = 4 + 4; | |
std::vector<Label*> labels(codelen+1); | |
// Prolog. | |
a.push(ebp); | |
a.mov(ebp, esp); | |
a.push(edi); | |
a.push(esi); | |
a.mov(edi, imm(frame_addr)); //edi = frame | |
a.mov(esi, imm((int)heap)); //esi = heap | |
//frame[0] = (int)params; | |
a.mov(eax, dword_ptr(ebp, arg_offset + 0)); | |
a.mov(dword_ptr(edi), eax); | |
ip = 0; | |
while(ip<codelen) { | |
switch(code[ip] & 0xFF) { | |
case ADD: ip += 4; break; | |
case MUL: ip += 4; break; | |
case MOD: ip += 4; break; | |
case SUB: ip += 4; break; | |
case DIV: ip += 4; break; | |
case XOR: ip += 4; break; | |
case MOV: ip += 3; break; | |
case MOVB: ip += 3; break; | |
case JMPLE: | |
if (!labels[code[ip+1]]) | |
labels[code[ip+1]] = new Label(); | |
ip += 4; break; | |
case JMPEQ: | |
if (!labels[code[ip+1]]) | |
labels[code[ip+1]] = new Label(); | |
ip += 4; break; | |
case JMP: | |
if (!labels[code[ip+1]]) | |
labels[code[ip+1]] = new Label(); | |
ip += 2; break; | |
case PRINT: ip += 3; break; | |
case PRCHAR: ip += 3; break; | |
case NEW: ip += 3; break; | |
case CALL: | |
if (!labels[code[ip+1]]) | |
labels[code[ip+1]] = new Label(); | |
ip += 3; | |
break; | |
case RET: | |
ip += 1; | |
break; | |
case ADD_RRR: ip += 4; break; | |
case ADD_RRV: ip += 4; break; | |
case MOV_RV: ip += 3; break; | |
case MOV_RR: ip += 3; break; | |
case JMPLE_RR: | |
if (!labels[code[ip+1]]) | |
labels[code[ip+1]] = new Label(); | |
ip += 4; | |
break; | |
case INC: ip += 4; break; | |
case INC4: ip += 4; break; | |
default: ip++; | |
} | |
} | |
ip = 0; | |
int *dest, source1, source2; | |
while(ip<codelen) { | |
const int cmd = code[ip]; | |
if (labels[ip]) | |
a.bind(labels[ip]); | |
switch(cmd) { | |
#include "jitcases.inc" | |
case JMP: | |
if (labels[code[ip+1]]) | |
a.jmp(labels[code[ip+1]]); | |
//else | |
// fprintf(stderr, "!!!no label found at %d in jump from ip=%d\n", code[ip+1], ip); | |
ip += 2; | |
break; | |
case INC: a.inc(dword_ptr(edi, code[ip+1]*4)); ip += 4; break; | |
case INC4: a.add(dword_ptr(edi, code[ip+1]*4), imm(4)); ip += 4; break; | |
default: ip++; | |
} | |
} | |
if (labels[codelen]) | |
a.bind(labels[codelen]); | |
//epilog | |
a.pop(esi); | |
a.pop(edi); | |
a.mov(esp, ebp); | |
a.pop(ebp); | |
// Return. | |
a.ret(); | |
fun = function_cast<RunFun>(a.make()); | |
//printf("\ncode size=%d\n", a.codeSize()); | |
return 0; | |
} | |
void LVM2jit::Run(void *params, const char* logfilename) | |
{ | |
strncpy(logname, logfilename, 1020); | |
if (fun) { | |
fun((int*)params); | |
if (f) { fclose(f); f = NULL; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment