This attribute is used in the simd overlay. To ensure we can layout
SIMD types correctly, emit a fixed type descriptor instead of a
field type descriptor for these types.
There was some duplication here, and also a potential
memory management issue; it appears that we were
converting a temporary std::string to a StringRef
when setting the section name of a global.
Ensure they get emitted at the end of the job by the dispatcher, and
also use a proper mangling and shared linkage for these symbols so
that if multiple threads emit the same descriptor it gets merged.
The new tests attempt to exercise these scenarios.
Fixes <rdar://problem/27906876>.
for weak semantics, that is!
94a9c512b9 made some changes to loading
weak references by adding some information in the lower bits with
respect to locking. These bits need to be masked out when performing a
load, such as when we want to get the metadata pointer for a class
instance. This normally works fine when going through the normal weak
loading functions in the runtime.
When the runtime function swift_ClassMirror_subscript gets the offset of
one of its stored properties, it immediately packages it into the the
ad-hoc existential container, known as just `Mirror` in the runtime.
However, the weak reference isn't aligned! It has bit 1 set. We weren't
loading the weak reference here as we would during normal SILGen, such
as with a weak_load instruction. Simulate that here and make the
reference strong before putting it into the Mirror container, which also
clears those lower bits.
rdar://problem/27475034
There are still a couple of other cases to handle, namely the
unowned(safe) and unowned(unsafe) reference kinds. There may be other
places where an unaligned pointer is problematic in the runtime, which
we should audit for correctness.
rdar://problem/27809991
Emit a 16-bit constant that tracks the version of the reflection
metadata emitted into binaries. This can be used to cross-check
what is supported by the SwiftRemoteMirror library with the new
version API.
rdar://problem/27251582
The approach here is to split this into two cases:
- If all case payloads have a fixed size, spare bits may be
potentially used to differentiate between cases, and the
remote reflection library does not have enough information to
compute the layout itself.
However, the total size must be fixed, so IRGen just emits a
builtin type descriptor (which I need to rename to 'fixed type
descriptor' since these are also used for imported value types,
and now, certain enums).
- If at least one case has a size that depends on a generic
parameter or is a resilient type, IRGen does not know the size,
but this means fancy tricks with spare bits cannot be used either.
The remote reflection library uses the same approach as the
runtime, basically taking the maximum of the payload size and
alignment, and adding a tag byte.
As with single-payload enums, we produce a new kind of
RecordTypeInfo, this time with a field for every enum case.
All cases start at offset zero (but of course this might change,
if for example we put the enum tag before the address point).
Also, just as with single-payload enums, there is no remote
'project case index' operation on ReflectionContext yet.
So the the main benefit from this change is that we don't entirely
give up when doing layout of class instances containing enums;
however, tools still cannot look inside the enum values themselves,
except in the simplest cases involving optionals.
Notably, the remote reflection library finally understands all
of the standard library's collection types -- Array, Character,
Dictionary, Set, and String.
@convention(witness_method) values were changed to carry a pointer to their source witness table, but the type info wasn't changed to match. Fixing this fixes rdar://problem/26268544.
Instead of hooking into nominal type and extension emission
and walking all conformances of those declarations, let's
just directly hook into the logic for emitting conformances.
This fixes an issue where we would apparently emit duplicate
conformances, as well as unnecessary conformances that are
defined elsewhere.
When we encounter a protocol typeref, we have to know if its @objc,
class-bound, or opaque, so make sure we provide the necessary
information when imported protocols are referenced.
Previously we would emit both a builtin descriptor and field
descriptor for imported classes, but we only need the latter.
Untangle some code and fix a crash with imported Objective-C
generics in the process.
Fixes <rdar://problem/26498484>.
We were recovering metadata from generic boxes by reading
the instantiated payload metadata from the box's metadata,
but this approach doesn't work for fixed-size boxes, whose
metadata does not store the payload metadata at all.
Instead, emit a capture descriptor with no metadata sources
and a single capture, using the lowered AST type appearing
in the alloc_box instruction that emitted the box.
Since box metadata is shared by all POD types of the same
size, and all single-retainable pointer payloads, the
AST type might not accurately reflect what is actually in
the box.
However, this type is *layout compatible* with the box
payload, at least enough to know where the retainable
pointers are, because after all IRGen uses this type to
synthesize the destructor.
Fixes <rdar://problem/26314060>.
When emitting capture descriptors for functions with a smaller number of parameters
than SIL parameters, the compiler can crash indexing into the heap layout's element
types, because the capture index underflows to UINT_MAX.
rdar://problem/26404583
Previously, we had hacks in place to eagerly emit everything in
the global ExternalDefinitions list. These can now be removed,
at least at the IRGen layer.
Clang IR-generation can fail. When it does this, it destroys the
module. Previously, we were blithely assuming this couldn't happen,
and so we would crash on the deallocated module. Delay the
finalization of the Clang code generator until our own module
finalization, which is a more appropriate place for it anyway,
and then just bail out of the last few steps if Clang fails.
- Fix caller/callee confusion, and use the right SIL function type
for obtaining the generic signature.
- Correctly interpret the NecessaryBindings structure and the
substitutions therein.
- Fix alignment for capture and builtin type descriptors
- Put capture descriptor typerefs in the correct section
Add new SIL-level tests to precisely trigger various scenarios.
Rather than collection nominal type and extension decls and emit
reflection metadata records in one go, we can emit them as they
are encountered and instead collection builtin types referenced
by those at the end.
specialization to be separately lowered in IRGen, use the mangling
of the specialized type as the name of the llvm::StructType instead
of the base, unspecialized type.
This tends to produce fewer collisions between IR type names.
LLVM does unique the names on its own, so that's not strictly
necessary, but it's still a good idea because it makes the test
output more reliable and somewhat easier to read (modulo the
impact of bigger type names). Collisions will still occur if
the type is specialized at an archetype, since in this case we
will fall back on the unspecialized type.
Now we can discern the types of values in heap boxes at runtime!
Closure reference captures are a common way of creating reference
cycles, so this provides some basic infrastructure for detecting those
someday.
A closure capture descriptor has the following:
- The number of captures.
- The number of sources of metadata reachable from the closure.
This is important for substituting generics at runtime since we
can't know precisely what will get captured until we observe a
closure.
- The number of types in the NecessaryBindings structure.
This is a holding tank in a closure for sources of metadata that
can't be gotten from the captured values themselves.
- The metadata source map, a list of pairs, for each
source of metadata for every generic argument needed to perform
substitution at runtime.
Key: The typeref for the generic parameter visible from the closure
in the Swift source.
Value: The metadata source, which describes how to crawl the heap from
the closure to get to the metadata for that generic argument.
- A list of typerefs for the captured values themselves.
Follow-up: IRGen tests for various capture scenarios, which will include
MetadataSource encoding tests.
rdar://problem/24989531
In order to perform layout, the remote mirrors library needs to know
about the size, alignment and extra inhabitants of builtin types.
Ideally we would emit a reflection info section in libswiftRuntime.o,
but in the meantime just duplicate builtin type metadata for all
builtin types referenced from the current module instead.
In practice only the stdlib and a handful of overlays like the SIMD
overlay use builtin types, and only a few at a time.
Tested manually by running swift-reflection-tool on the standard
library -- I'll add automated tests by using -parse-stdlib to
reference Builtin types in a subsequent patch that adds more layout
logic.
NFC if -enable-reflection-metadata is off.
Implements SE-0055: https://github.com/apple/swift-evolution/blob/master/proposals/0055-optional-unsafe-pointers.md
- Add NULL as an extra inhabitant of Builtin.RawPointer (currently
hardcoded to 0 rather than being target-dependent).
- Import non-object pointers as Optional/IUO when nullable/null_unspecified
(like everything else).
- Change the type checker's *-to-pointer conversions to handle a layer of
optional.
- Use 'AutoreleasingUnsafeMutablePointer<NSError?>?' as the type of error
parameters exported to Objective-C.
- Drop NilLiteralConvertible conformance for all pointer types.
- Update the standard library and then all the tests.
I've decided to leave this commit only updating existing tests; any new
tests will come in the following commits. (That may mean some additional
implementation work to follow.)
The other major piece that's missing here is migration. I'm hoping we get
a lot of that with Swift 1.1's work for optional object references, but
I still need to investigate.
initialization in-place on demand. Initialize parent metadata
references correctly on struct and enum metadata.
Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.
Includes a fix since the earlier commit to make enum metadata
writable if they have an unfilled payload size. This didn't show
up on Darwin because "constant" is currently unenforced there in
global data containing relocations.
This patch requires an associated LLDB change which is being
submitted in parallel.
initialization in-place on demand. Initialize parent metadata
references correctly on struct and enum metadata.
Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.
This was previously bumped to move from Swift 1.2 to 2.0. Time for 3.0.
Note, unlike last time (136965d9f8), the
CMakeLists.txt change already says 3.0 so that won't get changed here.
"minimal" is defined as the set of requirements that would be
passed to a function with the type's generic signature that
takes the thick metadata of the parent type as its only argument.
Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.
The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results. It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.
The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*. The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list. The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.
A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple. It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.
Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction. It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
IRGen now uses a ConstantBuilder to build protocol metadata, which may
now have additional fields at the end for default witnesses.
For now, the default implementations in the test have to external
because IRGen cannot emit a witness_method body where Self is
abstract. I will fix this by passing in the witness table as part
of the witness_method calling convention.
On the IRGen side, other than the calling convention change, the only
remaining piece here is emitting GenericWitnessTables and accessor
functions for conformances where the conformance is defined in
a different module than the protocol, and the protocol is resilient.
Sema still needs to infer default witnesses and store them in the
ProtocolDecl, so that SILGen can emit default witness thunks for
them.