mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: initial pass to support async inheritance on Windows
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
This commit is contained in:
@@ -1876,6 +1876,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
||||
// witness.
|
||||
Opts.LazyInitializeProtocolConformances = Triple.isOSBinFormatCOFF();
|
||||
|
||||
// PE/COFF cannot deal with the cross-module reference to the
|
||||
// AsyncFunctionPointer data block. Force the use of indirect
|
||||
// AsyncFunctionPointer access.
|
||||
Opts.IndirectAsyncFunctionPointer = Triple.isOSBinFormatCOFF();
|
||||
|
||||
if (Args.hasArg(OPT_disable_legacy_type_info)) {
|
||||
Opts.DisableLegacyTypeInfo = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user