The way that we include COMPATIBILITY_OVERRIDE_INCLUDE_PATH freaks out the
syntax highlighting of editors like emacs. It causes the whole file to be
highlighted like it is part of the include string.
To work around this, this patch creates a separate file called
CompatibilityOverrideIncludePath.h that just includes
COMPATIBILITY_OVERRIDE_INCLUDE_PATH. So its syntax highlighting is borked, but
at least in the actual files that contain real code, the syntax highlighting is
restored.
When the ObjC runtime indicates that it supports lazy realization, avoid forcing realization of classes while setting them up. This saves time and memory for classes that never touch the parts of the ObjC runtime that trigger realization
rdar://136102084
We attempted to use the declaration if it exists, and fall back to dlsym. This didn't actually work and we always call dlsym. Include the right header (when available) and add a weak check to the direct call.
rdar://127116080
This adds in hooks so that the new hash/isEqual interop
(which bridges Obj-C hash/isEqual: calls to the corresponding
Swift Hashable/Equatable conformances) can be selectively
disabled based on the OS and/or client.
For now, enable the new semantics everywhere except Apple platforms
(which have legacy apps that may be relying on the old semantics).
This is worth telling people about:
Since we're being asked for the hash value, that probably means someone is
trying to put this object into some form of set or dictionary. But we don't know
anything about the Equatable implementation, so the only valid hash value we can
possibly return is a constant. And hash table implementations typically degrade
into unsorted lists when provided constant hash values.
Note: In order to avoid hammering the logs, we only emit the
warning once for each class that hits this path.
For an Equatable type, we need a hash implementation that
is compatible with any possible definition of `==`.
Conservatively, that means `-hash` must return a constant.
For non-Equatable types, we know that `==` is identity based,
so we can get better hash behavior by using the object address.
Caveat: This means that non-Equatable types will do two
protocol conformance checks on every call to `hash`.
If a Swift type implements Equatable and/or Hashable and
we then pass that object into ObjC, we want ObjC
`isEqual:` and `hashValue` to use that. This allows
ObjC code to build ObjC collections of Swift objects.
* Support for Hashable struct/enum types was implemented in #4124
* Support for Equatable struct/enum types was implemented in #68720
* This implements support for Hashable and Equatable _class_ types
Caveats:
1. This does a lot of dynamic lookup work for each operation, so is
inherently rather slow. Unlike the struct/enum case, there is no convenient
place to cache the conformance information, so it's not clear that there is a
viable way to make it significantly faster.
2. This is a behavioral change to low-level support code. There is a
risk of breaking code that may be relying on the old behavior.
Given this
```
@objc protocol P { func f() }
class C: P { func f() {} }
```
the casts `C.self is any P` and `C.self as? any P` should always fail,
because the metatype of `C.self` does not have an `f()` implementation.
These casts previously succeeded because the runtime implementation
deferred to Obj-C's `[o conformsToProtocol:p]`, and that behaves
differently depending on whether `o` is a class instance or
a Class itself.
Since these casts should never succeed, I've just modified the
Swift runtime logic to fail whenever the source of the cast
is an Obj-C Class and the target is a protocol existential.
Resolves: rdar://106973771
The following sequence of casts would previously succeed
```
struct S {}
let s = S() as AnyObject
s as? NSObject
```
The final cast here should fail, since `S` clearly is not a
subclass of NSObject. But it would previously succeed because
the `as AnyObject` would package the struct into an ObjC-compatible
`__SwiftValue` class. This latter is an NSObject subclass.
This bug was fixed in the main `swift_dynamicCast` runtime function
some time ago, but not in the `swift_dynamicCastObjCClass` which
is chosen by IRGen to optimize casts to ObjC class types.
This PR changes the latter to test for `__SwiftValue` and fall
back to the former in that case in order to get the correct
handling. Falling back to `swift_dynamicCast` also ensures that
the contents of the `__SwiftValue` are correctly unwrapped/bridged/etc
as necessary to fully support Swift casting semantics.
Resolves: rdar://111422725
TODO: I've left an XFAILed test here about the behavior of `type(of:)`
with `__SwiftValue` boxes.
Ensure that context descriptor pointers are signed in the runtime by putting the ptrauth_struct attribute on the types.
We use the new __builtin_ptrauth_struct_key/disc to conditionally apply ptrauth_struct to TrailingObjects based on the signing of the base type, so that pointers to TrailingObjects get signed when used with a context descriptor pointer.
We add new runtime entrypoints that take signed pointers where appropriate, and have the compiler emit calls to the new entrypoints when targeting a sufficiently new OS.
rdar://111480914
This PR changes the casting machinery to avoid casting `__SwiftValue` boxes
directly. This forces the caster to instead unwrap `__SwiftValue` boxes and
retry with the inner content. This results in boxed values being cast like the
inner content.
This fixes the behavior in situations like the following:
```
let t = ...
let s = t as Any as! AnyObject
// `s` is now a `__SwiftValue` box
// Next line should be true iff t conforms to NSCopying
// Prior to this change, it always succeeds
s is NSCopying
```
After this change, the above cast succeeds only if `t` actually
conforms to `NSCopying`.
This is a follow-on to PR#37683.
Related to: SR-14635
We're supposed to expose bridgeObjectRetain/Release_xN variants, but they were missing. This fixes the custom_rr_abi.swift test. Also remove the redundant extern "C" on the entrypoint definitions, which fixes some warnings.
rdar://102793667 rdar://102783074
Rearrange the slow paths a bit to make them tail calls, which allows the compiler to emit these functions without frames.
Clang is happy to emit frameless functions on ARM64 if no stack space is needed on all execution paths. However, when there's a fast path which doesn't need stack space, and a slow path which does, clang emits code that pushes a stack frame and then decides which path to take. This is fine, but it means we're paying more than we'd like to on the fast path.
We can work around that by manually outlining the slow path, and ensuring that it's invoked with a tail call. Then the original function doesn't need a stack frame on any path and clang omits the stack frame.
We tweak RefCounts::increment to return the object it's being called on, which allows `swift_retain` to tail-call it. We manually outline the objc_retain call in swift_bridgeObjectRetain, which allows the swift_retain path to be frameless.
rdar://101764509
This replaces a number of `#include`-s like this:
```
#include "../../../stdlib/public/SwiftShims/Visibility.h"
```
with this:
```
#include "swift/shims/Visibility.h"
```
This is needed to allow SwiftCompilerSources to use C++ headers which include SwiftShims headers. Currently trying to do that results in errors:
```
swift/swift/include/swift/Demangling/../../../stdlib/public/SwiftShims/module.modulemap:1:8: error: redefinition of module 'SwiftShims'
module SwiftShims {
^
Builds.noindex/swift/swift/bootstrapping0/lib/swift/shims/module.modulemap:1:8: note: previously defined here
module SwiftShims {
^
```
This happens because the headers in both the source dir and the build dir refer to SwiftShims headers by relative path, and both the source root and the build root contain SwiftShims headers (which are equivalent, but since they are located in different dirs, Clang treats them as different modules).
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.
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
This gives us build-time warnings about format string mistakes, like we would get if we called the built-in asprintf directly.
Make TypeLookupError's format string constructor a macro instead so that its callers can get these build-time warnings.
This reveals various mistakes in format strings and arguments in the runtime, which are now fixed.
rdar://73417805
Swift's isa mask includes the signature bits. objc_debug_isa_class_mask does not. Switch to objc_absolute_packed_isa_class_mask instead, which does.
While we're at it, get rid of the now-unnecessary guards for back-deployment.
rdar://problem/60148213
There are a few environment variables used to enable debugging options in the
runtime, and we'll likely add more over time. These are implemented with
scattered getenv() calls at the point of use. This is inefficient, as most/all
OSes have to do a linear scan of the environment for each call. It's also not
discoverable, since the only way to find these variables is to inspect the
source.
This commit places all of these variables in a central location.
stdlib/public/runtime/EnvironmentVariables.def defines all of the debug
variables including their name, type, default value, and a help string. On OSes
which make an `environ` array available, the entire array is scanned in a single
pass the first time any debug variable is requested. By quickly rejecting
variables that do not start with `SWIFT_`, we optimize for the common case where
no debug variables are set. We also have a fallback to repeated `getenv()` calls
when a full scan is not possible.
Setting `SWIFT_HELP=YES` will print out all available debug variables along with
a brief description of what they do.
Rather than using the forward declaration for the LLVMSupport types,
expect to be able to use the full declaration. Because these are
references in the implementation, there is no reason to use a forward
declaration as the full types need to be declared for use. The LLVM
headers will provide the declaration and definition for the types. This
is motivated by the desire to ensure that the LLVMSupport symbols are
properly namespaced to avoid ODR violations in the runtime.
Rather than attempting Error bridging early when trying to dynamically
cast to NSError or NSObject, treat it as the *last* thing we do when
all else fails. Push most of this code over into Objective-C-specific
handling rather than #ifdef'd into the main casting logic to make that
slightly more clear.
One oddity of Error/NSError bridging is that a class that conforms to
Error can be dynamically cast to NSObject via Error bridging. This has
always been known to the static compiler, but the runtime itself was
not always handling such a cast uniformly. Do so now,
uniformly. However, this forced us to weaken an assertion, because
casting a class type to NSError or NSObject can produce an object with
a different identity.
Fixes rdar://problem/57393991.