This commit adds initial build system support for macCatalyst,
an Apple technology that enables code targeting iOS
to be recompiled so that it can be executed on macOS while still using
iOS APIs. This is the first in a series of commits building out support for
macCatalyst in the compiler, runtime, standard library, and overlays. Swift
for macCatalyst represents the work of multiple people, including
Devin Coughlin, Ross Bayer, and Brent Royal-Gordon.
Under macCatalyst, compiler-provided shared libraries (including overlays)
are built as one of four kinds (or "flavors") of libraries,
each with different install names and Mach-O load commands. This commit
adds the build system infrastructure to produce these different
library flavors.
**macOS-like Libraries**
A "macOS-like" library (such as the GLKit overlay) is a plain-old macOS library
that can only be loaded into regular macOS processes. It has a macOS slice with
a single load command allowing it to be loaded into normal macOS processes.
**iOS-like Libraries**
An "iOS-like" library, such as the UIKit overlay, is a library with a
macOS slice but with a load command that only allows it be loaded into
macCatalyst processes. iOS-like libraries are produced by passing a new
target tuple to the compiler:
swiftc ... -target x86_64-apple-ios13.0-macabi ...
Here 'ios' (and an iOS version number) is used for OS portion
of the triple, but the 'macabi' environment tells the compiler
that the library is intended for macCatalyst.
**Zippered Libraries**
A "zippered" library can be loaded into either a macCatalyst process or
a standard macOS process. Since macCatalyst does not introduce a new Mach-O
slice, the same code is shared between both processes. Zippered libraries
are usually relatively low level and with an API surface that is similar
between macOS and iOS (for example, both the Foundation overlay and the Swift
Standard Library/Runtime itself are zippered).
Zippered libraries are created by passing both the usual `-target`
flag to the compiler and an additional `-target-variant` flag:
swiftc ... -target x86_64-apple-macos10.15 \
-target-variant x86_64-apple-ios13.0-macabi
Just like the -target flag, -target-variant takes a target tuple.
This tells the compiler to compile the library for the -target tuple but
to add an extra load command, allowing the library to be loaded into processes
of the -target-variant flavor as well.
While a single zippered library and slice is shared between macOS and
macCatalyst, zippered libraries require two separate .swiftinterface/.swiftmodule
files, one for macOS and one for macCatalyst. When a macOS or macCatalyst client
imports the library, it will use module file for its flavor to determine what
symbols are present. This enables a zippered library to expose a subset of its
target APIs to its target-variant.
**Unzippered-Twin Libraries**
"Unzippered Twins" are pairs of libraries with the same name but different
contents and install locations, one for use from macOS processes and one for
use from macCatalyst processes. Unzippered twins are usually libraries that
depend on AppKit on macOS and UIKit on iOS (for example, the MapKit overlay)
and so do not share a common implementation between macOS and macCatalyst.
The macCatalyst version of an unzippered twin is installed in a parallel
directory hierarchy rooted at /System/iOSSupport/. So, for example, while macOS
and zippered Swift overlays are installed in /usr/lib/swift/, iOS-like and
the macCatalyst side of unzippered twins are installed in
/System/iOSSupport/usr/lib/swift. When building for macCatalyst, the build system
passes additional search paths so that the macCatalyst version of libraries is
found before macOS versions.
The add_swift_target_library() funciton now take an
optional MACCATALYST_BUILD_FLAVOR, which enables swift libraries to indicate
which flavor of library they are.
Move the special flag handling for the non-atomic runtime into the build
system rather than spreading it across the build system and the helper
utilities.
SR-3871: Dynamic casting of existentials stored in Obj-C references
Arbitrary Swift objects get packaged into __SwiftValue containers so
that pointers to them can be passed into Obj-C. (Obviously, Obj-C
code can't do anything particularly useful with such pointers other
than refcount them and give them back to Swift code.) Those values come
back into Swift as either `Any` (existential box) or `AnyObject`
(anonymous object pointer) values. Dynamically casting those requires
first inspecting the outer value to get access to the actual type and
value in the __SwiftValue container.
The tryDynamicCastBoxedSwiftValue() function that handles this
was missing a check for the `Any` case, which is why directly
casting from `Any` would routinely fail.
Resolves SR-3871
Added a new flag to the GenericMetadataPatternFlags flagset for whether
the metadata has a set of flags at its tail. When that flag is set,
there will be an extra uint64_t flagset at the end of the metadata. For
struct metadata, the type of that flagset will be
StructMetadataTrailingFlags. The first flag in that trailing flagset
indicates whether the metadata was statically specialized. The second
flag in that trailing flagset indicates whether the metadata is
statically canonical.
When verifying the metadata cache, a check is done for whether the
metadata was statically specialized and whether it was known to be
canonical statically. If so, verification is skipped. Skipping it is
necessary because the known-canonical statically specialized metadata
will not be in the cache. In that case, the canonical statically
specialized metadata will be returned from the metadata accessor and
never be cached.
SR-5289: Teach Mirror how to inspect weak, unowned, and unmanaged refs
Correctly reflect weak, unowned, and unmanaged references
to both Swift and Obj-C types (including existential references to
such types) that occur in both Swift class objects and in Swift
structs.
This includes the specific reported case (unowned reference to an
Obj-C object) and several related ones.
Related changes in this PR:
* Tweak internal bitmap used for tracking ownership modifiers
to reject unsupported combinations.
* Move FieldType into ReflectionMirror.mm
FieldType is really just an internal implementation detail
of this one source file, so it does not belong in an ABI header.
* Use TypeReferenceOwnership directly to track field ownership
This avoids bitwise copying of properties and localizes some
of the knowledge about reference ownership
* Generate a top-level "copyFieldContents" from ReferenceStorage.def
Adding new ownership types to ReferenceStorage.def will now
automatically produce calls to `copy*FieldContents` - failure
to provide a suitable implementation will fail the build.
* Add `deallocateBoxForExistentialIn` to match `allocateBoxForExistentialIn`
Caveat: The unit tests are not as strict as I'd like. Attempting to make them
so ran afoul of otherwise-unrelated bugs in dynamic casting.
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.
* SR-7732: Dynamic casting CFError to Error results in a memory leak
The special handling for casting CFError/NSError to Swift Error
type was using cleanup code that didn't correctly handle this case.
This replaces the cleanup code with a more targeted version.
Fixes: SR-7732
Fixes: rdar://problem/40423061
* Whitespace fixes
* Don't rely on localizable strings to verify test behavior.
I've verified this simplified test still leaks with
the original code and does not leak with the fixed code.
* Don't test against old runtimes that predate this fix
* Explicitly test both NSError and CFError
To implement swift_errorBridgingInfo, the Foundation overlay needs to import private runtime headers. Now that we cannot statically link the Foundation overlay, there is no point to keeping this workaround in the overlay any more.
This effectively reverts https://github.com/apple/swift/pull/16677.
rdar://problem/57809306
In Errors.cpp, PRIxPTR is used in a format string:
constexpr const char *format = "%-4u %-34s 0x%0.16" PRIxPTR " %s + %td\n";
This fails to build because of upstream changes in STLExtras:
049043b598 (diff-43fc25e3af55e1ae97f17ef051d68aa4)
This patch merely adds the include for the needed PRIxPTR define.
(cherry picked from commit 0529fbedca)
use getTypeByMangledName when abstract metadata state is requested
This can significantly reduce the code size of apps constructing deeply
nested types with conditional conformances.
Requires a new runtime.
rdar://57157619
This could fail to build due to BackDeployment.h not always being included in Config.h. Check an additional condition to ensure that this code is only active when BackDeployment.h is included.
rdar://problem/56735154
This is cleaner and it fixes a bunch of cases the old code didn't handle: @objc protocols, class bounds, and superclass constraints.
rdar://problem/56044443
This fixes cases like `type is T.Type` when T is generic specialized to a protocol type.
Note: the compiler can still optimize these checks away and will optimize this check down to `false` in some cases. We'll want to fix that as well.
rdar://problem/56044443
This removes it from the AST and largely replaces it with AnyObject
at the SIL and IRGen layers. Some notes:
- Reflection still uses the notion of "unknown object" to mean an
object with unknown refcounting. There's no real reason to make
this different from AnyObject (an existential containing a
single object with unknown refcounting), but this way nothing
changes for clients of Reflection, and it's consistent with how
native objects are represented.
- The value witness table and reflection descriptor for AnyObject
use the mangling "BO" instead of "yXl".
- The demangler and remangler continue to support "BO" because it's
still in use as a type encoding, even if it's not an AST-level
Type anymore.
- Type-based alias analysis for Builtin.UnknownObject was incorrect,
so it's a good thing we weren't using it.
- Same with enum layout. (This one assumed UnknownObject never
referred to an Objective-C tagged pointer. That certainly wasn't how
we were using it!)
Instead of passing around raw local pointers and references, and spreading
tricky offset arithmetic around with the Local/RemoteAddress fields in
ReflectionInfo, have the TypeRefBuilder code use RemoteRefs everywhere,
which keep the remote/local mapping together in one unit and provide
centralized API for this logic.
This doesn't yet change how code uses the RemoteRef address data to
follow pointers across objects, for things like reading type refs, but
that should be much easier to do after this lands.
These are now always zero, because memory readers handle virtual address mapping.
The `swift_reflection_info_t` structure used by the C RemoteMirror API keeps
its offset fields because it's supposed to be a stable API, but we now assert that
the values are always zero.
This reverts commit efaf1fbefa.
Add a much more palatable workaround for the unit tests. Rather than
adding the dllimport for the symbols, locally define the required
symbols. This list is sufficient to restore the ability to build tests
for Windows.
The runtime tests will statically link the runtime and dynamically link
to the standard library. This fails to build on Windows. This is a
horrible workaround for the time being.
Mangling these common types takes only two bytes, which is shorter than a symbolic reference. We
know where their metadata is in the standard library, too, so we don't need to search the lookup
tables for them.