Skip to content

Instantly share code, notes, and snippets.

@thedeemon
Created November 30, 2018 00:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thedeemon/980442af0ef5619fe5ae8a8dafcb8db7 to your computer and use it in GitHub Desktop.
Save thedeemon/980442af0ef5619fe5ae8a8dafcb8db7 to your computer and use it in GitHub Desktop.
#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