Skip to content

Instantly share code, notes, and snippets.

@CryptoManiac
Last active February 24, 2017 21:04
Show Gist options
  • Save CryptoManiac/7d1ac1ced5bdfd59322ed7deba2541d7 to your computer and use it in GitHub Desktop.
Save CryptoManiac/7d1ac1ced5bdfd59322ed7deba2541d7 to your computer and use it in GitHub Desktop.
#include <cassert>
#include <sys/timeb.h>
#ifdef _WIN32
# include <windows.h>
#else
# include <sys/time.h>
# include <unistd.h>
#endif
#include <iostream>
#include <iomanip>
#include <map>
#include <limits>
#include <asmjit/asmjit.h>
#define HALT 0
#define SET 1
#define DEC 2
#define JUMP_NZ 3
using namespace std;
using namespace asmjit;
double time_s()
{
#if defined(_WIN32)
struct __timeb64 time_struct;
int64_t time_ms;
_ftime64_s(&time_struct);
time_ms = (int64_t)time_struct.time;
time_ms *= 1000;
time_ms += time_struct.millitm;
return (time_ms / 1000.0);
#else
struct timeval time_struct;
int64_t time_ms;
gettimeofday(&time_struct, 0);
time_ms = (int64_t)time_struct.tv_sec;
time_ms *= 1000;
time_ms += (time_struct.tv_usec / 1000);
return (time_ms / 1000.0);
#endif
}
void run_program(size_t* program, size_t program_len) {
JitRuntime runtime;
X86Assembler a(&runtime);
X86Compiler c(&a);
c.addFunc(FuncBuilder0<void>(kCallConvHost));
map<size_t, Label> labels; // <addr, label>
for (size_t i = 0; i < program_len; i++) {
// collect labels
if (program[i] == JUMP_NZ) {
auto addr = program[i++ + 1];
labels[addr] = c.newLabel();
}
}
auto x = c.newInt64("x");
for (size_t i = 0; i < program_len; i++) {
// compile and bind
{
// Check whether there is a label for current position.
auto addr = reinterpret_cast<size_t>(&program[i]);
auto it = labels.find(addr);
if (it != labels.end()) {
// If we've found something then bind it.
c.bind(it->second);
}
}
// [SET x] operation
if (program[i] == SET) {
auto value = program[i++ + 1];
c.mov(x, value);
continue;
}
// [DEC x] operation
if (program[i] == DEC) {
c.dec(x);
continue;
}
// [JUMP_NZ address] operation
if (program[i] == JUMP_NZ) {
size_t addr = program[i++ + 1];
auto it = labels.find(addr);
assert(it != labels.end());
c.cmp(x, 0);
c.jnz(it->second);
continue;
}
// [HALT] operation
if (program[i] == HALT) {
c.ret();
continue;
}
}
// Finalize the building of instruction tree.
c.endFunc();
c.finalize();
// Finally, compile code.
typedef void(*FuncType)(void);
auto compiled = asmjit_cast<FuncType>(a.make());
// Run :)
compiled();
runtime.release((void*)compiled);
}
int main()
{
size_t program[6];
program[0] = SET;
program[1] = 2000000000;
program[2] = DEC;
program[3] = JUMP_NZ;
program[4] = (size_t)&program[2];
program[5] = HALT;
auto start_time = time_s();
run_program(program, sizeof(program) / sizeof(size_t));
auto end_time = time_s();
cout << "JIT'ed code done in " << (end_time - start_time) << " seconds." << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment