Call `swift_clearSensitive` after destroying or taking "sensitive" struct types.
Also, support calling C-functions with "sensitive" parameters or return values. In SIL, sensitive types are address-only and so are sensitive parameters/return values.
Though, (small) sensitive C-structs are passed directly to/from C-functions. We need re-abstract such parameter and return values for C-functions.
KeyPath's getter/setter/hash/equals functions have their own calling
convention, which receives generic arguments and embedded indices from a
given KeyPath argument buffer.
The convention was previously implemented by:
1. Accepting an argument buffer as an UnsafeRawPointer and casting it to
indices tuple pointer in SIL.
2. Bind generic arguments info from the given argument buffer while emitting
prologue in IRGen by creating a new forwarding thunk.
This 2-phase lowering approach was not ideal, as it blocked KeyPath
projection optimization [^1], and also required having a target arch
specific signature lowering logic in SIL-level [^2].
This patch centralizes the KeyPath accessor calling convention logic to
IRGen, by introducing `@convention(keypath_accessor_XXX)` convention in
SIL and lowering it in IRGen. This change unblocks the KeyPath projection
optimization while capturing subscript indices, and also makes it easier
to support WebAssembly target.
[^1]: https://github.com/apple/swift/pull/28799
[^2]: https://forums.swift.org/t/wasm-support/16087/21
The functions in llvm-project `AttributeList` have been
renamed/refactored to help remove uses of `AttributeList::*Index`.
Update to use these new functions where possible. There's one use of
`AttrIndex` remaining as `replaceAttributeTypeAtIndex` still takes the
index and there is no `param` equivalent. We could add one locally, but
presumably that will be added eventually.
Changes the task, taskGroup, asyncLet wait funtion call ABIs.
To reduce code size pass the context parameters and resumption function
as arguments to the wait function.
This means that the suspend point does not need to store parent context
and resumption to the suspend point's context.
```
void swift_task_future_wait_throwing(
OpaqueValue * result,
SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
AsyncTask *task,
ThrowingTaskFutureWaitContinuationFunction *resume,
AsyncContext *callContext);
```
The runtime passes the caller context to the resume entry point saving
the load of the parent context in the resumption function.
This patch adds a `Metadata *` field to `GroupImpl`. The await entry
pointer no longer pass the metadata pointer and there is a path through
the runtime where the task future is no longer available.
Previously, the error stored in the async context was of type SwiftError
*. In order to enable the context to be callee released, make it
indirect and change its type to SwiftError **.
rdar://71378532
This increases the level of abstraction a bit and makes it easier to stage
in the requisite support for async method calls. For now, I've kept the
existing, incomplete logic for those.
Part of rdar://problem/73625623.
An AsyncFunctionPointer, defined in Task.h, is a struct consisting of
two i32s: (1) the relative address of the async function and (2) the
size of the async context to be allocated when calling that function.
Here, such structs are emitted for every async SILFunction that is
emitted.
Here, the following is implemented:
- Construction of SwiftContext struct with the fields needed for calling
functions.
- Allocating and deallocating these swift context via runtime calls
before calling async functions and after returning from them.
- Storing arguments (including bindings and the self parameter but not
including protocol fields for witness methods) and returns (both
direct and indirect).
- Calling async functions.
Additional things that still need to be done:
- protocol extension methods
- protocol witness methods
- storing yields
- partial applies
The goals here are four-fold:
- provide cleaner internal abstractions
- avoid IR bloat from extra bitcasts
- avoid recomputing function-type lowering information
- allow more information to be propagated from the function
access site (e.g. class_method) to the call site
Use this framework immediately for class and protocol methods.
SubstitutionList is going to be a more compact representation of
a SubstitutionMap, suitable for inline allocation inside another
object.
For now, it's just a typedef for ArrayRef<Substitution>.
Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.
The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results. It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.
The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*. The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list. The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.
A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple. It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.
Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction. It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
It's not worth burning more than three registers on a parameter, and doing so causes code size issues for large structs and enums. Make it so that values with more than three explosion members get passed indirectly, just like they get returned indirectly.
This time, modify emitPartialApplyForwarder not to attempt to 'tail' call the original function when indirect arguments get alloca'ed on the stack, which is UB, and don't use "byval", as suggested by John.
Swift SVN r29032
It's not worth burning more than three registers on a parameter, and doing so causes code size issues for large structs and enums. Make it so that values with more than three explosion members get passed indirectly, just like they get returned indirectly.
Swift SVN r29016
As part of this, re-arrange the argument order so that
generic arguments come before the context, which comes
before the error result. Be more consistent about always
adding a context parameter on thick functions, even
when it's unused. Pull out the witness-method Self
argument so that it appears last after the error
argument.
Swift SVN r26667
If a type has to be passed or returned resiliently, it
will necessarily be passed indirectly, which is already
represented in SILFunctionType. There is no need to
represent this as a separate channel of information.
NFC. Also fixes a problem where the signature cache
for ExtraData::Block was writing past the end of an
array (but into the storage for an adjacent array
which was fortunately never used).
ExtraData should also disappear as a concept, but we're
still relying on that for existential protocol witnesses.
Swift SVN r21548
Remove uncurry level as a property of SILType/SILFunctionTypeInfo. During SIL type lowering, map a (Type, UncurryLevel) pair to a Swift CanType with the uncurried arguments as a Swift tuple. For example, T -> (U, V) -> W at uncurry level 1 becomes ((U, V), T) -> W--in reverse order to match the low-level calling convention. Update SILGen and IRGen all over the place for this representation change.
SILFunctionTypeInfo is still used in the SILType representation, but it's no longer load-bearing. Everything remaining in it can be derived from a Swift type.
This is an ABI break. Be sure to rebuild clean!
Swift SVN r5296
dead methods, and moving emitInvoke to CallInvocation.
An interesting semantic change of this is that we're now calling getResultType
on the function type every time IGF is constructed, which exposed some latent
bugs. Specifically two places in GenObjC are trying to extra curry level two
from function types like "SomeObject -> (value : SomeObject) -> ()" which
doesn't make sense. I switched them to get curry level 1, but this definitely
needs some close review.
Swift SVN r4852
Collect the substitutions from SpecializeInsts and use them when emitting an ApplyInst to pass archetype parameters and to reexplode arguments at the right abstraction level for the generic callee. Unfortunately, ArchetypeTypeInfo::allocate() is broken, so alloc_box $T for an archetype type T doesn't yet work.
Swift SVN r4597
Introduce cleanups onto arguments to SIL apply instructions, and let CallEmission consume the cleanups corresponding to the values consumed by the called function, so that releases will be emitted as needed to make a foreign call conform to Swift ownership conventions.
Swift SVN r4556
Push LLVM attribute generation from expandAbstractCC into getFunctionSignature and CallEmission so that they can generate sret and/or byval attributes per-argument according to the calling convention. Copy our bogus rule for emitting sret returns (more than three elements in the explosion) and reuse it to pass large struct values as byvals rather than as explosions. This should be good enough to get both 'NSRect' and
'NSRange', 'NSSize' etc. to pass correctly to ObjC methods. Next step is to set the AbstractCC correctly for imported func decls so that standalone C functions follow the same bogus rule.
Swift SVN r3993
Implement lowering of SIL ClosureInsts by packing the partial arguments into a heap allocation and emitting a thunk to unpack them and apply the closure function, similar to curried entry points. The test doesn't work quite yet because nested FuncDecls don't get visited anymore. I need to replace my hacked SIL path with a proper walk of the SIL module to generate functions and the AST to generate types.
Swift SVN r3817