* [IRGen] Handle complex single payload enum cases
rdar://110138498
Handles single payload enum cases with more complex bit patterns (e.g. >64 bits or scattered) by storing a relative pointer to a function that reads the tag.
* Use proper symbol for enum tag helper
We don't have any language or runtime support for noncopyable types as generic
or dynamic types yet, and existing reflection code almost certainly assumes it
can copy the values it's working with, and will trap or corrupt state if it does
so with noncopyable types. But a class can have noncopyable fields while the
type itself is copyable, and existing code assumes that it can use `Mirror` or
other reflection mechanisms to safely traverse the contents of an arbitrary
class.
Allow this sort of code to continue working, while still preparing for forward
compatibility with future runtimes that do support noncopyable generics, by
emitting the type references for fields using a function that probes the
address of a new symbol in the Swift runtime. The symbol will either be missing
or defined with an absolute address of zero in current or previous runtime
versions, but can be changed to a non-null address in the future.
Upgrade the old mangling from a list of argument types to a
list of requiremnets. For now, only same-type requirements
may actually be mangled since those are all that are available
to the surface language.
Reconstruction of existential types now consists of demangling (a list of)
base protocol(s), decoding the constraints, and converting the same-type
constraints back into a list of arguments.
rdar://96088707
I wrote out this whole analysis of why different existential types
might have the same logical content, and then I turned around and
immediately uniqued existential shapes purely by logical content
rather than the (generalized) formal type. Oh well. At least it's
not too late to make ABI changes like this.
We now store a reference to a mangling of the generalized formal
type directly in the shape. This type alone is sufficient to unique
the shape:
- By the nature of the generalization algorithm, every type parameter
in the generalization signature should be mentioned in the
generalized formal type in a deterministic order.
- By the nature of the generalization algorithm, every other
requirement in the generalization signature should be implied
by the positions in which generalization type parameters appear
(e.g. because the formal type is C<T> & P, where C constrains
its type parameter for well-formedness).
- The requirement signature and type expression are extracted from
the existential type.
As a result, we no longer rely on computing a unique hash at
compile time.
Storing this separately from the requirement signature potentially
allows runtimes with general shape support to work with future
extensions to existential types even if they cannot demangle the
generalized formal type.
Storing the generalized formal type also allows us to easily and
reliably extract the formal type of the existential. Otherwise,
it's quite a heroic endeavor to match requirements back up with
primary associated types. Doing so would also only allows us to
extract *some* matching formal type, not necessarily the *right*
formal type. So there's some good synergy here.
Marker protocols don't exist at runtime, drop them when mangling a type
for the purposes of runtime type metadata or reflection. Fixes
rdar://82314404.
When back-deploying concurrency support, do not use the standard
substitutions for _Concurrency-defined types (such as `Task`) in type
metadata because older Swift runtimes will not be able to demangle
them. Instead, use the full mangled names so the runtime can still
demangle them appropriately.
Addresses rdar://82931890.
This pattern was really error-prone. I've fixed multiple bugs related
to CurGenericSignature not being set correctly at the right time, and
found another latent bug by inspection while doing this cleanup.
Mangling uses a generic signature is used to shorten member types
to just a name where the protocol is unambiguous.
Unfortunately, in the particular case of 'associated type paths',
the IRGen mangler did not consistently set the right signature.
Sometimes, it would use no signature, and other times it would use
the signature of the concrete conforming type, which is incorrect
because the member type is written relative to the root protocol's
generic signature, <Self : P>.
This was caught by some new assertions I'm adding to the rewrite
system.
Note that this changes the mangling of a few symbols, but none
are public in the ABI.
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.
of adding a property.
This better matches what the actual implementation expects,
and it avoids some possibilities of weird mismatches. However,
it also requires special-case initialization, destruction, and
dynamic-layout support, none of which I've added yet.
In order to get NSObject default actor subclasses to use Swift
refcounting (and thus avoid the need for the default actor runtime
to generally use ObjC refcounting), I've had to introduce a
SwiftNativeNSObject which we substitute as the superclass when
inheriting directly from NSObject. This is something we could
do in all NSObject subclasses; for now, I'm just doing it in
actors, although it's all actors and not just default actors.
We are not yet taking advantage of our special knowledge of this
class anywhere except the reference-counting code.
I went around in circles exploring a number of alternatives for
doing this; at one point I basically had a completely parallel
"ForImplementation" superclass query. That proved to be a lot
of added complexity and created more problems than it solved.
We also don't *really* get any benefit from this subclassing
because there still wouldn't be a consistent superclass for all
actors. So instead it's very ad-hoc.
We want to be able to use mangled names to refer to protocol conformances in addition to type
metadata. Provide an ASTMangler method that can render an arbitrary abstract or concrete
`ProtocolConformanceRef`, factoring it out of the code used to emit conditional conformance arguments
in `appendProtocolConformance`.
In order for the runtime demangler to be able to find ObjC classes and protocols, it needs to
have the runtime name of the declaration be in the mangled name. Only do this for runtime manglings,
to minimize the potential ABI impact for symbol names that already have the source-level names of
ObjC entities baked in. Fixes SR-12169 | rdar://59306590.
In order for the cross-module optimization to work, it needs to generate
symbolic references, which were disabled in PE/COFF. This commit enables
them and marks some Reflection tests with XFAIL since
swift-reflection-dump still doesn't handle symbolic references.
When an original module name is specified via @_originalDefinedIn attribute, we need to
use the original module name for all related runtime symbol names instead of the current
module names.
rdar://55268186
Collect the relative and symbol relocations from ELF images in order to resolve pointer values
read from disk. This allows us to enable symbolic-referencing-all-the-things for ELF platforms.
Now that `swift-reflection-dump` correctly handles pointer values and unresolved
cross-image references (for Mach-O, at least), we can safely unconditionally use
symbolic references in runtime mangled names without regressing offline reflection
support.
When emitting metadata for a Swift-defined @objc protocol that has
provided a specific Objective-C name (e.g., via @objc(renamed)),
mangle such protocols using their Objective-C names so they can be
found at runtime.
Only do this for metadata, because doing it anywhere else would cause
an ABI break. Fixes rdar://problem/47877748.
This is essentially a long-belated follow-up to Arnold's #12606.
The key observation here is that the enum-tag-single-payload witnesses
are strictly more powerful than the XI witnesses: you can simulate
the XI witnesses by using an extra case count that's <= the XI count.
Of course the result is less efficient than the XI witnesses, but
that's less important than overall code size, and we can work on
fast-paths for that.
The extra inhabitant count is stored in a 32-bit field (always present)
following the ValueWitnessFlags, which now occupy a fixed 32 bits.
This inflates non-XI VWTs on 32-bit targets by a word, but the net effect
on XI VWTs is to shrink them by two words, which is likely to be the
more important change. Also, being able to access the XI count directly
should be a nice win.
Extend the key-path pattern with a representation of the generic environment
of the key-path, which includes the generic parameters and generic
requirements of the environment.
Switch key path metadata over to mangled names for each of the places it
refers to either a type metadata accessor or a witness table accessor. For
now, the mangled name is a symbolic reference to the existing accessors.
Part of rdar://problem/38038799.
The current representation of an associated conformance in a witness
tables (e.g., Iterator: IteratorProtocol within a witness table for
Sequence) is a function that the client calls.
Replace this with something more like what we do for associated types:
an associated conformance is either a pointer to the witness table (once
it is known) or a pointer to a mangled name that describes that
conformance. On first access, demangle the mangled name and replace the
entry with the resulting witness table. This will give us a more compact
representation of associated conformances, as well as always caching
them.
For now, the mangled name is a sham: it’s a mangled relative reference to
the existing witness table accessors, not a true mangled name. In time,
we’ll extend the support here to handle proper mangled names.
Part of rdar://problem/38038799.
(file)private entities are always available in the current file, so use
symbolic references to refer to them within mangled names (always). This
also eliminates problems stemming from our inability to demangle names
referring to private entities, because we (intentionally) don't allow
lookup for them.
Should fix rdar://problem/44977236.
Extending the mangling of symbolic references to also include indirect
symbolic references. This allows mangled names to refer to context
descriptors (both type and protocol) not in the current source file.
For now, only permit indirect symbolic references within the current module,
because remote mirrors (among other things) is unable to handle relocations.
Co-authored-by: Joe Groff <jgroff@apple.com>
(file)private entities are always available in the current file, so use
symbolic references to refer to them within mangled names (always). This
also eliminates problems stemming from our inability to demangle names
referring to private entities, because we (intentionally) don't allow
lookup for them.
Should fix rdar://problem/44977236.
Encode default associated type witnesses using a sentinel prefix byte
(0xFF) in the mangled name rather than as a second low bit on the
reference. Align all of the mangled names used for type references to
2 bytes (so we get that low bit regardless) and separate the symbol
names for default associated type witnesses vs. other kinds of
metadata or reflection metadata.
More groundwork for protocols with superclass constraints.
In several places we need to distinguish between existential
types that have a superclass term (MyClass & Proto) and
existential types containing a protocol with a superclass
constraint.
This is similar to how I can write 'AnyObject & Proto', or
write 'Proto1 & Proto2' where Proto1 has an ': AnyObject'
in its inheritance clause.
Note that some of the usages will be revisited later as
I do more refactoring and testing. This is just a first pass.