Files
swift-mirror/lib/Frontend/CompilerInvocation.cpp
Saleem Abdulrasool 68bc33fed3 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
2021-11-01 11:23:51 -07:00

87 KiB