> On Jan 6, 2016, at 12:57 PM, Austin Zheng <austinzh...@gmail.com> wrote:
> 
> Hey Slava,
> 
> Thanks a lot for your detailed responses; it definitely helps to understand 
> how structs are passed to the C++ function.
> 
> In a separate email, Joe Groff mentioned that there was a difference between 
> passing the enum value and passing a pointer to it. I think that might be the 
> root of my problem. I'll try a few things and send over a better code sample 
> tonight, if there are still issues.

Yeah, that sounds like it could be the problem.

In general, expecting the Swift calling convention to line up with C++ in this 
manner is really not something we want to officially support, and I believe 
JoeG is currently working on refactoring the runtime reflection interface to be 
a bit more minimal and orthogonal on the runtime side.

It would be great to see what you're working on, because I suspect we should be 
able to fold your use-case into the general reflection API.

Slava

> 
> Best,
> Austin
> 
> On Wed, Jan 6, 2016 at 11:37 AM, Slava Pestov <spes...@apple.com 
> <mailto:spes...@apple.com>> wrote:
> Hi Austin,
> 
> > On Jan 1, 2016, at 10:58 PM, Austin Zheng via swift-dev 
> > <swift-dev@swift.org <mailto: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.
> >
> > 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.
> 
> The three arguments together form the 'self' value of the call. That is, an 
> EnumMirror is a struct containing a pointer to the owner object, a pointer to 
> the value being reflected, and runtime type information for the value. You 
> can see this if you look at how the _MagicMirrorData struct is defined on the 
> swift side.
> 
> > 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.
> 
> Right.
> 
> >
> > * 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.
> 
> The value should indeed be a pointer to the enum value itself. Not sure why 
> it's not working for you, maybe you can share more code?
> 
> > 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.
> 
> The value witness table is a member of the type metadata. It contains entry 
> points for runtime manipulation of values of that type. The value witness 
> table is used for runtime generics (when I have a generic parameter 'T' and a 
> value of type 'T', the value witness functions are used for 
> copying/moving/destroying/etc values of type 'T'). They are also used for 
> reflection.
> 
> They're not really documented anywhere except for in the source code itself 
> -- see here:
> 
> include/swift/Runtime/Metadata.h
> lib/IRGen/ValueWitness.h
> 
> Slava
> 
> >
> > Thanks a lot for your time.
> >
> > Best,
> > Austin
> >
> > _______________________________________________
> > swift-dev mailing list
> > swift-dev@swift.org <mailto:swift-dev@swift.org>
> > https://lists.swift.org/mailman/listinfo/swift-dev 
> > <https://lists.swift.org/mailman/listinfo/swift-dev>
> 
> 

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

Reply via email to