In iOS 8.0/OS X 10.10, SpriteKit introduced an
-objectForKeyedSubscript: method that enabled subscripting in
Objective-C. However, this subscript wasn't generally useful in Swift
because it took AnyObject and produced AnyObject, so the SpriteKit
overlay defined a subscript that took a String and produced an
[SKNode].
Subsequently, in iOS 9.0/OS X 10.10, -objectForKeyedSubscript: got
type annotations that gave it the appropriate Swift signature, which
made the subscript defined in the overlay redundant.
The twisty logic of the Clang importer would suppress the imported
subscript when it saw the one in the overlay, hiding the
redundancy. My cleanup of that logic in
0c0a0fab4b caused uses of the subscript
to be redundant.
Removal of the redundant code in the overlay is the overall best
answer, because it minimizes the size of the overlay and leaves the
API in the Objective-C header. However, this will introduce a
regression for SpriteKit applications targeting iOS 7.0/OS X 10.8,
where the overlay was compensating for the lack of this operation
before iOS 8.0 / OS X 10.8. There are workarounds here we can
investigate, although they're fairly hacky.
of associated types in protocol witness tables.
We use the global access functions when the result isn't
dependent, and a simple accessor when the result can be cheaply
recovered from the conforming metadata. Otherwise, we add a
cache slot to a private section of the witness table, forcing
an instantiation per conformance. Like generic type metadata,
concrete instantiations of generic conformances are memoized.
There's a fair amount of code in this patch that can't be
dynamically tested at the moment because of the widespread
reliance on recursive expansion of archetypes / dependent
types. That's something we're now theoretically in a position
to change, and as we do so, we'll test more of this code.
There is absolutely no point in making this a runtime check, because
the library will be built differently on the different platforms
anyway. We only need to determine the version at runtime.
Many of the report* entry points are specific to the stdlib assert implementation, so belong in the stdlib. Keep a single `reportError` entry point in the runtime to handle the CrashReporter/ASL interface, and call down to it from the assert implementation functions.
Now, such classes will emit a metadata pattern and use the
generic metadata instantiation logic.
This was all wired up to handle the case of no generic
parameters previously, to support resilient struct layout
in the runtime.
The swift_initializeSuperclass() entry point still exists,
providing a fast path for when there's no field layout to
do, which is currently always true if we have a concrete
class.
This entry point no longer needs the global lock, since
now we get a per-class lock from the metadata cache.
Also, previously we would call the superclass accessor
function on every access of class metadata for a concrete
subclass of a generic class. Now that we re-use the
existing metadata cache logic, this extra call only occurs
during initialization.
Both swift_initializeSuperclass() and
swift_initClassMetadata_UniversalStrategy() used to take
the superclass as a parameter, but this isn't really
necessary, since it was loaded out of the class metadata
immediately prior to the call by the caller. Removing
this parameter makes the ABI a little simpler.
Once class layout supports resilient types, we will also
use swift_initClassMetadata_UniversalStrategy() to lay
out classes with resilient types as fields.
Singleton metadata caches will still allocate a copy of
the template, which is a slight performance regression
from the previous implementation of concrete subclasses
of generic classes. This will be optimized soon.
Right now, the template can always be modified in place;
in the future, it will be possible to modify in place as
long as the superclass is fixed-layout; a resilient superclass
might add or remove fields, thus we cannot leave room for
it in the metadata of the subclass, and will need to grow
the metadata and slide field offsets at runtime using a
new entry point.
Also, the representation of the cache itself could be
optimized to handle the singleton case, since all we
really need here is a lock without any kind of mapping
table.
Move the following from IRGen to runtime:
- Copying generic parameters from superclass to subclass
- Copying field offsets from superclass to subclass
- Initializing the Objective-C runtime name of the subclass
This eliminates some duplication between the generic subclass and
concrete subclass of a generic class cases.
Also this should reduce generated code size and have no impact on
performance (the instantiation logic only runs once per substituted
type).
This lets us remove `swift_fixLifetime` as a real runtime entry point. Also, avoid generating the marker at all if the LLVM ARC optimizer won't be run, as in -Onone or -disable-llvm-arc-optimizer mode.