Skip to content

Commit

Permalink
make IContractFactory.CreateContract non-static
Browse files Browse the repository at this point in the history
make Registry hold a collection of contract factories, optionally with a configure callback
  • Loading branch information
lambdageek committed Sep 12, 2024
1 parent 9aec4dd commit dd75ae8
Show file tree
Hide file tree
Showing 13 changed files with 45 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.Diagnostics.DataContractReader;

internal interface IContractFactory<IProduct> where IProduct : Contracts.IContract
internal interface IContractFactory<out TProduct> where TProduct : Contracts.IContract
{
static virtual IProduct CreateContract(ITarget target, int version) => throw new NotImplementedException();
TProduct CreateContract(ITarget target, int version);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FCodeVersions : IContractFactory<ICodeVersions>
{
static ICodeVersions IContractFactory<ICodeVersions>.CreateContract(ITarget target, int version)
ICodeVersions IContractFactory<ICodeVersions>.CreateContract(ITarget target, int version)
{
return version switch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FDacStreams : IContractFactory<IDacStreams>
{
static IDacStreams IContractFactory<IDacStreams>.CreateContract(ITarget target, int version)
IDacStreams IContractFactory<IDacStreams>.CreateContract(ITarget target, int version)
{
return version switch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FEcmaMetadata : IContractFactory<IEcmaMetadata>
{
static IEcmaMetadata IContractFactory<IEcmaMetadata>.CreateContract(ITarget target, int version)
IEcmaMetadata IContractFactory<IEcmaMetadata>.CreateContract(ITarget target, int version)
{
return version switch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FException : IContractFactory<IException>
{
static IException IContractFactory<IException>.CreateContract(ITarget target, int version)
IException IContractFactory<IException>.CreateContract(ITarget target, int version)
{
return version switch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FExecutionManager : IContractFactory<IExecutionManager>
{
static IExecutionManager IContractFactory<IExecutionManager>.CreateContract(ITarget target, int version)
IExecutionManager IContractFactory<IExecutionManager>.CreateContract(ITarget target, int version)
{
TargetPointer executionManagerCodeRangeMapAddress = target.ReadGlobalPointer(Constants.Globals.ExecutionManagerCodeRangeMapAddress);
Data.RangeSectionMap rangeSectionMap = target.ProcessedData.GetOrAdd<Data.RangeSectionMap>(executionManagerCodeRangeMapAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FLoader : IContractFactory<ILoader>
{
static ILoader IContractFactory<ILoader>.CreateContract(ITarget target, int version)
ILoader IContractFactory<ILoader>.CreateContract(ITarget target, int version)
{
return version switch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FObject : IContractFactory<IObject>
{
static IObject IContractFactory<IObject>.CreateContract(ITarget target, int version)
IObject IContractFactory<IObject>.CreateContract(ITarget target, int version)
{
ulong methodTableOffset = (ulong)target.GetTypeInfo(DataType.Object).Fields["m_pMethTab"].Offset;
byte objectToMethodTableUnmask = target.ReadGlobal<byte>(Constants.Globals.ObjectToMethodTableUnmask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FPrecodeStubs : IContractFactory<IPrecodeStubs>
{
static IPrecodeStubs IContractFactory<IPrecodeStubs>.CreateContract(ITarget target, int version)
IPrecodeStubs IContractFactory<IPrecodeStubs>.CreateContract(ITarget target, int version)
{
TargetPointer precodeMachineDescriptorAddress = target.ReadGlobalPointer(Constants.Globals.PrecodeMachineDescriptor);
Data.PrecodeMachineDescriptor precodeMachineDescriptor = target.ProcessedData.GetOrAdd<Data.PrecodeMachineDescriptor>(precodeMachineDescriptorAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FReJIT : IContractFactory<IReJIT>
{
static IReJIT IContractFactory<IReJIT>.CreateContract(ITarget target, int version)
IReJIT IContractFactory<IReJIT>.CreateContract(ITarget target, int version)
{
TargetPointer profControlBlockAddress = target.ReadGlobalPointer(Constants.Globals.ProfilerControlBlock);
Data.ProfControlBlock profControlBlock = target.ProcessedData.GetOrAdd<Data.ProfControlBlock>(profControlBlockAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FRuntimeTypeSystem : IContractFactory<IRuntimeTypeSystem>
{
static IRuntimeTypeSystem IContractFactory<IRuntimeTypeSystem>.CreateContract(ITarget target, int version)
IRuntimeTypeSystem IContractFactory<IRuntimeTypeSystem>.CreateContract(ITarget target, int version)
{
TargetPointer targetPointer = target.ReadGlobalPointer(Constants.Globals.FreeObjectMethodTable);
TargetPointer freeObjectMethodTable = target.ReadPointer(targetPointer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;

internal sealed class FThread : IContractFactory<IThread>
{
static IThread IContractFactory<IThread>.CreateContract(ITarget target, int version)
IThread IContractFactory<IThread>.CreateContract(ITarget target, int version)
{
TargetPointer threadStorePointer = target.ReadGlobalPointer(Constants.Globals.ThreadStore);
TargetPointer threadStore = target.ReadPointer(threadStorePointer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,52 @@ internal sealed class Registry : IRegistry
// Contracts that have already been created for a target.
// Items should not be removed from this, only added.
private readonly Dictionary<Type, IContract> _contracts = [];
private readonly Dictionary<Type, IContractFactory<IContract>> _factories;
private readonly Target _target;

public Registry(Target target)
public Registry(Target target, Action<Dictionary<Type, IContractFactory<IContract>>>? configureFactories = null)
{
_target = target;
_factories = new () {
[typeof(IException)] = new FException(),
[typeof(ILoader)] = new FLoader(),
[typeof(IEcmaMetadata)] = new FEcmaMetadata(),
[typeof(IObject)] = new FObject(),
[typeof(IThread)] = new FThread(),
[typeof(IRuntimeTypeSystem)] = new FRuntimeTypeSystem(),
[typeof(IDacStreams)] = new FDacStreams(),
[typeof(ICodeVersions)] = new FCodeVersions(),
[typeof(IPrecodeStubs)] = new FPrecodeStubs(),
[typeof(IExecutionManager)] = new FExecutionManager(),
[typeof(IReJIT)] = new FReJIT(),
};
configureFactories?.Invoke(_factories);
}

public IException Exception => GetContract<FException, IException>();
public ILoader Loader => GetContract<FLoader, ILoader>();
public IEcmaMetadata EcmaMetadata => GetContract<FEcmaMetadata, IEcmaMetadata>();
public IObject Object => GetContract<FObject, IObject>();
public IThread Thread => GetContract<FThread, IThread>();
public IRuntimeTypeSystem RuntimeTypeSystem => GetContract<FRuntimeTypeSystem, IRuntimeTypeSystem>();
public IDacStreams DacStreams => GetContract<FDacStreams, IDacStreams>();
public ICodeVersions CodeVersions => GetContract<FCodeVersions, ICodeVersions>();
public IPrecodeStubs PrecodeStubs => GetContract<FPrecodeStubs, IPrecodeStubs>();
public IExecutionManager ExecutionManager => GetContract<FExecutionManager, IExecutionManager>();
public IReJIT ReJIT => GetContract<FReJIT, IReJIT>();

private TProduct GetContract<TFactory, TProduct>() where TProduct : IContract where TFactory : IContractFactory<TProduct>
public IException Exception => GetContract<IException>();
public ILoader Loader => GetContract<ILoader>();
public IEcmaMetadata EcmaMetadata => GetContract<IEcmaMetadata>();
public IObject Object => GetContract<IObject>();
public IThread Thread => GetContract<IThread>();
public IRuntimeTypeSystem RuntimeTypeSystem => GetContract<IRuntimeTypeSystem>();
public IDacStreams DacStreams => GetContract<IDacStreams>();
public ICodeVersions CodeVersions => GetContract<ICodeVersions>();
public IPrecodeStubs PrecodeStubs => GetContract<IPrecodeStubs>();
public IExecutionManager ExecutionManager => GetContract<IExecutionManager>();
public IReJIT ReJIT => GetContract<IReJIT>();

private TProduct GetContract<TProduct>() where TProduct : IContract
{
if (_contracts.TryGetValue(typeof(TProduct), out IContract? contractMaybe))
return (TProduct)contractMaybe;

if (!_target.TryGetContractVersion(TProduct.Name, out int version))
throw new NotImplementedException();

if (!_factories.TryGetValue(typeof(TProduct), out IContractFactory<IContract>? factory))
throw new NotImplementedException();
// Create and register the contract
TProduct contract = TFactory.CreateContract(_target, version);
TProduct contract = (TProduct)factory.CreateContract(_target, version);
if (_contracts.TryAdd(typeof(TProduct), contract))
return contract;

Expand Down

0 comments on commit dd75ae8

Please sign in to comment.