mirror of
https://github.com/open-goal/jak-project
synced 2026-06-23 09:29:56 -04:00
Merge pull request #47 from water111/w/win-format
Add format order test and fix reg order for windows
This commit is contained in:
+46
-2
@@ -342,7 +342,8 @@ Ptr<Function> make_function_from_c_linux(void* func) {
|
||||
* Create a GOAL function from a C function. This doesn't export it as a global function, it just
|
||||
* creates a function object on the global heap.
|
||||
*
|
||||
* The implementation is to create a simple trampoline function which jumps to the C function.
|
||||
* This creates a simple trampoline function which jumps to the C function and reorders the
|
||||
* arguments to be correct for Windows.
|
||||
*/
|
||||
Ptr<Function> make_function_from_c_win32(void* func) {
|
||||
// allocate a function object on the global heap
|
||||
@@ -386,6 +387,38 @@ Ptr<Function> make_function_from_c_win32(void* func) {
|
||||
return mem.cast<Function>();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create a GOAL function from a C function. This calls a windows function, but doesn't scramble
|
||||
* the argument order. It's supposed to be used with _format_win32 which assumes GOAL order.
|
||||
*/
|
||||
Ptr<Function> make_function_for_format_from_c_win32(void* func) {
|
||||
// allocate a function object on the global heap
|
||||
auto mem = Ptr<u8>(
|
||||
alloc_heap_object(s7.offset + FIX_SYM_GLOBAL_HEAP, *(s7 + FIX_SYM_FUNCTION_TYPE), 0x80));
|
||||
auto f = (uint64_t)func;
|
||||
auto fp = (u8*)&f;
|
||||
|
||||
int i = 0;
|
||||
// we will put the function address in RAX with a movabs rax, imm8
|
||||
mem.c()[i++] = 0x48;
|
||||
mem.c()[i++] = 0xb8;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
mem.c()[i++] = fp[j];
|
||||
}
|
||||
|
||||
/*
|
||||
* sub rsp, 40
|
||||
* call rax
|
||||
* add rsp, 40
|
||||
* ret
|
||||
*/
|
||||
for (auto x : {0x48, 0x83, 0xEC, 0x28, 0xFF, 0xD0, 0x48, 0x83, 0xC4, 0x28, 0xC3}) {
|
||||
mem.c()[i++] = x;
|
||||
}
|
||||
|
||||
return mem.cast<Function>();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create a GOAL function from a C function. This doesn't export it as a global function, it just
|
||||
* creates a function object on the global heap.
|
||||
@@ -440,6 +473,17 @@ Ptr<Function> make_function_symbol_from_c(const char* name, void* f) {
|
||||
return func;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Given a C function and a name, create a GOAL function and store it in the symbol with the given
|
||||
* name. This is designed for _format_win32, which is special because it takes 8 arguments.
|
||||
*/
|
||||
Ptr<Function> make_format_function_symbol_from_c_win32(const char* name, void* f) {
|
||||
auto sym = intern_from_c(name);
|
||||
auto func = make_function_for_format_from_c_win32(f);
|
||||
sym->value = func.offset;
|
||||
return func;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set the named symbol to the value. This isn't specific to functions.
|
||||
*/
|
||||
@@ -1778,7 +1822,7 @@ s32 InitHeapAndSymbol() {
|
||||
#ifdef __linux__
|
||||
make_function_symbol_from_c("_format", (void*)_format_linux);
|
||||
#elif _WIN32
|
||||
make_function_symbol_from_c("_format", (void*)_format_win32);
|
||||
make_format_function_symbol_from_c_win32("_format", (void*)_format_win32);
|
||||
#endif
|
||||
|
||||
// allocations
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
(define-extern _format function)
|
||||
(define format _format)
|
||||
|
||||
(format #t "test ~D ~D ~D ~D ~D ~D~%" 1 2 3 4 5 6)
|
||||
0
|
||||
@@ -253,6 +253,8 @@ TEST(CompilerAndRuntime, CompilerTests) {
|
||||
runner.run_test("test-factorial-loop.gc", {"3628800\n"});
|
||||
runner.run_test("test-protect.gc", {"33\n"});
|
||||
|
||||
runner.run_test("test-format-reg-order.gc", {"test 1 2 3 4 5 6\n0\n"});
|
||||
|
||||
// expected =
|
||||
// "test newline\nnewline\ntest tilde ~ \ntest A print boxed-string: \"boxed string!\"\ntest
|
||||
// A " "print symbol: a-symbol\ntest A make boxed object longer: \"srt\"!\ntest A
|
||||
|
||||
Reference in New Issue
Block a user