Skip to content

[Swift projection tooling] Bridging generic constraints for metadata retrieval #2962

@jkurdek

Description

@jkurdek

Issue Summary

In the current implementation, we need to dynamically execute specific behaviors in generic contexts based on the type being processed. These behaviors include operations such as loading metadata or creating an instance of a C# object from a Swift handle.

The complexity arises because the types can either:

  1. Originate from Swift (e.g., types conforming to ISwiftObject).
  2. Be non-Swift types, such as primitive types or C#-specific types that conform to protocols.

Since these cases do not share a common interface or base class, we cannot enforce a shared abstraction to generalize behavior.

Current Approach

The current implementation uses helper classes/methods and leverages MakeGenericType (compatible with NativeAOT) to dynamically dispatch type-specific behavior. The implementation looks like this:

void DoSomething<T>()
{
    var type = typeof(T);

    if (typeof(ISwiftObject).IsAssignableFrom(type))
    {
        var helperType = typeof(DoSomethingHelper<>).MakeGenericType(type);
        helperType.GetMethod("DoForSwiftObject")!.Invoke(null, null);
    }
    else
    {
        // Handle other cases...
    }
}

This approach ensures compatibility with NativeAOT while working around the limitations of C#, which does not support constructs like:

void DoSomething<T>()
{
    if (T is ISwiftObject)
        T.DoSomething();
    else
        // Handle other cases...
}

However, this pattern introduces significant performance overhead due to:

  • The use of reflection (MakeGenericType, GetMethod, and Invoke).
  • The lack of caching, which leads to repeated and unnecessary reflection-based operations.

Problem Statement

The current pattern is slow and poses a significant performance bottleneck. Since the majority of calls into Swift involve this pattern, it impacts the overall efficiency of the system. We need to investigate alternatives or optimizations to reduce the performance overhead.


We already have a cache for this pattern when it comes to TypeMetadata

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions