private void SetNode(StructuralTypeNode genericDefinitionStemType, StructuralGenericInstanceTypeNode node) { if (genericDefinitionStemType.GenericInstances == null) { genericDefinitionStemType.GenericInstances = new StructuralGenericInstanceTypeNode[5]; } var foundSlot = false; int currentIndex = 0; for (; currentIndex < genericDefinitionStemType.GenericInstances.Length; currentIndex++) { var arrayNode = genericDefinitionStemType.GenericInstances[currentIndex]; if (arrayNode == null) { foundSlot = true; break; } } if (!foundSlot) { var tempArrays = new StructuralGenericInstanceTypeNode[genericDefinitionStemType.GenericInstances.Length + 5]; Array.Copy(genericDefinitionStemType.GenericInstances, 0, tempArrays, 0, genericDefinitionStemType.GenericInstances.Length); genericDefinitionStemType.GenericInstances = tempArrays; } genericDefinitionStemType.GenericInstances[currentIndex] = node; }
public bool IsConverted(ILConversion conversion, StructuralTypeNode structuralNode) { if (!structuralNode.IsDerived) { return(conversion.MetadataModel.Assemblies.BySourceName.ContainsKey(structuralNode.Module.Assembly.FullName)); } if (!structuralNode.IsGenericInstance) { return(IsConverted(conversion, structuralNode.StemType)); } if (IsConverted(conversion, structuralNode.StemType)) { return(true); } StructuralGenericInstanceTypeNode genericInstance = (StructuralGenericInstanceTypeNode)structuralNode; for (int i = 0; i < genericInstance.GenericArguments.Length; i++) { if (IsConverted(conversion, genericInstance.GenericArguments[i])) { return(true); } } return(false); }
private bool CheckForBranch(StructuralTypeNode blueprintNode, StructuralTypeNode[] typeArguments, out StructuralGenericInstanceTypeNode executionTypeNode) { executionTypeNode = null; var generics = blueprintNode.GenericInstances; if (generics == null) { return(false); } for (int i = 0; i < generics.Length; i++) { var genericInstanceNode = generics[i]; if (genericInstanceNode?.GenericArguments?.Length != typeArguments.Length) { continue; } var ok = true; for (var j = 0; j < genericInstanceNode.GenericArguments.Length; j++) { var argument = genericInstanceNode.GenericArguments[j]; if (ReferenceEquals(argument, typeArguments[j])) { continue; } ok = false; break; } if (!ok) { continue; } executionTypeNode = genericInstanceNode; return(true); } return(false); }
public StructuralTypeNode Ensure(RuntimicSystemModel model, TypeReference typeReference, TypeReference declaringType, MethodReference declaringMethod) { var metadataToken = typeReference.MetadataToken.ToInt32(); var rowId = metadataToken & 0x00FFFFFF; var tableId = (int)(metadataToken & 0xFF000000); bool isDerived = rowId < 1; if (typeReference.IsPointer) { PointerType pointerType = (PointerType)typeReference; var pointerStemType = Ensure(model, pointerType.ElementType); if (pointerStemType.PointerType != null) { return(pointerStemType.PointerType); } pointerStemType.PointerType = new StructuralTypeNode() { IsPointerType = true, StemType = pointerStemType, IsDerived = true, MetadataToken = metadataToken, CecilTypeReference = pointerStemType.CecilTypeReference.MakeByReferenceType() }; return(pointerStemType.PointerType); } if (typeReference.IsByReference) { ByReferenceType byReferenceType = (ByReferenceType)typeReference; var byRefStemType = Ensure(model, byReferenceType.ElementType); if (byRefStemType.ByRefType != null) { return(byRefStemType.ByRefType); } byRefStemType.ByRefType = new StructuralTypeNode() { IsByReferenceType = true, StemType = byRefStemType, IsDerived = true, MetadataToken = metadataToken, CecilTypeReference = byRefStemType.CecilTypeReference.MakeByReferenceType() }; return(byRefStemType.ByRefType); } if (typeReference.IsGenericInstance) { var genericInstanceType = (GenericInstanceType)typeReference; var genericDefinitionType = Ensure(model, genericInstanceType.ElementType); //var structuralModuleNode = GetModuleNode(model, typeReference); StructuralTypeNode[] genericArguments = new StructuralTypeNode[genericInstanceType.GenericArguments.Count]; for (int i = 0; i < genericInstanceType.GenericArguments.Count; i++) { genericArguments[i] = Ensure(model, genericInstanceType.GenericArguments[i], genericInstanceType); } if (CheckForBranch(genericDefinitionType, genericArguments, out StructuralGenericInstanceTypeNode structuralTypeNode)) { return(structuralTypeNode); } structuralTypeNode = new StructuralGenericInstanceTypeNode() { StemType = genericDefinitionType, CecilTypeReference = typeReference, MetadataToken = metadataToken, //Module = structuralModuleNode, IsDerived = true, FullName = typeReference.FullName ?? typeReference.Name, IsGenericParameter = typeReference.IsGenericParameter, Signature = typeReference.Signature, IsGenericInstance = true, GenericArguments = genericArguments }; SetNode(genericDefinitionType, structuralTypeNode); return(structuralTypeNode); } if (typeReference.IsArray) { var arrayType = (ArrayType)typeReference; var arrayElementType = Ensure(model, arrayType.ElementType); if (arrayElementType.Arrays != null && arrayElementType.Arrays.Length > 0) { for (int i = 0; i < arrayElementType.Arrays.Length; i++) { var arrayNode = arrayElementType.Arrays[i]; if (arrayNode?.Rank == arrayType.Rank) { return(arrayNode); } } } var structuralTypeNode = new StructuralTypeNode() { StemType = arrayElementType, CecilTypeReference = typeReference, MetadataToken = metadataToken, Module = arrayElementType.Module, IsDerived = true, FullName = typeReference.FullName ?? typeReference.Name, IsGenericParameter = typeReference.IsGenericParameter, Signature = typeReference.Signature, IsGenericInstance = false, Rank = arrayType.Rank, IsArrayType = true, }; if (arrayElementType.Arrays == null) { arrayElementType.Arrays = new StructuralTypeNode[5]; } var foundSlot = false; int currentIndex = 0; for (; currentIndex < arrayElementType.Arrays.Length; currentIndex++) { var arrayNode = arrayElementType.Arrays[currentIndex]; if (arrayNode == null) { foundSlot = true; break; } } if (!foundSlot) { var tempArrays = new StructuralTypeNode[arrayElementType.Arrays.Length + 5]; Array.Copy(arrayElementType.Arrays, 0, tempArrays, 0, arrayElementType.Arrays.Length); arrayElementType.Arrays = tempArrays; } arrayElementType.Arrays[currentIndex] = structuralTypeNode; return(structuralTypeNode); } StructuralAssemblyNode structuralAssembly; switch (tableId) { case 0x01000000: { structuralAssembly = Infrastructure.Structural.Metadata.Assemblies.Ensuring.Ensure(model, typeReference); if (!structuralAssembly.Types.TryGetValue(typeReference.FullName, out StructuralTypeNode node)) { throw new Exception("Could not resolve reference"); } return(node); } case 0x2a000000: // GenericParam { var genericParameter = (GenericParameter)typeReference; if (declaringMethod != null && genericParameter.Type == GenericParameterType.Method) { genericParameter = declaringMethod.GenericParameters[genericParameter.Position]; var methodReference = genericParameter.DeclaringMethod; genericParameter.Owner = declaringMethod; } if (rowId != 0) { var structuralModuleNode = GetModuleNode(model, typeReference); return(LookupStructuralTypeNode(structuralModuleNode, tableId, rowId)); } else { if (genericParameter.Type == GenericParameterType.Type) { var declaringTypeNode = Ensure(model, genericParameter.DeclaringType, null); return(declaringTypeNode.GenericParameters[genericParameter.Position]); } else { var declaringMethod1 = genericParameter.DeclaringMethod; var methodDefinition = declaringMethod1.Resolve(); genericParameter = methodDefinition.GenericParameters[genericParameter.Position]; return(Ensure(model, genericParameter, null)); } } } case 0x02000000: // TypeDef { TypeDefinition typeDefintion = (TypeDefinition)typeReference; structuralAssembly = Infrastructure.Structural.Metadata.Assemblies.Ensuring.Ensure(model, typeDefintion.Module.Assembly.FullName); var structuralModuleNode = Infrastructure.Structural.Metadata.Modules.Ensure(model, structuralAssembly, typeDefintion.Module.Mvid); return(LookupStructuralTypeNode(structuralModuleNode, tableId, rowId)); } default: throw new Exception("Should not happen."); } }
public StructuralTypeNode Ensure(RuntimicSystemModel model, Type type) { var rowId = type.MetadataToken & 0x00FFFFFF; bool isDerived = rowId < 1; if (isDerived) { if (type.IsPointer) { var pointerStemType = Ensure(model, type.GetElementType()); if (pointerStemType.PointerType != null) { return(pointerStemType.PointerType); } pointerStemType.PointerType = new StructuralTypeNode() { IsPointerType = true, StemType = pointerStemType, IsDerived = true, MetadataToken = type.MetadataToken, CecilTypeReference = pointerStemType.CecilTypeReference.MakeByReferenceType() }; return(pointerStemType.PointerType); } if (type.IsByRef) { var byRefStemType = Ensure(model, type.GetElementType()); if (byRefStemType.ByRefType != null) { return(byRefStemType.ByRefType); } byRefStemType.ByRefType = new StructuralTypeNode() { IsByReferenceType = true, StemType = byRefStemType, IsDerived = true, MetadataToken = type.MetadataToken, CecilTypeReference = byRefStemType.CecilTypeReference.MakeByReferenceType() }; return(byRefStemType.ByRefType); } throw new Exception("Derived type (arrays, generics?) not handled"); } if (type.IsGenericType && !type.IsGenericTypeDefinition) { var genericDefinitionType = type.GetGenericTypeDefinition(); var structuralDefinitionType = Ensure(model, genericDefinitionType); var argumentsTypes = type.GenericTypeArguments; StructuralTypeNode[] genericArguments = new StructuralTypeNode[argumentsTypes.Length]; for (int i = 0; i < argumentsTypes.Length; i++) { genericArguments[i] = Ensure(model, argumentsTypes[i]); } if (CheckForBranch(structuralDefinitionType, genericArguments, out StructuralGenericInstanceTypeNode structuralTypeNode)) { return(structuralTypeNode); } TypeReference[] cecilArguments = GetCecilArguments(genericArguments); structuralTypeNode = new StructuralGenericInstanceTypeNode() { StemType = structuralDefinitionType, CecilTypeReference = structuralDefinitionType.CecilTypeReference.MakeGenericInstanceType(cecilArguments), IsDerived = true, FullName = type.FullName ?? type.Name, IsGenericInstance = true, GenericArguments = genericArguments }; SetNode(structuralDefinitionType, structuralTypeNode); return(structuralTypeNode); } var structuralAssembly = Infrastructure.Structural.Metadata.Assemblies.Ensuring.Ensure(model, type.Assembly); var structuralModuleNode = Infrastructure.Structural.Metadata.Modules.Ensure(model, structuralAssembly, type.Module.ModuleVersionId); // Have a derived type // Have a non-derived type / thus stored type var x = structuralModuleNode.CecilModuleDefinition.LookupToken(type.MetadataToken); var tableId = (int)(type.MetadataToken & 0xFF000000); if (!structuralModuleNode.Tables.TryGetValue(tableId, out StructuralTypeTable table)) { table = new StructuralTypeTable(); structuralModuleNode.Tables.Add(tableId, table); } if (!table.ByRow.TryGetValue((uint)rowId, out StructuralTypeNode structuralTypeNode1)) { throw new Exception("Expected it to already be here."); } return(structuralTypeNode1); }