Also add end-to-end tests for this finally, and fix a bug in
the SwiftReflectionTest library where we would give up on an
module completely if it did not have a field metadata section.
This is of course wrong if the module defines closures but
not nominal types.
This adds various MetadataReader methods to support closure layout:
- Reading generic arguments from metadata
- Reading parent metadata
- Reading capture descriptor from heap metadata
To a large extent, this is not currently taken advantage of, because
SILGen always wraps address-only captures in SIL box types.
Tests are in the next patch.
Remote metadata for closure contexts points to a capture descriptor.
We have a local copy of all capture descriptors. Translate the
address by recording the local and remote start address of
reflection metadata.
When deriving substitutions from closure contexts, we end up with
a problem where we have an original type and a substituted type,
and the original type is not necessarily a type parameter.
We need to decompose the original and substituted types to derive
the substitutions that produced the substitution.
For example, deriveSubstitutions(Foo<T -> Int>, Foo<String -> Int>)
will give us a substitution of T := Int.
It's more accurate to use the offset of the "metadata field" of the
existential's RecordTypeInfo when projecting an existential
during remote reflection.
Implement the ReflectionContext's implementation of:
swift_reflection_projectExistential.
First, we get the type info of the existential typeref - it should be a
record type info. If it's a class existential, it has trivial layout:
the first word is a pointer to the class instance. Otherwise, if the
value fits in the 3-word buffer of the existential container, it
trivially is also at the start of the container. Otherwise, the value is
off in a heap box somewhere, but the first word of the container is a
pointer to that box.
Closure context layout will depend on the instance itself as well
as the isa pointer, because instead of instantiating metadata for
closures that capture generic parameters, we store the substitutions
inside the context itself.
For classes, this entry point just reads the isa pointer, applies
the isa mask and proceeds down the metadata path.
For now, the only the latter is hooked up.
Also, use the instance layout entry point in swift-reflection-test,
so that we can dump the layout of a class instance and not the
lowering of the reference value.
- Improper handling of read() returning an incomplete read
- Update SwiftReflectionTest library for new builtin types section
Only tested manually so far; automated tests coming soon.
along with the boilerplate macro. This allows one to create TypeRefs
with either the builder or via the static methods, so long as a builder
argument is supplied so uniquing caches can be checked.
rdar://problem/25924875
We'd like to be able to compare TypeRefs with pointer equality,
but we can't link LLVMSupport, so make a lightweight TypeRefID
like FoldingSetID, that only supports the input types necessary
to unique TypeRefs.
rdar://problem/25924875
The metadata system doesn't actually unique based on labels
correctly, so the test case has to play some games. That's
something that will be easier to fix when there are fewer
clients poking at the internals of the metadata runtime.
The thin vs thick distinction is handled a little awkwardly. Instead of
passing around abstraction patterns, we add a "must be thick" bit to
MetatypeTypeRef, and thicken substitutions (to handle T; T := C.Type)
and the result of a subtitution (to handle T.Type; T := C).
With the exception of enums this completes <rdar://problem/25738849>.
For now, just enough for lowering.
Perhaps we should have a way to always just get this information
from metadata instead, since protocol metadata is always static
and not instantiated.
This would require the static "object file" interface used by
swift-reflection-dump to take a callback for symbol lookup.
Also add slightly inaccurate lowering for the special case of an
optional of a reference type. I need to rethink the approach for
extra inhabitants and enums, but this suffices for now.