From c6b902d2b7da0306ef5edda3658b9e055c6dcaae Mon Sep 17 00:00:00 2001 From: spaceface Date: Thu, 16 Dec 2021 17:02:05 +0100 Subject: [PATCH] cgen: support closures on arm64 (#12863) --- cmd/tools/vtest-self.v | 10 ++++++++-- vlib/v/gen/c/cheaders.v | 29 ++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/cmd/tools/vtest-self.v b/cmd/tools/vtest-self.v index 3b387ae787..e3294344a7 100644 --- a/cmd/tools/vtest-self.v +++ b/cmd/tools/vtest-self.v @@ -130,7 +130,10 @@ const ( skip_on_amd64 = [ 'do_not_remove', ] - skip_on_non_amd64 = [ + skip_on_arm64 = [ + 'do_not_remove', + ] + skip_on_non_amd64_or_arm64 = [ // closures aren't implemented yet: 'vlib/v/tests/closure_test.v', 'vlib/context/cancel_test.v', @@ -232,12 +235,15 @@ fn main() { if os.getenv('V_CI_UBUNTU_MUSL').len > 0 { tsession.skip_files << skip_on_ubuntu_musl } - $if !amd64 { + $if !amd64 && !arm64 { tsession.skip_files << skip_on_non_amd64 } $if amd64 { tsession.skip_files << skip_on_amd64 } + $if arm64 { + tsession.skip_files << skip_on_arm64 + } $if !linux { tsession.skip_files << skip_on_non_linux } diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index 2bdb1df04e..fa8a226d1a 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -58,6 +58,15 @@ static inline void __sort_ptr(uintptr_t a[], bool b[], int l) { } ' +fn arm_bytes(nargs int) string { + // start: + // ldr x16, start-0x08 + // ldr x, start-0x10 + // br x16 + bytes := '0xd0, 0xff, 0xff, 0x58, 0x6, 0xff, 0xff, 0x58, 0x00, 0x02, 0x1f, 0xd6' + return bytes.replace('', nargs.str()) +} + // Heavily based on Chris Wellons's work // https://nullprogram.com/blog/2017/01/08/ @@ -65,7 +74,7 @@ fn c_closure_helpers(pref &pref.Preferences) string { if pref.os == .windows { verror('closures are not implemented on Windows yet') } - if pref.arch != .amd64 { + if pref.arch !in [.amd64, .arm64] { verror('closures are not implemented on this architecture yet: $pref.arch') } mut builder := strings.new_builder(2048) @@ -95,6 +104,24 @@ static unsigned char __closure_thunk[6][13] = { 0xff, 0x25, 0xeb, 0xff, 0xff, 0xff }, }; +') + } else if pref.arch == .arm64 { + builder.write_string(' +static unsigned char __closure_thunk[6][12] = { + { + ${arm_bytes(0)} + }, { + ${arm_bytes(1)} + }, { + ${arm_bytes(2)} + }, { + ${arm_bytes(3)} + }, { + ${arm_bytes(4)} + }, { + ${arm_bytes(5)} + }, +}; ') } builder.write_string('