private MosaField ResolveFieldOperand(IField operand, GenericArgumentResolver resolver) { TypeSig declType; FieldDef fieldDef = operand as FieldDef; if (fieldDef == null) { MemberRef memberRef = (MemberRef)operand; fieldDef = memberRef.ResolveFieldThrow(); declType = memberRef.DeclaringType.ToTypeSig(); } else { declType = fieldDef.DeclaringType.ToTypeSig(); } MDToken fieldToken = fieldDef.MDToken; MosaType type = metadata.Loader.GetType(resolver.Resolve(declType)); foreach (var field in type.Fields) { var desc = field.GetUnderlyingObject <UnitDesc <FieldDef, FieldSig> >(); if (desc.Token.Token == fieldToken) { return(field); } } throw new AssemblyLoadException(); }
private MosaMethod ResolveArrayMethod(IMethod method, GenericArgumentResolver resolver) { MosaType type = metadata.Loader.GetType(resolver.Resolve(method.DeclaringType.ToTypeSig())); if (method.Name == "Get") { return(type.FindMethodByName("Get")); } else if (method.Name == "Set") { return(type.FindMethodByName("Set")); } else if (method.Name == "AddressOf") { return(type.FindMethodByName("AddressOf")); } else if (method.Name == ".ctor") { return(type.FindMethodByName(".ctor")); } else { throw new AssemblyLoadException(); } }
private MosaField ResolveFieldOperand(IField operand, GenericArgumentResolver resolver) { TypeSig declType; if (!(operand is FieldDef fieldDef)) { var memberRef = (MemberRef)operand; fieldDef = memberRef.ResolveFieldThrow(); declType = memberRef.DeclaringType.ToTypeSig(); }
private void ResolveProperty(MosaProperty property) { GenericArgumentResolver resolver = new GenericArgumentResolver(); if (property.DeclaringType.GenericArguments.Count > 0) { resolver.PushTypeGenericArguments(property.DeclaringType.GenericArguments.GetGenericArguments()); } using (var mosaProperty = metadata.Controller.MutateProperty(property)) { mosaProperty.PropertyType = metadata.Loader.GetType(resolver.Resolve(property.GetPropertySig().RetType)); ResolveCustomAttributes(mosaProperty, property.GetUnderlyingObject <UnitDesc <PropertyDef, PropertySig> >().Definition); } }
private MosaMethod ResolveMethodOperand(IMethod operand, GenericArgumentResolver resolver) { if (operand is MethodSpec) { return(metadata.Loader.LoadGenericMethodInstance((MethodSpec)operand, resolver)); } else if (operand.DeclaringType.TryGetArraySig() != null || operand.DeclaringType.TryGetSZArraySig() != null) { return(ResolveArrayMethod(operand, resolver)); } TypeSig declType; MethodDef methodDef = operand as MethodDef; if (methodDef == null) { MemberRef memberRef = (MemberRef)operand; methodDef = memberRef.ResolveMethodThrow(); declType = memberRef.DeclaringType.ToTypeSig(); } else { declType = methodDef.DeclaringType.ToTypeSig(); } if (resolver != null) { declType = resolver.Resolve(declType); } MDToken methodToken = methodDef.MDToken; MosaType type = metadata.Loader.GetType(declType); foreach (var method in type.Methods) { var desc = method.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (desc.Token.Token == methodToken) { return(method); } } throw new AssemblyLoadException(); }
private void ResolveField(MosaField field) { var resolver = new GenericArgumentResolver(); if (field.DeclaringType.GenericArguments.Count > 0) { resolver.PushTypeGenericArguments(field.DeclaringType.GenericArguments.GetGenericArguments()); } using (var mosaField = metadata.Controller.MutateField(field)) { mosaField.FieldType = metadata.Loader.GetType(resolver.Resolve(field.GetFieldSig().Type)); mosaField.HasOpenGenericParams = field.DeclaringType.HasOpenGenericParams || field.FieldType.GetTypeSig().HasOpenGenericParameter(); ResolveCustomAttributes(mosaField, field.GetUnderlyingObject <UnitDesc <FieldDef, FieldSig> >().Definition); } }
private void ResolveType(MosaType type) { GenericArgumentResolver resolver = new GenericArgumentResolver(); MosaType srcType = type; if (type.GenericArguments.Count > 0) { resolver.PushTypeGenericArguments(type.GenericArguments.GetGenericArguments()); srcType = type.ElementType; Debug.Assert(srcType != null); } using (var mosaType = metadata.Controller.MutateType(type)) { if (srcType.BaseType != null) { mosaType.BaseType = metadata.Loader.GetType(resolver.Resolve(srcType.BaseType.GetTypeSig())); } if (srcType.DeclaringType != null) { mosaType.DeclaringType = metadata.Loader.GetType(resolver.Resolve(srcType.DeclaringType.GetTypeSig())); mosaType.Namespace = srcType.DeclaringType.Namespace; } var ifaces = new List <MosaType>(srcType.Interfaces); mosaType.Interfaces.Clear(); for (int i = 0; i < ifaces.Count; i++) { mosaType.Interfaces.Add(metadata.Loader.GetType(resolver.Resolve(ifaces[i].GetTypeSig()))); } mosaType.HasOpenGenericParams = type.GetTypeSig().HasOpenGenericParameter(); ResolveCustomAttributes(mosaType, srcType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Definition); } // Add type again to make it easier to find metadata.Controller.AddType(type); }
private MosaType ResolveTypeOperand(ITypeDefOrRef operand, GenericArgumentResolver resolver) { return(metadata.Loader.GetType(resolver.Resolve(operand.ToTypeSig()))); }
private MosaInstruction ResolveInstruction(MethodDef methodDef, CilBody body, int index, GenericArgumentResolver resolver) { Instruction instruction = body.Instructions[index]; int? prev = index == 0 ? null : (int?)body.Instructions[index - 1].Offset; int? next = index == body.Instructions.Count - 1 ? null : (int?)body.Instructions[index + 1].Offset; object operand = instruction.Operand; // Special case: newarr instructions need to have their operand changed now so that the type is a SZArray if (instruction.OpCode == OpCodes.Newarr) { var typeSig = resolver.Resolve(((ITypeDefOrRef)instruction.Operand).ToTypeSig()); var szArraySig = new SZArraySig(typeSig); operand = metadata.Loader.GetType(szArraySig); } else if (instruction.Operand is ITypeDefOrRef) { operand = ResolveTypeOperand((ITypeDefOrRef)instruction.Operand, resolver); } else if (instruction.Operand is MemberRef) { MemberRef memberRef = (MemberRef)instruction.Operand; if (memberRef.IsFieldRef) { operand = ResolveFieldOperand(memberRef, resolver); } else { operand = ResolveMethodOperand(memberRef, resolver); } } else if (instruction.Operand is IField) { operand = ResolveFieldOperand((IField)instruction.Operand, resolver); } else if (instruction.Operand is IMethod) { operand = ResolveMethodOperand((IMethod)instruction.Operand, resolver); } else if (instruction.Operand is Local) { operand = ((Local)instruction.Operand).Index; } else if (instruction.Operand is Parameter) { operand = ((Parameter)instruction.Operand).Index; } else if (instruction.Operand is Instruction) { operand = (int)((Instruction)instruction.Operand).Offset; } else if (instruction.Operand is Instruction[]) { Instruction[] targets = (Instruction[])instruction.Operand; int[] offsets = new int[targets.Length]; for (int i = 0; i < offsets.Length; i++) { offsets[i] = (int)targets[i].Offset; } operand = offsets; } else if (instruction.Operand is string) { operand = metadata.Cache.GetStringId((string)instruction.Operand); } ushort code = (ushort)instruction.OpCode.Code; if (code > 0xff) // To match compiler's opcode values { code = (ushort)(0x100 + (code & 0xff)); } return(new MosaInstruction((int)instruction.Offset, code, operand, prev, next)); }
private void ResolveBody(MethodDef methodDef, MosaMethod.Mutator method, CilBody body, GenericArgumentResolver resolver) { method.LocalVariables.Clear(); int index = 0; foreach (var variable in body.Variables) { method.LocalVariables.Add(new MosaLocal( variable.Name ?? "V_" + index, metadata.Loader.GetType(resolver.Resolve(variable.Type)), variable.Type.IsPinned)); index++; } method.ExceptionBlocks.Clear(); foreach (var eh in body.ExceptionHandlers) { method.ExceptionBlocks.Add(new MosaExceptionHandler( (ExceptionHandlerType)eh.HandlerType, ResolveOffset(body, eh.TryStart), ResolveOffset(body, eh.TryEnd), ResolveOffset(body, eh.HandlerStart), ResolveOffset(body, eh.HandlerEnd), eh.CatchType == null ? null : metadata.Loader.GetType(resolver.Resolve(eh.CatchType.ToTypeSig())), eh.FilterStart == null ? null : (int?)eh.FilterStart.Offset )); } method.MaxStack = methodDef.Body.MaxStack; method.Code.Clear(); for (int i = 0; i < body.Instructions.Count; i++) { method.Code.Add(ResolveInstruction(methodDef, body, i, resolver)); } }
private void ResolveMethod(MosaMethod method) { GenericArgumentResolver resolver = new GenericArgumentResolver(); bool hasOpening = method.DeclaringType.HasOpenGenericParams; if (method.DeclaringType.GenericArguments.Count > 0) { foreach (var i in method.DeclaringType.GenericArguments.GetGenericArguments()) { hasOpening |= i.HasOpenGenericParameter(); } resolver.PushTypeGenericArguments(method.DeclaringType.GenericArguments.GetGenericArguments()); } if (method.GenericArguments.Count > 0) { foreach (var i in method.GenericArguments.GetGenericArguments()) { hasOpening |= i.HasOpenGenericParameter(); } resolver.PushMethodGenericArguments(method.GenericArguments.GetGenericArguments()); } using (var mosaMethod = metadata.Controller.MutateMethod(method)) { var desc = method.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); MosaType returnType = metadata.Loader.GetType(resolver.Resolve(desc.Signature.RetType)); hasOpening |= returnType.HasOpenGenericParams; List <MosaParameter> pars = new List <MosaParameter>(); Debug.Assert(desc.Signature.GetParamCount() + (desc.Signature.HasThis ? 1 : 0) == desc.Definition.Parameters.Count); foreach (var param in desc.Definition.Parameters) { if (!param.IsNormalMethodParameter) { continue; } var paramType = metadata.Loader.GetType(resolver.Resolve(desc.Signature.Params[param.MethodSigIndex])); var parameter = metadata.Controller.CreateParameter(); using (var mosaParameter = metadata.Controller.MutateParameter(parameter)) { mosaParameter.Name = param.Name; mosaParameter.ParameterAttributes = (MosaParameterAttributes)param.ParamDef.Attributes; mosaParameter.ParameterType = paramType; mosaParameter.DeclaringMethod = method; ResolveCustomAttributes(mosaParameter, param.ParamDef); } pars.Add(parameter); hasOpening |= paramType.HasOpenGenericParams; } mosaMethod.Signature = new MosaMethodSignature(returnType, pars); foreach (var methodImpl in desc.Definition.Overrides) { Debug.Assert(methodImpl.MethodBody == desc.Definition); mosaMethod.Overrides.Add(ResolveMethodOperand(methodImpl.MethodDeclaration, null)); } if (desc.Definition.HasBody) { ResolveBody(desc.Definition, mosaMethod, desc.Definition.Body, resolver); } mosaMethod.HasOpenGenericParams = hasOpening; ResolveCustomAttributes(mosaMethod, desc.Definition); } }
public MosaMethod LoadGenericMethodInstance(IMethodDefOrRef method, IList <TypeSig> genericArguments, GenericArgumentResolver resolver) { MosaType declType = GetType(resolver.Resolve(method.DeclaringType.ToTypeSig())); MDToken token; if (method is MethodDef) { token = ((MethodDef)method).MDToken; } else { token = ((MemberRef)method).ResolveMethodThrow().MDToken; } MosaMethod mosaMethod = null; UnitDesc <MethodDef, MethodSig> desc = null; foreach (var m in declType.Methods) { desc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (desc.Token.Token == token) { mosaMethod = m; break; } } if (mosaMethod == null) { throw new AssemblyLoadException(); } List <TypeSig> genericArgs = new List <TypeSig>(); foreach (var genericArg in genericArguments) { genericArgs.Add(resolver.Resolve(genericArg)); } resolver.PushMethodGenericArguments(genericArgs); // Check for existing generic method instance var newSig = resolver.Resolve(method.MethodSig); var comparer = new SigComparer(); foreach (var m in declType.Methods) { var mDesc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (mDesc.Definition == desc.Definition && comparer.Equals(mDesc.Signature, newSig)) { return(m); } } mosaMethod = metadata.Controller.CreateMethod(mosaMethod); using (var _mosaMethod = metadata.Controller.MutateMethod(mosaMethod)) { bool hasOpening = mosaMethod.DeclaringType.HasOpenGenericParams; foreach (var genericArg in genericArguments) { var newGenericArg = resolver.Resolve(genericArg); hasOpening |= newGenericArg.HasOpenGenericParameter(); _mosaMethod.GenericArguments.Add(GetType(newGenericArg)); } _mosaMethod.UnderlyingObject = desc.Clone(newSig); _mosaMethod.DeclaringType = declType; _mosaMethod.HasOpenGenericParams = hasOpening; } resolver.PopMethodGenericArguments(); using (var decl = metadata.Controller.MutateType(declType)) decl.Methods.Add(mosaMethod); metadata.Resolver.EnqueueForResolve(mosaMethod); return(mosaMethod); }
public MosaMethod LoadGenericMethodInstance(MethodSpec methodSpec, GenericArgumentResolver resolver) { return(LoadGenericMethodInstance(methodSpec.Method, methodSpec.GenericInstMethodSig.GenericArguments, resolver)); }
private MosaType LoadGenericTypeInstanceSig(GenericInstSig typeSig) { //Debug.Assert(false, typeSig.FullName); MosaType origin = GetType(typeSig.GenericType); MosaType result = metadata.Controller.CreateType(origin); var desc = result.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >(); using (var resultType = metadata.Controller.MutateType(result)) { resultType.UnderlyingObject = desc.Clone(typeSig); resultType.ElementType = origin; foreach (var genericArg in typeSig.GenericArguments) { resultType.GenericArguments.Add(GetType(genericArg)); } metadata.Resolver.EnqueueForResolve(result); GenericArgumentResolver resolver = new GenericArgumentResolver(); resolver.PushTypeGenericArguments(typeSig.GenericArguments); for (int i = 0; i < result.Methods.Count; i++) { MosaMethod method = metadata.Controller.CreateMethod(result.Methods[i]); using (var mosaMethod = metadata.Controller.MutateMethod(method)) { mosaMethod.DeclaringType = result; mosaMethod.UnderlyingObject = method.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); } resultType.Methods[i] = method; metadata.Resolver.EnqueueForResolve(method); } for (int i = 0; i < result.Fields.Count; i++) { MosaField field = metadata.Controller.CreateField(result.Fields[i]); using (var mosaField = metadata.Controller.MutateField(field)) { mosaField.DeclaringType = result; mosaField.UnderlyingObject = field.GetUnderlyingObject <UnitDesc <FieldDef, FieldSig> >(); } resultType.Fields[i] = field; metadata.Resolver.EnqueueForResolve(field); } for (int i = 0; i < result.Properties.Count; i++) { MosaProperty property = metadata.Controller.CreateProperty(result.Properties[i]); PropertySig newSig = property.GetPropertySig().Clone(); newSig.RetType = resolver.Resolve(newSig.RetType); using (var mosaProperty = metadata.Controller.MutateProperty(property)) { mosaProperty.DeclaringType = result; mosaProperty.UnderlyingObject = property.GetUnderlyingObject <UnitDesc <PropertyDef, PropertySig> >(); } resultType.Properties[i] = property; metadata.Resolver.EnqueueForResolve(property); } resultType.HasOpenGenericParams = typeSig.HasOpenGenericParameter(); } metadata.Controller.AddType(result); return(result); }
public MosaMethod LoadGenericMethodInstance(IMethodDefOrRef method, IList <TypeSig> genericArguments, GenericArgumentResolver resolver) { var declType = GetType(resolver.Resolve(method.DeclaringType.ToTypeSig())); MDToken token; if (method is MethodDef) { token = ((MethodDef)method).MDToken; } else { token = ((MemberRef)method).ResolveMethodThrow().MDToken; } MosaMethod mosaMethod = null; UnitDesc <MethodDef, MethodSig> desc = null; foreach (var m in declType.Methods) { desc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (desc.Token.Token == token) { mosaMethod = m; break; } } if (mosaMethod == null) { throw new AssemblyLoadException(); } var genericArgs = new List <TypeSig>(); foreach (var genericArg in genericArguments) { genericArgs.Add(resolver.Resolve(genericArg)); } resolver.PushMethodGenericArguments(genericArgs); // Check for existing generic method instance var newSig = resolver.Resolve(method.MethodSig); // Need to make sure we pop otherwise it will cause bugs resolver.PopMethodGenericArguments(); var comparer = new SigComparer(); foreach (var m in declType.Methods) { var mDesc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (mDesc.Definition != desc.Definition || !comparer.Equals(mDesc.Signature, newSig)) { continue; } if (newSig.ContainsGenericParameter || newSig.GenParamCount > 0) { continue; } if (m.GenericArguments.Count != genericArgs.Count) { continue; } if (m.GenericArguments.Count > 0) { var failedGenericArgumentMatch = false; for (var i = 0; i < m.GenericArguments.Count; i++) { if (comparer.Equals(genericArguments[i], m.GenericArguments[i].GetTypeSig())) { continue; } failedGenericArgumentMatch = true; break; } if (failedGenericArgumentMatch) { continue; } } return(m); } mosaMethod = metadata.Controller.CreateMethod(mosaMethod); using (var _mosaMethod = metadata.Controller.MutateMethod(mosaMethod)) { bool hasOpening = mosaMethod.DeclaringType.HasOpenGenericParams; foreach (var genericArg in genericArgs) { hasOpening |= genericArg.HasOpenGenericParameter(); var t = GetType(genericArg); if (!_mosaMethod.GenericArguments.Contains(t)) { _mosaMethod.GenericArguments.Add(t); } } _mosaMethod.UnderlyingObject = desc.Clone(newSig); _mosaMethod.DeclaringType = declType; _mosaMethod.HasOpenGenericParams = hasOpening; } using (var decl = metadata.Controller.MutateType(declType)) decl.Methods.Add(mosaMethod); metadata.Resolver.EnqueueForResolve(mosaMethod); return(mosaMethod); }