[swift-dev] Understanding runtime entry points

Joe Groff jgroff at apple.com
Wed Jan 6 15:23:14 CST 2016


> On Jan 6, 2016, at 12:46 PM, Austin Zheng <austinzheng at gmail.com> wrote:
> 
> Thanks Joe, this is incredibly helpful, especially the note about how enums are passed in 'piecewise'.

To clarify, what you're seeing in EnumMirror is not the enum itself, but the _EnumMirror structure, which is itself designed to be bitwise-compatible with a generic (owner, type, pointer to value) triple that can reference an arbitrary value in memory while keeping it alive if reference-counted. The 'value' field in this structure is always a pointer to the value of the 'type' type in memory. 

> 
> re. your question: I was indeed calling the C++ function from Swift and directly passing in the enum (in pseudo-Swift):
> let myEnum : SomeEnumType = ...
> cplusplusFunction(value: myEnum, type: SomeEnumType.self)  // incorrect
> 
> How would I pass a pointer to the enum's value from Swift? I don't think Swift exposes any mechanism to get the memory address of a Swift object. Perhaps I should create an UnsafeMutablePointer<SomeEnumType>, set its memory to (a copy of) the enum value, and pass that pointer object in instead?

If all you want is the enum tag, you could implement a more straightforward interface. In Swift:

@_silgen_name("_swift_stdlib_getEnumTag")
func _getEnumTag<T>(value: T) -> Int32

In C++:

/// Return the tag number for an enum, or crash if the value is not of enum type.
int32_t _swift_stdlib_getEnumTag(OpaqueValue *value, const Metadata *type) {
  assert(type->getKind() == MetadataKind::Enum);
  auto tag = type->vw_getEnumTag(value);
  type->vw_destroy(value);
  return tag;
}

-Joe


More information about the swift-dev mailing list