Esempio n. 1
0
        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();
        }
Esempio n. 2
0
        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();
            }
        }
Esempio n. 3
0
        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();
            }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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();
        }
Esempio n. 6
0
        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);
            }
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
 private MosaType ResolveTypeOperand(ITypeDefOrRef operand, GenericArgumentResolver resolver)
 {
     return(metadata.Loader.GetType(resolver.Resolve(operand.ToTypeSig())));
 }
Esempio n. 9
0
        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));
        }
Esempio n. 10
0
        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));
            }
        }
Esempio n. 11
0
        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);
            }
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
 public MosaMethod LoadGenericMethodInstance(MethodSpec methodSpec, GenericArgumentResolver resolver)
 {
     return(LoadGenericMethodInstance(methodSpec.Method, methodSpec.GenericInstMethodSig.GenericArguments, resolver));
 }
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
        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);
        }