#include #include #include #include #include class JIT { typedef unsigned char byte; std::vector code; std::map vars; private: void Emit(byte a) { code.push_back(a); } void Emit(byte a,byte b) { Emit(a);Emit(b); } void EmitRef(double& r) { unsigned x = (unsigned)&r; Emit(x); Emit(x>>8); Emit(x>>16); Emit(x>>24); } public: void DefineVar(const std::string& name, double value) { vars[name] = value; } // Compilation void Load(const std::string& name) { Emit(0xDD,0x05); EmitRef(vars[name]); } void Plus() { Emit(0xDE,0xC1); } void Mul() { Emit(0xDE,0xC9); } void Minus() { Emit(0xDE,0xE9); } double Exec() { double result; Emit(0xDD,0x1D); EmitRef(result); //fstp Emit(0xC3); //ret unsigned len = code.size(); void* ptr = (void*)&code[0]; mprotect(ptr,len,PROT_EXEC); ((void(*)(void))ptr) (); mprotect(ptr,len,PROT_READ|PROT_WRITE); return result; } }; int main(void) { JIT jit; jit.DefineVar("x", 1.0); jit.DefineVar("y", 2.0); jit.DefineVar("z", 300.0); // Testing expression: (x+y)*z - x jit.Load("x"); jit.Load("y"); jit.Plus(); jit.Load("z"); jit.Mul(); jit.Load("x"); jit.Minus(); double value = jit.Exec(); std::printf("(x+y)*z-x = %g\n", value); }