Skip to content

[Swift shipping] Update CryptoKit tests to use generated projections #2705

@kotlarmilos

Description

@kotlarmilos

Note

This is a draft issue that tracks feedback from the #2704. Ii will be updated with more details soon.

Overview

This issue tracks the the existing design proposals of Swift runtime features required for the interop.

Metadata

The existing implementation from the CryptoKit example:

public static unsafe void* GetMetadata<T>(ISwiftObject obj) {
    return obj.Metadata;
}

Proposal based on measurements:

public static bool TryGetMetadata (Type t, out Metadata metadata)
{
    // one catch - t must not be an unbound generic.
    if (typeof(ISwiftObject).IsAssignableFrom(t)) {
        metadata = GetMetadataFromISwiftObject(t);
        return true;
    }
    // over time we add the cases we need for tuples, nint, nuint, nfloat, etc.
    // I'd like to see this ultimately be a ladder of `else if` constructs for each major type ordered by
    // most common and/or cheapest predicates. For example, identifying certain scalars should be
    // a matter of looking at `t.GetTypeCode()`
    return false;
}

static Metadata GetMetadataFromISwiftObject(Type t) // t is guaranteed to be ISwiftObject compatible 
{
    if (typeof(ISwiftObject).IsAssignableFrom(t))
    {
        var metadataProperty = t.GetProperty("Metadata", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
        if (metadataProperty != null)
        {
            var metadataValue = metadataProperty.GetValue(null);
            if (metadataValue is IntPtr ptr)
            {
                return ptr.ToPointer();
            }
        }
    }
    // no try/get pattern needed, this is a private API 
    throw new ArgumentException($"Type {t.Name} does not implement ISwiftObject.");
}

Consider creating a new type for the metadata - a struct containing either an IntPtr, a NativeHandle, or a void*. There will be sufficient functions that will have metadata as arguments that we are likely to have signature conflicts.

Protocol conformance descriptor

The existing implementation from the CryptoKit example:

public static unsafe void* GetConformanceDescriptor(string symbol)
  {
      IntPtr handle = IntPtr.Zero;
      try
      {
          handle = NativeLibrary.Load(Foundation.Path);
          void* conformanceDescriptor = NativeLibrary.GetExport(handle, symbol).ToPointer();
          return conformanceDescriptor;
      }
      catch (Exception ex)
      {
          throw new InvalidOperationException($"Failed to get conformance descriptor for symbol: {symbol}", ex);
      }
      finally
      {
          if (handle != IntPtr.Zero)
          {
              NativeLibrary.Free(handle);
          }
      }
  }

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions