Compilation¶
Compiling a procedure¶
Now that we have a working UNIT_Procedure type, let’s compile it to machine
code!
There is a single function to compile a procedure, called UNIT_Compile().
It takes two arguments:
A pointer to the procedure we want to compile.
The target platform – a combination of the architecture and ABI.
The current platform is accessible via the UNIT_HOST_PLATFORM macro.
Currently, UNIT only supports the AMD64 architecture, so let’s pass
UNIT_ARCH_AMD64.
Note
AMD64 has many different names. You might be used to reading it as “x86-64”, “x64”, or “Intel 64”.
Now, our code looks like this:
#include <unit/unit.h>
int main(void)
{
UNIT_Context context;
if (UNIT_FAILED(UNIT_Context_Init(&context))) {
return 1;
}
UNIT_Procedure procedure;
if (UNIT_FAILED(UNIT_Procedure_Init(&procedure, &context, "main"))) {
UNIT_PrintError(&context, stderr);
UNIT_Context_Clear(&procedure);
return 1;
}
#define ADDOP_INT(op, value) \
if (UNIT_FAILED(UNIT_Procedure_AddOperation(&procedure, op, value))) { \
UNIT_PrintError(&context, stderr); \
UNIT_Procedure_Clear(&context); \
UNIT_Context_Clear(&procedure); \
return 1; \
}
#define ADDOP(op) ADDOP_INT(op, 0)
ADDOP_INT(UNIT_OP_LOAD_INTEGER, 0);
ADDOP(UNIT_OP_RETURN_VALUE);
#undef ADDOP_INT
#undef ADDOP
UNIT_CompiledProcedure *compiled = UNIT_Compile(procedure, UNIT_ARCH_AMD64);
UNIT_Procedure_Clear(&procedure)
UNIT_Context_Clear(&context);
return 0;
}