Skip to content

Instantly share code, notes, and snippets.

@code-disaster
Created August 21, 2023 06:03
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 code-disaster/fee2e1608cd3bbe4f08c179e9f03706a to your computer and use it in GitHub Desktop.
Save code-disaster/fee2e1608cd3bbe4f08c179e9f03706a to your computer and use it in GitHub Desktop.
static void test_tilde_api(TB_System system, TB_Arch arch, const char* file_path)
{
TB_Arena arena = {};
tb_arena_create(&arena, 16 * 1024 * 1024);
TB_FeatureSet features = {};
TB_Module* module = tb_module_create(
arch,
system,
&features,
false
);
tb_module_set_tls_index(module, 0, nullptr);
TB_PrototypeParam uint64_param = {
.dt = TB_TYPE_I64,
};
TB_PrototypeParam uint_param = {
.dt = TB_TYPE_I32,
};
TB_PrototypeParam ptr_param = {
.dt = TB_TYPE_PTR,
};
/*
* MessageBoxA
*/
TB_PrototypeParam messagebox_params[] = {
uint64_param,
ptr_param,
ptr_param,
uint_param
};
TB_FunctionPrototype* fn_messagebox_proto = tb_prototype_create(
module,
TB_CallingConv::TB_STDCALL,
4,
messagebox_params,
1,
&uint_param,
false
);
TB_External* fn_messagebox_ext = tb_extern_create(
module,
-1,
"MessageBoxA",
TB_ExternalType::TB_EXTERNAL_SO_EXPORT
);
/*
* ExitProcess
*/
TB_FunctionPrototype* fn_exit_process_proto = tb_prototype_create(
module,
TB_CallingConv::TB_STDCALL,
1,
&uint_param,
0,
nullptr,
false
);
TB_External* fn_exit_process_ext = tb_extern_create(
module,
-1,
"ExitProcess",
TB_ExternalType::TB_EXTERNAL_SO_EXPORT
);
/*
* main function
*/
TB_FunctionPrototype* main_fn_proto = tb_prototype_create(
module,
TB_CallingConv::TB_STDCALL,
0,
nullptr,
1,
&uint_param,
false
);
TB_Function* main_fn = tb_function_create(
module,
-1,
"mainCRTStartup",
TB_Linkage::TB_LINKAGE_PUBLIC,
TB_ComdatType::TB_COMDAT_NONE
);
tb_function_set_prototype(main_fn, main_fn_proto, &arena);
/*
* function body
*/
{
TB_Node* target;
TB_Node* s0 = tb_inst_cstring(main_fn, "This message box has been invoked from code emitted by TB.");
TB_Node* s1 = tb_inst_cstring(main_fn, "The Tilde Backend");
TB_Node* args[4];
args[0] = tb_inst_uint(main_fn, TB_TYPE_I64, 0);
args[1] = s0;
args[2] = s1;
args[3] = tb_inst_uint(main_fn, TB_TYPE_I64, MB_OKCANCEL);
target = tb_inst_get_symbol_address(main_fn, (TB_Symbol*) fn_messagebox_ext);
tb_inst_call(main_fn, fn_messagebox_proto, target, 4, args);
TB_Node* exit_code = tb_inst_uint(main_fn, TB_TYPE_I32, u32(66));
target = tb_inst_get_symbol_address(main_fn, (TB_Symbol*) fn_exit_process_ext);
tb_inst_call(main_fn, fn_exit_process_proto, target, 1, &exit_code);
tb_inst_ret(main_fn, 1, &exit_code);
}
/*
* Codegen
*/
{
TB_Passes* passes = tb_pass_enter(main_fn, &arena);
TB_FunctionOutput* compile = tb_pass_codegen(passes, true);
if (compile != nullptr) {
tb_output_print_asm(compile, stdout);
}
tb_pass_exit(passes);
}
/*
* Linker
*/
TB_ExecutableType exe_format = tb_system_executable_format(system);
TB_Linker* linker = tb_linker_create(exe_format, arch);
if (exe_format == TB_ExecutableType::TB_EXECUTABLE_PE) {
tb_linker_set_subsystem(linker, TB_WindowsSubsystem::TB_WIN_SUBSYSTEM_CONSOLE);
}
auto append_library = [&](String path) -> MemVoid {
auto [mem, err] = file_read_into_memory(
mem_get_heap_allocator(),
path
);
if (err == File_Error::None) {
TB_Slice name = {
.length = size_t(path.len),
.data = (u8*) path.ptr,
};
TB_Slice data = {
.length = size_t(mem.len),
.data = (u8*) mem.ptr,
};
tb_linker_append_library(
linker,
name,
data
);
}
return mem;
};
tb_linker_append_module(linker, module);
if (system == TB_SYSTEM_WINDOWS) {
append_library(S("e:\\Windows Kits\\10\\Lib\\10.0.19041.0\\um\\x64\\kernel32.lib"));
append_library(S("e:\\Windows Kits\\10\\Lib\\10.0.19041.0\\um\\x64\\user32.lib"));
}
TB_ExportBuffer exe = tb_linker_export(linker);
tb_export_buffer_to_file(exe, file_path);
tb_linker_destroy(linker);
tb_module_destroy(module);
tb_arena_destroy(&arena);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment