Commit Graph

296 Commits

Author SHA1 Message Date
David Farler
787b0dcc3f Merge pull request #3419 from bitjammer/remote-mirror-metadata-version
SwiftRemoteMirror: Add reflection metadata version query API
2016-07-14 08:30:18 -07:00
Doug Gregor
823c24b355 [SE-0112] Rename ErrorProtocol to Error.
This is bullet (5) of the proposed solution in SE-0112, and the last
major piece to be implemented.
2016-07-12 10:53:52 -07:00
David Farler
941ec1e043 SwiftRemoteMirror: Add reflection metadata version query API
rdar://problem/27251582
2016-07-08 14:12:59 -07:00
Slava Pestov
95bc009e3e Reflection: Multi-payload enum layout
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.
2016-07-01 01:31:25 -07:00
Slava Pestov
48c928938a Reflection: Single-payload enum layout
Attempt to lay out single-payload enums, using knowledge of extra
inhabitants where possible.

- The extra inhabitants of an aggregate are the extra inhabitants of
  the first field. If the first field is empty, there are no extra
  inhabitants, and subsequent fields do not affect anything.

- Function pointers and metatypes have different extra inhabitants
  than Builtin.RawPointer, so have IRGen emit distinct builtin type
  descriptors for those.

- Opaque existentials do not have extra inhabitants.

- Weak references do not have extra inhabitants.

Also, fix IRGen to emit more accurate enum reflection metadata in
these two cases:

- We now record whether enum cases are indirect or not. An indirect
  case is the same as a payload case with Builtin.NativeObject.

- We now record whether a case is empty or not using the same logic
  as the rest of IRGen. Previously, we would incorrectly emit a
  payload type for a case with a payload that is an empty struct,
  for example.

At this point we don't have a way to get the currently inhabited
enum case from a value. However, this is still an improvement because
we can still reflect other fields of aggregates containing enums,
instead of just giving up.

Finally make some methods on TypeCoverter private, and use 'friend'
to allow them to be accessed from other internal classes, making the
public API simpler.
2016-06-30 12:57:14 -06:00
Saleem Abdulrasool
f29e6144a4 Reflection: use std::strtol instead of std::atoi
Address post-commit review comments from Harlan.  Use `std::strtol` as it can
deal with hex and octal inputs.
2016-06-22 19:07:59 -07:00
Saleem Abdulrasool
b979359d43 Reflection: use atoi instead of stoi
The Microsoft C++ library does not have std::stoi.  Opt to use std::atoi with
the C-string backing the std::string.  NFC.
2016-06-20 07:13:00 -07:00
Slava Pestov
e2cf23d971 Reflection: Don't emit builtin descriptors for imported classes
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>.
2016-05-26 19:32:59 -07:00
David Farler
2799cabcfb SwiftRemoteMirror: Dig into generic SIL boxes
Part 1: Generic SIL Boxes always have instatiated metadata with kind
HeapGenericLocalVariable, which includes a metadata pointer for the
boxed type.

Part 2, after this, is to provide some kind of outgoing pointer map for
fixed heap boxes, whose metadata may be shared among different but
destructor-compatible types.

rdar://problem/26240419
2016-05-17 01:30:28 -07:00
David Farler
c9e0df7d4d Add an opaque field for necessary bindings struct
Without this, offsets of captures in closure contexts may be
incorrect if there is a non-empty necessary bindings structure
at the front.

rdar://problem/26312900
2016-05-16 20:25:35 -07:00
practicalswift
21c872c590 [gardening] Fix recently introduced typos. 2016-05-14 20:33:28 +02:00
David Farler
fe2872fae1 SwiftRemoteMirror: Lower types with imported / Objective-C types
- Lower Objective-C class typerefs as strong references with unknown
reference counting.
- Lower other imported C types as builtin blobs of their known
size, alignment, etc.

In the future, it might be beneficial to track which stored properties
of imported types are pointers, for better conservative scanning of
outgoing pointers to the heap.

