Skip to content

Commit

Permalink
[SwiftBindings] Adds runtime support for protocol constraints (#2969)
Browse files Browse the repository at this point in the history
* Add placeholder protocol projections

* Add support for conformances in type declarations

* Replaced string with ProtocolSpec on ProtocolConformance

* Added initial support for non-pat protocol constraint

* Reverted some changes introduced in previous PR to ensure defensive handling of constructors

* Added PAT support

* Removed Conformances from Protocols

* Simplified ProtocolConformance record

* Fixed bug when passing multiple generic params of the same type resulted in compile error

* Refactored ProtocolWitnessTable name generation to use NameProvider for consistency

* Fix failing build

* Applied review feedback

* Used static field for protocolConformanceSymbols

* Applied review feedback

* Add TODO comment for reverting struct writing in generic method handling
  • Loading branch information
jkurdek authored Feb 3, 2025
1 parent 4e8f6ec commit ce200f0
Show file tree
Hide file tree
Showing 19 changed files with 721 additions and 200 deletions.
64 changes: 64 additions & 0 deletions src/Swift.Bindings/src/DemangledSymbols.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using BindingsGeneration;
using Xamarin;

public readonly record struct DemangledSymbols
{
public Dictionary<(NamedTypeSpec, NamedTypeSpec), string> ProtocolConformanceDescriptors { get; init; }

public DemangledSymbols(Dictionary<(NamedTypeSpec, NamedTypeSpec), string> descriptors)
{
ProtocolConformanceDescriptors = descriptors;
}
}

public sealed class DemangledSymbolsRegister
{
private static readonly Lazy<DemangledSymbolsRegister> _instance = new(() => new DemangledSymbolsRegister());

private DemangledSymbols _symbols = new(new Dictionary<(NamedTypeSpec, NamedTypeSpec), string>());
private bool _isLoaded = false;

public static DemangledSymbolsRegister Instance => _instance.Value;

private DemangledSymbolsRegister() { }

public DemangledSymbols GetData(string dylibPath = "")
{
if (!_isLoaded)
{
if (string.IsNullOrEmpty(dylibPath))
{
throw new ArgumentException("dylibPath cannot be null or empty.");
}

Load(dylibPath);
}
return _symbols;
}

private void Load(string dylibPath)
{
try
{
var abis = MachO.GetArchitectures(dylibPath);
var descriptors = DemanglingResults.FromFile(dylibPath, abis[0]).ProtocolConformanceDescriptors;
var dictionary = new Dictionary<(NamedTypeSpec, NamedTypeSpec), string>();

foreach (var descriptor in descriptors)
{
dictionary[(descriptor.ImplementingType, descriptor.ProtocolType)] = descriptor.Symbol[1..];
}

_symbols = new DemangledSymbols(dictionary);
_isLoaded = true;
}
catch (Exception e)
{
// This happens if the dylib cannot be located on disk, which will be the case for Apple shipped dylibs. (e.g. Foundation, StoreKit, etc.)
Console.Error.WriteLine($"Error loading demangled symbols: {e.Message}");
}
}
}
Loading

0 comments on commit ce200f0

Please sign in to comment.