Previously, the "bare" linkage of a link entity was used to determine
whether to put an async function pointer into the tbd. That did not
match the mechanism by which the linkage was determined in IRGen.
There, the linkage is the "_effective_" linkage (i.e. the value returned
from SILFunction::getEffectiveSymbolLinkage).
Here, whether to put the async function pointer corresponding to a class
method is determined on the basis of that effective linkage.
rdar://problem/73203508
Instead of substituting the AST type, substitute the SIL type. This preserves the calling convention.
E.g. if a function has an indirect @out T result, the substituted function must also have an indirect result.
The substituted AST type would just have a direct empty-tuple result.
Fixes a miscompile
rdar://72386504
Previously, the WitnessMetadata values that were collected were just
ignored when making a function call, although space was reserved for
them in the async context. Here, that error is corrected by actually
storing them into the async context if they are present.
Previously, the suffix "AD" was used to mangle AsyncFunctionPointers.
That was incorrect because it was already used in the mangling scheme.
Here, that error is fixed by using 'u' under the thunk or specialization
operator 'T' to mangle AsyncFunctionPointers. Additionally, printing
and demangling support is added.
rdar://problem/72336407
Currently, the convention for partially applying an async function is to
form a thick function consisting of (1) a pointer to the partial apply
forwarder and (2) a thick context containing the async context size.
Previously, the partial application of async methods--specifically, for
which the partial application of the non-async analog produced a simple
partial apply (meaning that their context was a single ref-counted
object in the form of self)--would result in a simple partial
application. Here, that error is addressed by never allowing the
partial application of async methods to produce a simple partial apply.
Eventually, when the complex temporary ABI for partial application of
async functions is unrolled, this change will need to be unrolled as
well.
Currently, the only thing in the system that donates a thread
to run it is swift_runAndBlockThread, but we'll probably need
others. Nothing in the concurrency runtime should block via a
semaphore in this configuration.
As an outrageous hack, work around the layering problems with
using libdispatch from the concurrency library on non-Darwin
systems by making those systems use the cooperative global
executor. This is only acceptable as a temporary solution
for landing this change and setting things onto the right
long-term design.
It would be more abstractly correct if this got DI support so
that we destroy the member if the constructor terminates
abnormally, but we can get to that later.
We expect to iterate on this quite a bit, both publicly
and internally, but this is a fine starting-point.
I've renamed runAsync to runAsyncAndBlock to underline
very clearly what it does and why it's not long for this
world. I've also had to give it a radically different
implementation in an effort to make it continue to work
given an actor implementation that is no longer just
running all work synchronously.
The major remaining bit of actor-scheduling work is to
make swift_task_enqueue actually do something sensible
based on the executor it's been given; currently it's
expecting a flag that IRGen simply doesn't know to set.
For this, store those 3 values on the stack at function entry and update them with the return values of coro_suspend_async intrinsic calls.
This fixes a correctness issue, because the executor may be different after a resume.
It also is more efficient, because this means that the 3 values don't have to preserved in the context over a suspension point.
Previously, when looking up a protocol method, the witness table was
always exepcted to be the final argument passed to the function.
That is true for sync protocol witnesses but not for async witnesses.
In the async case, the witness table is embedded in the async context.
Here, the witness table is dug out of the async context.
rdar://problem/71491604
Thick async functions store their async context size in the closure
context. Only if the closure context is nil can we assume the
partial_apply_forwarder function to be the address of an async function
pointer struct value.
Now that the convention for partial apply forwarders of async functions
is that the thick context is embedded within the async context, there is
never a need for a placeholder thick context. Here, the placeholder
thick context is only added when the function for which a partial apply
forwarder is being emitted is not async.
Previously, the thick context was passed as a fourth parameter to
partial apply forwarders. Here, the thick context is instead moved into
the async context at the local context position. To support this, the
local context is made always available.
As part of concurrency bringup, some workarounds were put in place to
enable the async cc execution tests to continue to run while enabling
async function SIL verification (specifically, that an async function
must be called from an async function) to land before we have the
Task.runDetached mechanism. Specifically, these workaround allow @main
to be annotated @async but continue to be emitted as if it were not
@async.
Now that we have a better mechanism in the form of runAsync, use that
instead.
rdar://problem/70597390
Metadata for an instance of a type is resolved by extracting it from an
instance of the class. When doing method lookup for an instance method
of a resilient class, the lowered self value was being obtained from the
list of arguments directly by indexing. That does not apply to async
functions where self is embedded within the async context. Here, the
self parameter is extracted from the async context so that the metadata
can in turn be extracted from it.
rdar://problem/71260862
Previously, when lowering the entry point of an async function, the
parameters were lowered to explosions that matched those of sync
functions, namely native explosions. That is incorrect for async
functions where the structured values are within the async context.
Here, that error is fixed, by adding a new customization point to
NativeCCEntryPointArgumentEmission which behaves as before for sync
functions but which simply extracts an argument from the async context
for async functions.
rdar://problem/71260972