rdar://problem/26240258
rdar://problem/26240394
2016-05-12 20:49:32 -07:00
Slava Pestov
710d7ede71 Reflection: Break out SWIFT_RAW_POINTER vs SWIFT_BUILTIN in the C API
Also, use "opaque existential" consistently to refer to non-class
existentials, and clean up some other random bits.
2016-05-12 18:27:35 -07:00
Slava Pestov
85a75524d5 Reflection: Clearer metadata offset calculations, NFC 2016-05-11 22:51:32 -07:00
David Farler
9dddc6492b SwiftRemoteMirror: Project error existentials
Error existentials have a kind of special heap layout and can also
be compatible as NSError instances, too.
2016-05-10 12:50:31 -07:00
Slava Pestov
c90ee3c322 Reflection: Fix for last-minute fix for 32-bit platforms that broke 64-bit platforms 2016-05-09 14:18:04 -07:00
Slava Pestov
75bd780aca Reflection: Add support for closure contexts to readMetadataFromInstance()
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.
2016-05-09 13:41:56 -07:00
Slava Pestov
4fccd2f6fc Reflection: Closure context layout
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.
2016-05-09 13:40:58 -07:00
Slava Pestov
0dffbcb791 Reflection: Add TypeLowering::hasFixedSize() 2016-05-09 13:40:57 -07:00
Slava Pestov
5cc4ce1760 Reflection: Looking up CaptureDescriptors by remote address
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.
2016-05-09 13:40:57 -07:00
Slava Pestov
2abcd97aa8 Reflection: Remove some unused code, NFC 2016-05-09 13:40:57 -07:00
practicalswift
c262b42ae0 [gardening] Fix recently introduced whitespace typos. (#2443) 2016-05-06 23:49:39 -07:00
Slava Pestov
9e9acd2dfe Reflection: Add RecordTypeInfoBuilder class to TypeLowering.h, NFC
Closure context layout uses this class.
2016-05-06 15:13:23 -07:00
Slava Pestov
73b1bd8f4e Reflection: Add TypeRef::deriveSubstitutions()
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.
2016-05-05 22:28:48 -07:00
Slava Pestov
a62d414086 Reflection: Add TypeRef::isConcreteAfterSubstitutions()
This is needed for closure context layout.
2016-05-05 22:28:48 -07:00
Slava Pestov
5858756651 Reflection: Correct handling of nested types in TypeRef substitution 2016-05-05 22:28:48 -07:00
Slava Pestov
a1f37a4b9e Reflection: Fix formatting, NFC 2016-05-05 22:28:48 -07:00
David Farler
7e06ee45e8 SwiftReflectionContext: Remove dependency on SwiftRemoteMirror header
Although mechanically it's not a circular dependency yet, conceptually
it is. Use RemoteAddress instead of the raw addr_t typedef.
2016-05-04 13:33:08 -07:00
David Farler
656c3936d2 projectExistential: Use the metadata field offset as size comparison
It's more accurate to use the offset of the "metadata field" of the
existential's RecordTypeInfo when projecting an existential
during remote reflection.
2016-05-04 00:23:29 -07:00
David Farler
7827b75493 projectExistential: Fix doc comment re: class existential layout 2016-05-04 00:02:50 -07:00
David Farler
5f5ce39a1d SwiftRemoteMirror: Wire up existential projection API
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.
2016-05-03 21:04:31 -07:00
Slava Pestov
86dae6850c Reflection: Add SILBoxTypeRef, which can come up in capture descriptors 2016-05-02 19:26:12 -07:00
Slava Pestov
efca93e632 Reflection: Add dumping of capture descriptors to swift-reflection-dump
The tests show that there's some round-tripping issue; I will investigate
this next.
2016-05-02 01:16:25 -07:00
Slava Pestov
71d28691ef Reflection: Plumb through capture descriptor section 2016-05-02 01:16:25 -07:00
Slava Pestov
9627aa98b5 Reflection: Add operator-> overloads to reflection section iterators 2016-05-02 01:16:24 -07:00
Slava Pestov
8f3279a17d Reflection: Formatting fix, NFC 2016-05-02 01:16:24 -07:00
Slava Pestov
faecfda594 Reflection: Consolidate some code for passing around reflection sections
I'm about to add a new section, and I'd like to update as few
places as possible.
2016-04-30 15:12:38 -07:00
Slava Pestov
1d5b9b09ac Reflection: Add instance-specific layout entry point, and do some refactoring
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.
2016-04-29 15:39:49 -07:00
Slava Pestov
1bd536e577 Reflection: Fix compile error, oops 2016-04-29 15:39:49 -07:00
Slava Pestov
8f06358b5b Reflection: Fix typos 2016-04-29 15:13:29 -07:00
Slava Pestov
e81fca926a Reflection: Use correct starting offset and alignment in class instance layout
Also, add caching for class instance layout.
2016-04-28 22:56:15 -07:00
Slava Pestov
ce1c30b1bc Reflection: Support reading the remote process's isaMask
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.
2016-04-28 22:56:15 -07:00
Slava Pestov
7a9a4dca83 Reflection: Preliminary C API entry points for class instance layout
Tested by manually running swift-reflection-test, no automated
tests yet, but coming soon.
2016-04-27 23:15:08 -07:00
Slava Pestov
95d648779b Reflection: Fix some bugs in swift-reflection-test
- 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.
2016-04-27 18:17:25 -07:00
David Farler
243bc7545b Move cache check into TypeRefs' static create methods
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
2016-04-26 01:11:35 -07:00
David Farler
8e0412f84f Don't include Parent pointer in Nominal/BoundGeneric TypeRef uniquing
This information is already in the mangled type name.
2016-04-26 01:11:31 -07:00
David Farler
defe2b17a2 Include WasAbstract flag when uniquing MetatypeTypeRef 2016-04-26 00:11:46 -07:00
David Farler
dd7b6635e8 TypeRefID: Only add high bits of a pointer if on 64-bit
Adding another 0 to the TypeRefID bits is useless on 32-bit
platforms.
2016-04-25 23:56:28 -07:00
David Farler
50440abcd0 TypeRef Uniquing
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
2016-04-25 23:56:28 -07:00
David Farler
d9368ff5ec Wrap 80-columns, NFC. 2016-04-25 23:56:28 -07:00