Skip to content

Instantly share code, notes, and snippets.

@Huud
Created July 19, 2020 13:34
Show Gist options
  • Save Huud/5a8f5f0a16ed6df25364ecdfc2465674 to your computer and use it in GitHub Desktop.
Save Huud/5a8f5f0a16ed6df25364ecdfc2465674 to your computer and use it in GitHub Desktop.
An esample code that generates C++ code and compiles it to a DLL file then uses it.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <random>
#include <cmath>
#include <string>
#include <chrono>
#include <vector>
#include <windows.h>
using namespace std;
// Instructions implementation
void add(int &a, int &b, int &c) { c = a + b; }
void sub(int &a, int &b, int &c) { b = c - b; }
void mult(int &a, int &b, int &c) { a = c * b; }
void divide(int &a, int &b, int &c) { if (a!=0) c = b / a; }
void inc(int &a, int &b, int &c) { a++; b++; c++; }
void print(int c) { cout << c << endl; }
typedef void(*funcPointer)(int&,int&,int&); // function pointer used to get the function from the dll
int main()
{
int a = 50; // some random initialization
int b = 200;
int c = 3;
std::random_device seedDevice;
std::mt19937 rEngine(seedDevice());
std::uniform_int_distribution<int> InstNumDist(100000, 200000);
std::uniform_int_distribution<int> InstOpcodeDist(1, 5);
int numberOfInst = InstNumDist(rEngine);
vector<int> input;
for (int i = 0; i != numberOfInst; i++) // emulate user input with random numbers
input.push_back(InstOpcodeDist(rEngine));
/// Interpreter
auto interpreterStart = chrono::steady_clock::now();
for (int i = 0; i != input.size(); i++)
{
switch (input[i])
{
case 1: add(a, b, c); break;
case 2: sub(a, b, c); break;
case 3: mult(a, b, c); break;
case 4: divide(a, b, c); break;
case 5: inc(a, b, c); break;
case 6: print(c); break;
}
}
cout << "Interpreter: " << endl << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl;
auto interpreterEnd = chrono::steady_clock::now();
cout << "Interpreter took " << chrono::duration <double, milli>(interpreterEnd - interpreterStart).count() << " ms" << endl;
/// Recompiler:
a = 50; // Same initial state
b = 200;
c = 3;
ofstream CompileFile;
CompileFile.open("GeneratedCode.cpp");
CompileFile << R"(
#include <iostream>
extern "C"
{
void __declspec(dllexport) GeneratedCode(int &a, int &b, int &c)
{
)" << '\n';
// Code Generation
for (int i = 0; i != input.size(); i++)
{
switch (input[i])
{
case 1: CompileFile << "c = a + b;\n"; break;
case 2: CompileFile << "b = c - b;\n"; break;
case 3: CompileFile << "a = c * b;\n"; break;
case 4: CompileFile << "if (a != 0) c = b / a;\n"; break;
case 5: CompileFile << "a++; b++; c++;\n"; break;
case 6: print(c); break;
}
}
CompileFile << R"(
}
}
)" << '\n';
CompileFile.close(); // call before compiling
auto compilerStart = chrono::steady_clock::now();
// compile the generated code as dll
system(R"(call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" && cl /LD GeneratedCode.cpp)");
auto compilerEnd = chrono::steady_clock::now();
cout << "Compilation took " << chrono::duration <double, milli>(compilerEnd - compilerStart).count() << " ms" << endl;
HINSTANCE calledCode = LoadLibrary("GeneratedCode.dll");
if (!calledCode) {
cout << "Import dll failed" << endl;
system("pause");
return EXIT_FAILURE;
}
else
std::cout << "Import dll succeeded" << std::endl;
funcPointer fp = (funcPointer)GetProcAddress(calledCode, "GeneratedCode"); // get the function from the dll
if (!fp)
{
cout << "dll function get failed" << endl;
system("pause");
return EXIT_FAILURE;
}
auto recompilerStart = chrono::steady_clock::now();
fp(a,b,c); // execute the dll function
auto recompilerEnd = chrono::steady_clock::now();
cout << "Recompiler took " << chrono::duration <double, milli>(recompilerEnd - recompilerStart).count() << " ms" << endl;
cout << "Recompiler: " << endl << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl;
system("pause");
return 0;
}
// output:
/*
Interpreter:
a = 19
b = 4
c = 1
Interpreter took 74.4546 ms
*several lines of compiler log*
out:GeneratedCode.dll
Compilation took 12320.2 ms
Import dll succeeded
Recompiler took 3.27327 ms
Recompiler:
a = 19
b = 4
c = 1
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment