Implement swift_willThrow variant for typed throws.

`swift_willThrow` is called with an error right before it is thrown.
This existing entrypoint requires an already-boxed error existential;
with typed errors, we don't have the error existential on hand, so we
would need to allocate the box to throw a typed error. That's not okay.

Introduce a new `swift_willThrowTypedImpl` entry point into the runtime
that will first check for the presence of an error handler and, if one
is present, box the error to provide to the error handler. This
maintains the no-allocations path for typed errors while still
allowing existing error handlers to work.

This new entrypoint isn't available on older Swift runtimes, so create
a back-deployable shim called by the compiler. On new-enough platforms,
this will call through to `swift_willThrowTypedImpl`. On older
platforms, we drop the error and don't call the registered will-throw
handler at all. This is a compromise that avoids boxing when throwing
typed errors, at the cost of a slightly different experience for this
new feature on older runtimes.

Fixes rdar://119828459.
This commit is contained in:
Doug Gregor
2024-02-05 15:06:55 -08:00
parent e7be8f32f1
commit 3fa07a0e7a
10 changed files with 167 additions and 18 deletions

View File

@@ -302,6 +302,11 @@ public func swift_deletedMethodError() -> Never {
public func swift_willThrow() throws {
}
/// Called when a typed error will be thrown.
@_silgen_name("swift_willThrowTyped")
public func _willThrowTyped<E: Error>(_ error: E) {
}
@_extern(c, "arc4random_buf")
func arc4random_buf(buf: UnsafeMutableRawPointer, nbytes: Int)