mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
With PE/COFF, one cannot reference a data symbol directly across the
binary module boundary. Instead, the reference must be indirected
through the Import Address Table (IAT) to allow for position
independence.
When generating a reference to a AsyncFunctionPointer ({i8*, i32}), we
tag the pointer as being indirected by tagging bit 1 (with the
assumption that native alignment will ensure 4/8 byte alignment, freeing
the bottom 2 bits at least for bit-packing). We tweak the
v-table/witness table emission such that all references to the
AsyncFunctionPointer are replaced with the linker synthetic import
symbol with the bit packing:
~~~
.quad __imp_$s1L1CC1yyYaKFTu+1
~~~
rather than
~~~
.quad $s1L1CC1yyYaKFTu
~~~
Upon access of the async function pointer reference, we open-code the
check for the following:
~~~
pointer = (pointer & 1) ? *(void **)(pointer & ~1) : pointer;
~~~
Thanks to @DougGregor for the discussion and the suggestion for the
pointer tagging. Thanks to @aschwaighofer for pointers to the code that
I had missed. Also, thanks to @SeanROlszewski for the original code
sample that led to the reduced test case.
Fixes: SR-15399
33 lines
1.4 KiB
Swift
33 lines
1.4 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(NonresilientClass)) %S/Inputs/class_open-1instance-void_to_void.swift -Xfrontend -disable-availability-checking -g -module-name NonresilientClass -emit-module -emit-module-path %t/NonresilientClass.swiftmodule
|
|
// RUN: %target-codesign %t/%target-library-name(NonresilientClass)
|
|
// RUN: %target-build-swift -Xfrontend -disable-availability-checking -g %S/Inputs/class_open-1instance-void_to_void.swift -emit-ir -I %t -L %t -lNonresilientClass -parse-as-library -module-name main | %FileCheck %S/Inputs/class_open-1instance-void_to_void.swift --check-prefix=CHECK-LL
|
|
// RUN: %target-build-swift -Xfrontend -disable-availability-checking -g %s -parse-as-library -module-name main -o %t/main -I %t -L %t -lNonresilientClass %target-rpath(%t)
|
|
// RUN: %target-codesign %t/main
|
|
// RUN: %target-run %t/main %t/%target-library-name(NonresilientClass) | %FileCheck %s
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: swift_test_mode_optimize_none
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: concurrency_runtime
|
|
// UNSUPPORTED: back_deployment_runtime
|
|
|
|
import _Concurrency
|
|
import NonresilientClass
|
|
|
|
class D : C {
|
|
}
|
|
|
|
// CHECK: entering call_f
|
|
// CHECK: entering f
|
|
// CHECK: D
|
|
// CHECK: main.D
|
|
// CHECK: exiting f
|
|
// CHECK: exiting call_f
|
|
@main struct Main {
|
|
static func main() async {
|
|
let c = D()
|
|
await call_f(c)
|
|
}
|
|
}
|