> On Jan 1, 2016, at 10:58 PM, Austin Zheng via swift-dev <swift-dev@swift.org> 
> wrote:
> 
> Hello,
> 
> I'm trying to better understand how calls are made between the Swift standard 
> library code and the runtime entry points. I've read through most of the 
> documentation in the repo but still have some questions.

The particular functions in question aren't so much runtime entry points as 
Swift methods that happen to be written in C++, in a way that makes them 
incidentally ABI-compatible with Swift methods. 

> More specifically, here's an example: the '_EnumMirror' struct below 
> represents a mirror reflecting a value whose type is an enum. 
> 
> ------
> 
> struct _EnumMirror : _MirrorType {
>  let data: _MagicMirrorData
>  var value: Any { return data.value }
>  var valueType: Any.Type { return data.valueType }
>  // ... more stuff
> 
>  var caseName: UnsafePointer<CChar> {
>    @_silgen_name("swift_EnumMirror_caseName")get
>  }
>  // ... (more stuff)
> }
> 
> ------
> 
> The 'caseName' property represents the name of the enum value's case (e.g. 
> "FirstCase" in Foo.FirstCase) as a C string. This property's getter calls 
> into a C++ runtime function named "swift_EnumMirror_caseName", which is 
> reproduced below (from Reflection.mm):
> 
> extern "C"
> const char *swift_EnumMirror_caseName(HeapObject *owner,
>                                      const OpaqueValue *value,
>                                      const Metadata *type) {
>  if (!isEnumReflectable(type))
>    return nullptr;
> 
>  const auto Enum = static_cast<const EnumMetadata *>(type);
>  const auto &Description = Enum->Description->Enum;
> 
>  unsigned tag;
>  getEnumMirrorInfo(value, type, &tag, nullptr, nullptr);    // effectively, 
> same as "tag = type->vw_getEnumTag(value);"
>  return getFieldName(Description.CaseNames, tag);
> }
> 
> Now, I had a few questions about exactly how this interoperation works, 
> because I'd like to be able to get the name of an enum case using this entry 
> point from a different context (not from within an _EnumMirror property).
> 
> * swift_EnumMirror_caseName takes three arguments, but the Swift call site 
> doesn't seem to specify what gets passed into the function. Is there a 
> convention that is implicitly passing properties on _EnumMirror as arguments 
> into the C++ function when it's being called? I did note that there were 
> other runtime entry points (like "swift_MagicMirrorData_summary") where the 
> number of arguments in the Swift function matched the number of arguments in 
> the C++ function, but in those cases the Swift function was a free function 
> and not a method.

Swift structs are (currently) passed by passing each stored property 
individually. _EnumMirror is defined as a struct with owner/value/type fields, 
and the 'self' parameter to its methods gets broken down this way.

> * What I really want to do is to get the tag of an enum. I wrote a different 
> entry point that omits the unused "owner" property and simply calls 
> swift_EnumMirror_caseName with nullptr as the first argument. This other C++ 
> function takes 'value' (an OpaqueValue*) and 'type' (a Metadata*). I've 
> surmised that 'type' should be the Swift metatype of the enum instance (e.g. 
> myEnum.dynamicType), and I do get the case names table. However, if I pass in 
> the enum instance itself as 'value', my tag is always retrieved as 0. I 
> noticed that there's some sort of indirection in the form of "vw_getEnumTag", 
> which goes through something called the "value witness". Is there somewhere I 
> can read up about the value witness concept? I assume the reason the 
> 'original' code worked was because it was passing in a different object as 
> 'value', maybe one that could serve as a value witness for the reflected-upon 
> instance's type.

'value' is a pointer to the value in memory, not the value itself. Are you 
passing the enum's literal representation by value instead of passing a pointer 
to it?

-Joe

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to