When constructing generic type metadata, we can end up checking protocol conformances for metadata that isn't fully built, and in particular the superclass field may not be set up yet. Handle this case properly by falling back to looking up the superclass by mangled name from the nominal type descriptor when necessary.
Previously we were just chasing Superclass fields, which would cause us to terminate the search early sometimes when concurrently looking up the same type from multiple threads. When a protocol conformance is on a superclass, this causes the search to fail incorrectly, causing type lookup failures.
This only arises on the very first attempt to instantiate a given type, since the lookup will be cached (and all metadata fully initialized) after the first success.
rdar://72583931
Implement name mangling, type metadata, runtime demangling, etc. for
global-actor qualified function types. Ensure that the manglings
round-trip through the various subsystems.
Implements rdar://78269642.
Introduce a second level of standard substitutions to the mangling,
all of the form `Sc<character>`, and use it to provide standard
substitutions for most of the _Concurrency types.
This is a precursor to rdar://78269642 and a good mangling-size
optimization in its own right.
* SR-14635: Casts to NSCopying should not always succeed
The runtime dynamic casting logic explores a variety of strategies for
each cast request. One of the last options is to wrap the source
in a `__SwiftValue` box so it can bridge to Obj-C. The previous
code was overly aggressive about such boxing; it performed the boxing
for any source type and only checked to verify that the `__SwiftValue`
box itself was compatible with the destination.
Among other oddities, this results in the behavior discussed
in SR-14635, where any Swift or Obj-C type will always successfully cast
to NSCopying because `__SwiftValue` is compatible with NSCopying.
This is actually two subtly different issues:
* Class types should not be subject to `__SwiftValue` boxing at all.
Casting class types to class existentials is already handled elsewhere,
so this function should just reject any source with class type.
* Non-class types should be boxed only when being assigned to
an AnyObject (an "unconstrained class existential"). If
the class existential has constraints, it is by definition
a class-constrained existential which should not receive
any non-class object.
To solve these, this PR disables `__SwiftValue` boxing in two cases:
1. If the source is a class (reference) type.
2. If the destination has constraints
Resolves SR-14635
Resolves rdar://78224322
* Avoid boxing class metatypes on Darwin
But continue boxing
* Non-class metatypes on all platforms
* All metatypes on non-Darwin platforms
Obj-C interop requires that we do not box class metatypes;
those must be usable as simple pointers when passed to Obj-C.
But no other metatype is object-compatible, so we have to
continue boxing everything else.
* Split out ObjC-specific test cases
Rename duplicated `swift::fatalError` in `swiftRuntime` and `swift_Concurrency`.
Both `swiftRuntime` and `swift_Concurrency` had `swift::fatalError` implementation, but it causes symbol conflict with the `-static-stdlib` flag.
This patch removes one of the implementations in `swift_Concurrency` to avoid conflicts. Also added a test case to ensure that linking the Concurrency module with `-static-stdlib` works.
This issue was found by SwiftWasm test cases.
Both swiftRuntime and swift_Concurrency had swift::fatalError
implementation, but it causes symbol conflict when -static-stdlib.
This patch renames one of the impl in swift_Concurrency to avoid
conflict.
SWIFT_CLASS_IS_SWIFT_MASK is optionally defined to a global variable _swift_classIsSwiftMask, which allows the runtime to choose the appropriate mask when running on OS versions earlier than macOS 10.14.4. This is no longer a supported target for newly built runtimes (Swift apps built with such a target will embed a copy of the back deployment runtime, which is separate) and this global is no longer useful. Instead, unconditionally define SWIFT_CLASS_IS_SWIFT_MASK to 2 on Apple platforms, which is the correct value for current OS versions.
rdar://48413153
Commit the platform definition and build script work necessary to
cross-compile for arm64_32.
arm64_32 is a variant of AARCH64 that supports an ILP32 architecture.
The callbacks made in ImageInspectionMachO.cpp are called in a dangerous context, with the dyld and ObjC runtime locks held. C++ allows programs to overload the global operator new/delete, and there's no guarantee that those overloads behave. Ideally, we'd avoid them entirely, but that's a bigger job. For now, avoid the worst trouble by avoiding STL and new/delete in these callbacks. That use came from ConcurrentReadableArray's free list, so we switch that from a std::vector to a linked list.
rdar://75036800
Repurpose mangling operator `Y` as an umbrella operator that covers new attributes on function types. Free up operators `J`, `j`, and `k`.
```
async ::= 'Ya' // 'async' annotation on function types
sendable ::= 'Yb' // @Sendable on function types
throws ::= 'K' // 'throws' annotation on function types
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
differentiable ::= 'Yjr' // @differentiable(reverse) on function type
differentiable ::= 'Yjd' // @differentiable on function type
differentiable ::= 'Yjl' // @differentiable(_linear) on function type
```
Resolves rdar://76299796.
`@noDerivative` was not mangled in function types, and was resolved incorrectly when there's an ownership specifier. It is fixed by this patch with the following changes:
* Add `NoDerivative` demangle node represented by a `k` operator.
```
list-type ::= type identifier? 'k'? 'z'? 'h'? 'n'? 'd'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, and variadic specifier
```
* Fix `NoDerivative`'s overflown offset in `ParameterTypeFlags` (`7` -> `6`).
* In type decoder and type resolver where attributed type nodes are processed, add support for nested attributed nodes, e.g. `inout @noDerivative T`.
* Add `TypeResolverContext::InoutFunctionInput` so that when we resolve an `inout @noDerivative T` parameter, the `@noDerivative T` checking logic won't get a `TypeResolverContext::None` set by the caller.
Resolves rdar://75916833.
Previously, AsyncFunctionPointer constants were signed as code. That
was incorrect considering that these constants are in fact data. Here,
that is fixed.
rdar://76118522
* Move differentiability kinds from target function type metadata to trailing objects so that we don't exhaust all remaining bits of function type metadata.
* Differentiability kind is now stored in a tail-allocated word when function type flags say it's differentiable, located immediately after the normal function type metadata's contents (with proper alignment in between).
* Add new runtime function `swift_getFunctionTypeMetadataDifferentiable` which handles differentiable function types.
* Fix mangling of different differentiability kinds in function types. Mangle it like `ConcurrentFunctionType` so that we can drop special cases for escaping functions.
```
function-signature ::= params-type params-type async? sendable? throws? differentiable? // results and parameters
...
differentiable ::= 'jf' // @differentiable(_forward) on function type
differentiable ::= 'jr' // @differentiable(reverse) on function type
differentiable ::= 'jd' // @differentiable on function type
differentiable ::= 'jl' // @differentiable(_linear) on function type
```
Resolves rdar://75240064.
The previous fix here switched dyn_cast for dyn_cast_or_null, but this left us with an assertion failure in cast<>. Instead, explicitly check for NULL at the top of the function.
Fill out the metadata for Job to have a Dispatch-compatible vtable. When available, use the dispatch_enqueue_onto_queue_4Swift to enqueue Jobs directly onto queues. Otherwise, keep using dispatch_async_f as we have been.
rdar://75227953
Somehow, clang was generating code that accepted nil and returned nil in swift_getObjCClassFromMetadata, but is no longer doing so. Some code relies on this to work, so switch to dyn_cast_or_null to accept nil explicitly.
rdar://74895271
Take the existing CompatibilityOverride mechanism and generalize it so it can be used in both the runtime and Concurrency libraries. The mechanism is preprocessor-heavy, so this requires some tricks. Use the SWIFT_TARGET_LIBRARY_NAME define to distinguish the libraries, and use a different .def file and mach-o section name accordingly.
We want the global/main executor functions to be a little more flexible. Instead of using the override mechanism, we expose function pointers that can be set by the compatibility library, or by any other code that wants to use a custom implementation.
rdar://73726764
Match the logic used in the non-shared-cache case, where we walk up the class hierarchy to find the class where the conformance actually applies. This is important in cases like:
class Super<T> : Proto {}
class Sub: Super<Int> {}
Looking up the conformance `Sub: Proto` without this logic causes it to attempt to find the witness table for `Sub<Int>`, which fails. The correct logic looks up the witness table for `Super<Int>`.
While we're in there, fix a bug in the shared cache validation code (std::find wasn't checked for failure correctly) and add a `SWIFT_DEBUG_ENABLE_SHARED_CACHE_PROTOCOL_CONFORMANCES` environment variable to allow us to turn the shared cache integration off at runtime.
rdar://75431771
Some ObjC runtime calls are weak or strong depending on the deployment target. When strong, we get warnings that the NULL checks always succeed; silence them.
Some of the adjacent code looked up functions using dlsym when they aren't provided by the SDK. Our current minimum SDK always has them, so remove the dlsym workaround.
NFC except that I added swift_errorRetain and swift_errorRelease
functions on non-ObjC targets so that we have consistent
functions to call in the runtime. I have not changed everywhere
in the runtime to use these, nor have I changed the compiler to
call them.
The file static-executable-args.lnk was added to the stdlib install
component, but stdlib didn't depend on it, so when invoking
install-stdlib or install-swift-components, the file was not being
generated.
Because of the magic target marked as `ALL`, when one built all the
targets, and later issued a `install-*` target, the file was there by
a lucky coincidence.
The change only creates that dependency, so a call to install the stdlib
will also create this file.
When available, take advantage of precomputed protocol conformances in the shared cache on Darwin platforms to accelerate conformance lookups and cut down on memory usage.
We consult the precomputed conformances before doing the runtime's standard conformance lookup. When a conformance is precomputed, this avoids the slow linear scan of all loaded conformances for the first access, and it avoids the memory cost of storing the conformance in the cache.
When the shared cache has no images overridden (the normal case), then we can also skip scanning conformances in the shared cache in all circumstances, because the precomputed conformances will always cover those results. This greatly speeds up the slow linear scan for the initial lookup of anything that doesn't have a conformance in the shared cache, including lookups with conformances in apps or app frameworks, and negative lookups.
A validation mode is available by setting the SWIFT_DEBUG_VALIDATE_SHARED_CACHE_PROTOCOL_CONFORMANCES environment variable. When enabled, results from the precomputed conformances are compared with the results from a slow scan of the conformances in the shared cache. This extremely slow, but good at catching bugs in the system.
When the calls for precomputed conformances are unavailable, the new code is omitted and we remain in the same situation as before, with the runtime performing all lookups by scanning conformance sections in all loaded Swift images.
rdar://71128983
The new cast logic checks and aborts if a non-nullable pointer has a null value
at runtime. However, because this was tolerated by the old casting logic, some
apps inadvertently rely on being able to cast such null references.
This change adds specific checks for null pointers in compatibility mode and
handles them similarly to the previous casting logic:
* Casting to Obj-C or CF type: casting a null pointer succeeds
* Casting to class-constrained existential: casting a null pointer succeeds
* Casting to a Swift class type: cast fails without crashing
* Bridging from Obj-C class to Swift struct type: cast fails without crashing
This also adds a guard to avoid trying to lookup the dynamic type of a null
class reference.
In non-compatibility mode, all of the above cause an immediate runtime crash.
The changes here are only intended to support existing binaries running against
new Swift runtimes.
Resolves rdar://72323929
In the uncached case, we'd scan conformances, cache them, then re-query the cache. This worked fine when the cache always grew, but now we clear the cache when loading new Swift images into the process. If that happens between the scan and the re-query, we lose the entry and return a false negative.
Instead, track what we've found in the scan in a separate local table, then query that after completing the scan.
While we're in there, fix a bug in TypeLookupError where operator= accidentally copied this->Context instead of other.Context. This caused the runtime to crash when trying to print error messages due to the false negative.
Add a no-parameter constructor to TypeLookupErrorOr<> to distinguish the case where it's being initialized with nothing from the case where it's being initialized with nullptr.