예제 #1
0
        public void EmitAssemblyEntryPoint (AssemblyDefinition assembly, MethodDefinition entryMethod, MethodSignature signature) {
            Formatter.WriteRaw("JSIL.SetEntryPoint");
            Formatter.LPar();

            Formatter.AssemblyReference(assembly);

            Formatter.Comma();

            var context = new TypeReferenceContext();
            Formatter.TypeReference(entryMethod.DeclaringType, context);

            Formatter.Comma();

            Formatter.Value(entryMethod.Name);

            Formatter.Comma();

            Formatter.MethodSignature(
                entryMethod, signature, context
            );

            Formatter.RPar();
            Formatter.Semicolon(true);

            Formatter.NewLine();
        }
예제 #2
0
        public void Equals_TwoIdenticalSignatures()
        {
            var ms1 = new MethodSignature(typeof(MethodSignature).GetConstructors()[1].GetParameters());
            var ms2 = new MethodSignature(typeof(MethodSignature).GetConstructors()[1].GetParameters());

            Assert.AreEqual(ms1, ms2);
        }
        public void ctor_LegalParameters_InitializeFieldsWithValues()
        {
            var target = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME);

            Assert.AreEqual(SOME_TYPE_NAME, target.TypeName);
            Assert.AreEqual(SOME_METHOD_NAME, target.MethodName);
        }
예제 #4
0
 private static CCDataEntry LocateCCData(MethodSignature method, IList<CCDataEntry> ccData)
 {
     var answer = (from data in ccData
                   where data.Method.Equals(method)
                   select data);
     return answer.SingleOrDefault();
 }
예제 #5
0
        public void Equals_TwoDifferentSignaturesSameLength()
        {
            var ms1 = new MethodSignature(typeof(Type[]), typeof(object));
            var ms2 = new MethodSignature(typeof(Type), typeof(object));

            Assert.AreNotEqual(ms1, ms2);
        }
 public void Equals_DifferentMethod_ReturnFalse()
 {
     var otherMethod = new MethodSignature(VALID_TYPE_NAME, VALID_METHOD_NAME+"a");
     var target1 = new CombinedDataEntry(_Method, 1, 5);
     var target2 = new CombinedDataEntry(otherMethod, 1, 5);
     Assert.IsFalse(target1.Equals(target2));
 }
예제 #7
0
파일: Native.cs 프로젝트: afrog33k/mobjc
        internal Native(IntPtr target, Selector selector, IntPtr imp, MethodSignature sig)
        {
            Contract.Requires(selector != null, "selector is null");
            Contract.Requires(target == IntPtr.Zero || imp != IntPtr.Zero, "imp is null");

            m_target = target;

            if (m_target != IntPtr.Zero)
            {
                if (ms_stackFrames == null)
                    ms_stackFrames = new Dictionary<MethodSignature, StackFrame>();	// note that we have to do this here so each thread gets its own dictionary

                m_selector = selector;
                m_imp = imp;
                m_sig = sig ?? new MethodSignature(target, (IntPtr) selector);

                if (!ms_stackFrames.TryGetValue(m_sig, out m_stackFrame))
                {
                    m_stackFrame = new StackFrame(m_sig);
                    ms_stackFrames.Add(m_sig, m_stackFrame);
                }

                Ffi.FillBuffer(m_stackFrame.ArgBuffers[0], target, "@");
                Ffi.FillBuffer(m_stackFrame.ArgBuffers[1], m_selector, ":");
            }
        }
예제 #8
0
파일: Managed.cs 프로젝트: afrog33k/mobjc
        internal Managed(MethodInfo info, string encoding)
        {
            Contract.Requires(info != null, "info is null");
            Contract.Requires(!string.IsNullOrEmpty(encoding), "encoding is null or empty");

            m_info = info;
            m_signature = new MethodSignature(encoding);
        }
예제 #9
0
 public static bool Remove(string conditionFormat, IList<Type> parameterTypes)
 {
     lock (_methods)
     {
         var signature = new MethodSignature(conditionFormat, parameterTypes);
         return _methods.Remove(signature);
     }
 }
예제 #10
0
        public void ToString_Works()
        {
            var ms1 = new MethodSignature(typeof(Type[]), typeof(object));
            Assert.AreEqual("(System.Type[], System.Object)", ms1.ToString());

            var ms2 = new MethodSignature(new Type[0]);
            Assert.AreEqual("()", ms2.ToString());
        }
        public void Equals_NullObject_ReturnsFalse()
        {
            var target = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME + "a");

            var actual = target.Equals(null);

            Assert.IsFalse(actual);
        }
예제 #12
0
        public void Equals_TwoDifferentSignatures()
        {
            var ms1 = new MethodSignature(typeof(Type[]), typeof(object), typeof(string));
            var ms2 = new MethodSignature(typeof(Type[]), typeof(object));

            Assert.AreNotEqual(ms1, ms2);
            Assert.IsFalse(ms1.Equals(null));
        }
        public void Equals_IdenticalValues_ReturnsTrue()
        {
            var target1 = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME);
            var target2 = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME);

            var actual = target1.Equals(target2);

            Assert.IsTrue(actual);
        }
        public void Equals_DifferentTypeName_ReturnsFalse()
        {
            var target1 = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME + "a");
            var target2 = new MethodSignature(SOME_TYPE_NAME, SOME_METHOD_NAME);

            var actual = target1.Equals(target2);

            Assert.IsFalse(actual);
        }
예제 #15
0
		/// <summary>
		/// Generates a mock object with an interface defined by an array of method signatures.
		/// </summary>
		/// <param name="typeName">Name of the type to ganerate.</param>
		/// <param name="methodSignatures">Array of method signatures of methods to be implemented.</param>
		/// <param name="handler">Mocked calls handler.</param>
		/// <returns>Instance of generated class.</returns>
		public object Generate( string typeName, MethodSignature[] methodSignatures, IMockedCallHandler handler )
		{
			MockClassBuilder classBuilder = new MockClassBuilder(
				_moduleBuilder,
				typeName,
				typeof ( object ),
				Type.EmptyTypes
				);
			foreach ( MethodSignature ms in methodSignatures )
			{
				classBuilder.ImplementMockedMethod( ms.MethodName, ms.ReturnType, ms.ParamTypes );
			}
			return compileAndGenerateMock( classBuilder, handler );
		}
예제 #16
0
 public static object RunMethod(string conditionFormat, object[] parameters)
 {
     lock (_methods)
     {
         Type[] parameterTypes = parameters.Select(x => x != null ? x.GetType() : typeof(object)).ToArray();
         var signature = new MethodSignature(conditionFormat, parameterTypes);
         Func<object[], object> method;
         if (_methods.TryGetValue(signature, out method) == false)
         {
             _methods[signature] = method = GenerateMethod(conditionFormat, parameterTypes);
         }
         return method(parameters);
     }
 }
        /// <summary>
        /// Construct a comparer between NativeFormat metadata methods and native layouts
        /// </summary>
        /// <param name="metadataReader">Metadata reader for the method declaring type</param>
        /// <param name="methodHandle">Handle of method to compare</param>
        public MethodSignatureComparer(
            MetadataReader metadataReader,
            MethodHandle methodHandle)
        {
            _metadataReader = metadataReader;
            _methodHandle = methodHandle;

            _method = methodHandle.GetMethod(metadataReader);

            _methodSignature = _method.Signature.GetMethodSignature(_metadataReader);
            _isGeneric = (_methodSignature.GenericParameterCount != 0);

            // Precalculate initial method attributes used in signature queries
            _isStatic = (_method.Flags & MethodAttributes.Static) != 0;
        }
예제 #18
0
        public void VerifyConstructor()
        {
            var header = new SignatureHeader(2);
            var returnType = 5;
            var requiredParameterCount = 10;
            var genericParameterCount = 3;
            var parameterTypes = ImmutableArray.Create(2, 4, 6, 8);

            var methodSignature = new MethodSignature<int>(header, returnType, requiredParameterCount, genericParameterCount, parameterTypes);

            // Verify each field was correctly set
            Assert.Equal(methodSignature.Header, header);
            Assert.Equal(methodSignature.ReturnType, returnType);
            Assert.Equal(methodSignature.RequiredParameterCount, requiredParameterCount);
            Assert.Equal(methodSignature.GenericParameterCount, genericParameterCount);
            Assert.Equal(methodSignature.ParameterTypes, parameterTypes);
        }
예제 #19
0
        // TODO: ARe we handling generic methods properly?
        // TODO: Are we handling explicit-implementation interface methods properly?
        private static void AddInterfaceMethods(
            TypeBuilder proxyTB,
            FieldBuilder mapField,
            Type superclass,
            HashSet<Type> allInterfaces,
            HashSet<MethodBuilder> specialMethods)
        {
            HashSet<MethodSignature> considered = new HashSet<MethodSignature>();
            List<MethodInfo> implementedMethods = new List<MethodInfo>();
            List<MethodInfo> unimplementedMethods = new List<MethodInfo>();

            MethodInfo[] minfos = superclass.GetMethods(BindingFlags.Public|BindingFlags.NonPublic| BindingFlags.Instance| BindingFlags.InvokeMethod);

            foreach (MethodInfo  m in minfos )
            {
                MethodSignature sig = new MethodSignature(m);
                if (!considered.Contains(sig)
                    && !m.IsPrivate
                    && !m.IsStatic
                    && !m.IsFinal)
                {
                    if (m.IsAbstract)
                        unimplementedMethods.Add(m);
                    else
                        implementedMethods.Add(m);
                }
                considered.Add(sig);
            }

            foreach ( Type ifType in allInterfaces )
                foreach (MethodInfo m in ifType.GetMethods() )
                {
                    MethodSignature sig = new MethodSignature(m);
                    if (!considered.Contains(sig))
                        unimplementedMethods.Add(m);
                    considered.Add(sig);
                }

            foreach (MethodInfo m in implementedMethods)
                GenerateProxyMethod(proxyTB, mapField, m, specialMethods);

            foreach (MethodInfo m in unimplementedMethods)
                GenerateProxyMethod(proxyTB, mapField, m, specialMethods);
        }
예제 #20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MethodRunner"/> class.
        /// </summary>
        /// <param name="typeRunner">The assembly runner.</param>
        /// <param name="method">The method.</param>
        /// <param name="target">The target.</param>
        /// <param name="methodSignature">The method signature.</param>
        public MethodRunner(TypeRunner typeRunner, MethodInfo method, object target, MethodSignature methodSignature)
        {
            // Check for null arguments.
            if (typeRunner == null)
            {
                throw new ArgumentNullException("typeRunner");
            }

            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            // Save the parameters into fields.
            this.typeRunner = typeRunner;
            this.method = method;
            this.target = target;
            this.methodSignature = methodSignature;
        }
예제 #21
0
        private MethodSignature InitializeSignature()
        {
            var metadataReader = MetadataReader;

            NativeFormatSignatureParser parser = new NativeFormatSignatureParser(MetadataUnit, MetadataReader.GetMethod(_handle).Signature, metadataReader);
            var signature = parser.ParseMethodSignature();
            return (_signature = signature);
        }
예제 #22
0
 public static void ThrowMissingMethodException(TypeDesc owningType, string methodName, MethodSignature signature)
 {
     throw new TypeSystemException.MissingMethodException(ExceptionStringID.MissingMethod, Format.Method(owningType, methodName, signature));
 }
            public override void Implement(TransformationContext context)
            {
                
                ModuleDeclaration module = this.AspectWeaver.Module;

                TypeDefDeclaration typeDef = (TypeDefDeclaration)context.TargetElement;

                // Declare the method.
                MethodDefDeclaration methodDef = new MethodDefDeclaration
                {
                    Name = "AutoGeneratedValidate",
                    Attributes = (MethodAttributes.Family | MethodAttributes.ReuseSlot | MethodAttributes.Virtual),
                    CallingConvention = CallingConvention.HasThis
                };
                typeDef.Methods.Add(methodDef);
                methodDef.CustomAttributes.Add(this.AspectWeaver.AspectInfrastructureTask.WeavingHelper.GetDebuggerNonUserCodeAttribute());

                // Define parameter.
                methodDef.ReturnParameter = new ParameterDeclaration
                {
                    ParameterType = module.Cache.GetIntrinsic(IntrinsicType.Void),
                    Attributes = ParameterAttributes.Retval
                };

                // Define the body
                MethodBodyDeclaration methodBody = new MethodBodyDeclaration();
                methodDef.MethodBody = methodBody;
                InstructionBlock instructionBlock = methodBody.CreateInstructionBlock();
                methodBody.RootInstructionBlock = instructionBlock;
                InstructionSequence sequence = methodBody.CreateInstructionSequence();
                instructionBlock.AddInstructionSequence(sequence, NodePosition.After, null);

                using (InstructionWriter writer = new InstructionWriter())
                {
                    writer.AttachInstructionSequence( sequence );

                    // Find the base method.
                    IMethod baseValidateMethod = null;
                    IType baseTypeCursor = typeDef.BaseType;
                    MethodSignature methodSignature =
                        new MethodSignature( module, CallingConvention.HasThis, module.Cache.GetIntrinsic( IntrinsicType.Void ),
                                             new ITypeSignature[0], 0 );

                    while ( baseValidateMethod == null )
                    {
                        TypeDefDeclaration baseTypeCursorTypeDef = baseTypeCursor.GetTypeDefinition();

                        baseValidateMethod =
                            baseTypeCursorTypeDef.Methods.GetMethod( "AutoGeneratedValidate",
                                                                     methodSignature.Translate( baseTypeCursorTypeDef.Module ),
                                                                     BindingOptions.OnlyExisting |
                                                                     BindingOptions.DontThrowException );

                        baseTypeCursor = baseTypeCursorTypeDef.BaseType;
                    }

                    // TODO: support generic base types.

                    // Call the base method.
                    writer.EmitInstruction( OpCodeNumber.Ldarg_0 );
                    writer.EmitInstructionMethod( OpCodeNumber.Call, (IMethod) baseValidateMethod.Translate( typeDef.Module ) );

                    // Make an array with the boxed field values.
                    TypeValidationAspect aspect = (TypeValidationAspect) this.AspectWeaverInstance.Aspect;
                    LocalVariableSymbol fieldValuesArrayLocal = instructionBlock.DefineLocalVariable(
                        module.Cache.GetType( typeof(object[]) ), "fieldValues" );
                    writer.EmitInstructionInt32( OpCodeNumber.Ldc_I4, aspect.Validators.Count );
                    writer.EmitInstructionType( OpCodeNumber.Newarr, module.Cache.GetIntrinsic( IntrinsicType.Object ) );
                    writer.EmitInstructionLocalVariable( OpCodeNumber.Stloc, fieldValuesArrayLocal );

                    int i = 0;
                    foreach ( FieldValidationAttribute validator in aspect.Validators )
                    {
                        FieldDefDeclaration fieldDef = typeDef.Fields.GetByName( validator.TargetLocation.Name );
                        IField fieldSpec = GenericHelper.GetFieldCanonicalGenericInstance( fieldDef );

                        writer.EmitInstructionLocalVariable( OpCodeNumber.Ldloc, fieldValuesArrayLocal );
                        writer.EmitInstructionInt32( OpCodeNumber.Ldc_I4, i );
                        writer.EmitInstruction( OpCodeNumber.Ldarg_0 );
                        writer.EmitInstructionField( OpCodeNumber.Ldfld, fieldSpec );
                        writer.EmitConvertToObject( fieldSpec.FieldType );
                        writer.EmitInstruction( OpCodeNumber.Stelem_Ref );

                        i++;
                    }

                    // Get the validator method.
                    IMethod validateMethod = module.Cache.GetItem(
                        () => module.FindMethod(
                                  typeof(TypeValidationAspect).GetMethod( "Validate" ),
                                  BindingOptions.Default ) );

                    // Call the validator.
                    this.AspectWeaverInstance.AspectRuntimeInstanceField.EmitLoadField( writer, null );
                    writer.EmitInstructionLocalVariable( OpCodeNumber.Ldloc, fieldValuesArrayLocal );
                    writer.EmitInstructionMethod( OpCodeNumber.Callvirt, validateMethod );

                    writer.EmitInstruction( OpCodeNumber.Ret );
                    writer.DetachInstructionSequence();
                }
            }
예제 #24
0
 public ILToken NewToken(MethodSignature value)
 {
     return(NewToken(value, 0x11000000));
 }
예제 #25
0
        public static TypeDesc[] GetThunkInstantiationForMethod(MethodDesc method)
        {
            MethodSignature sig = method.Signature;

            ParameterMetadata[] paramMetadata = null;
            TypeDesc[]          instantiation = new TypeDesc[sig.ReturnType.IsVoid ? sig.Length : sig.Length + 1];

            for (int i = 0; i < sig.Length; i++)
            {
                TypeDesc parameterType = sig[i];
                if (parameterType.IsByRef)
                {
                    // strip ByRefType off the parameter (the method already has ByRef in the signature)
                    parameterType = ((ByRefType)parameterType).ParameterType;

                    // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that
                    // by being specialized for the specific pointer depth.
                    while (parameterType.IsPointer)
                    {
                        parameterType = ((PointerType)parameterType).ParameterType;
                    }
                }
                else if (parameterType.IsPointer)
                {
                    // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that
                    // by being specialized for the specific pointer depth.
                    while (parameterType.IsPointer)
                    {
                        parameterType = ((PointerType)parameterType).ParameterType;
                    }
                }
                else if (parameterType.IsEnum)
                {
                    // If the invoke method takes an enum as an input parameter and there is no default value for
                    // that paramter, we don't need to specialize on the exact enum type (we only need to specialize
                    // on the underlying integral type of the enum.)
                    if (paramMetadata == null)
                    {
                        paramMetadata = method.GetParameterMetadata();
                    }

                    bool hasDefaultValue = false;
                    foreach (var p in paramMetadata)
                    {
                        // Parameter metadata indexes are 1-based (0 is reserved for return "parameter")
                        if (p.Index == (i + 1) && p.HasDefault)
                        {
                            hasDefaultValue = true;
                            break;
                        }
                    }

                    if (!hasDefaultValue)
                    {
                        parameterType = parameterType.UnderlyingType;
                    }
                }

                instantiation[i] = parameterType;
            }

            if (!sig.ReturnType.IsVoid)
            {
                TypeDesc returnType = sig.ReturnType;

                // strip ByRefType off the return type (the method already has ByRef in the signature)
                if (returnType.IsByRef)
                {
                    returnType = ((ByRefType)returnType).ParameterType;
                }

                // If the invoke method return an object reference, we don't need to specialize on the
                // exact type of the object reference, as the behavior is not different.
                if ((returnType.IsDefType && !returnType.IsValueType) || returnType.IsArray)
                {
                    returnType = method.Context.GetWellKnownType(WellKnownType.Object);
                }

                // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that
                // by being specialized for the specific pointer depth.
                while (returnType.IsPointer)
                {
                    returnType = ((PointerType)returnType).ParameterType;
                }

                instantiation[sig.Length] = returnType;
            }

            return(instantiation);
        }
예제 #26
0
        internal DelegateThunkCollection(DelegateInfo owningDelegate)
        {
            _openStaticThunk           = new DelegateInvokeOpenStaticThunk(owningDelegate);
            _multicastThunk            = new DelegateInvokeMulticastThunk(owningDelegate);
            _closedStaticThunk         = new DelegateInvokeClosedStaticThunk(owningDelegate);
            _closedInstanceOverGeneric = new DelegateInvokeInstanceClosedOverGenericMethodThunk(owningDelegate);

            // Methods that have a byref-like type in the signature cannot be invoked with the object array thunk.
            // We would need to box the parameter and these can't be boxed.
            // Neither can be methods that have pointers in the signature.
            MethodSignature delegateSignature        = owningDelegate.Signature;
            bool            generateObjectArrayThunk = true;

            for (int i = 0; i < delegateSignature.Length; i++)
            {
                TypeDesc paramType = delegateSignature[i];
                if (paramType.IsByRef)
                {
                    paramType = ((ByRefType)paramType).ParameterType;
                }
                if (!paramType.IsSignatureVariable && paramType.IsByRefLike)
                {
                    generateObjectArrayThunk = false;
                    break;
                }
                if (paramType.IsPointer || paramType.IsFunctionPointer)
                {
                    generateObjectArrayThunk = false;
                    break;
                }
            }
            TypeDesc normalizedReturnType = delegateSignature.ReturnType;

            if (normalizedReturnType.IsByRef)
            {
                normalizedReturnType = ((ByRefType)normalizedReturnType).ParameterType;
            }
            if (!normalizedReturnType.IsSignatureVariable && normalizedReturnType.IsByRefLike)
            {
                generateObjectArrayThunk = false;
            }
            if (normalizedReturnType.IsPointer || normalizedReturnType.IsFunctionPointer)
            {
                generateObjectArrayThunk = false;
            }

            if ((owningDelegate.SupportedFeatures & DelegateFeature.ObjectArrayThunk) != 0 && generateObjectArrayThunk)
            {
                _invokeObjectArrayThunk = new DelegateInvokeObjectArrayThunk(owningDelegate);
            }

            //
            // Check whether we have a reverse p/invoke thunk
            //

            if (!owningDelegate.Type.HasInstantiation && IsNativeCallingConventionCompatible(delegateSignature))
            {
                _reversePInvokeThunk = new DelegateReversePInvokeThunk(owningDelegate);
            }

            //
            // Check whether we have an open instance thunk
            //

            if (delegateSignature.Length > 0)
            {
                TypeDesc firstParam = delegateSignature[0];

                bool generateOpenInstanceMethod;

                switch (firstParam.Category)
                {
                case TypeFlags.Pointer:
                case TypeFlags.FunctionPointer:
                    generateOpenInstanceMethod = false;
                    break;

                case TypeFlags.ByRef:
                    firstParam = ((ByRefType)firstParam).ParameterType;
                    generateOpenInstanceMethod = firstParam.IsSignatureVariable || firstParam.IsValueType;
                    break;

                case TypeFlags.Array:
                case TypeFlags.SzArray:
                case TypeFlags.SignatureTypeVariable:
                    generateOpenInstanceMethod = true;
                    break;

                default:
                    Debug.Assert(firstParam.IsDefType);
                    generateOpenInstanceMethod = !firstParam.IsValueType;
                    break;
                }

                if (generateOpenInstanceMethod)
                {
                    _openInstanceThunk = new DelegateInvokeOpenInstanceThunk(owningDelegate);
                }
            }
        }
예제 #27
0
 static string OverloadName(MethodSignature sig)
 {
     if ( sig.ParamTypes.Length == 0 )
         return sig.Name + "-void";
     else
     {
         string[] names = new string[sig.ParamTypes.Length+1];
         names[0] = sig.Name;
         for ( int i=0; i< sig.ParamTypes.Length; i++ )
             names[i+1] = EscapeTypeName(sig.ParamTypes[i]);
         return String.Join("-",names);
     }
 }
 public MethodDesc GetCalliStub(MethodSignature signature)
 {
     return(_interopStateManager.GetPInvokeCalliStub(signature));
 }
 public MethodSignatureFilter(ResolveErrorType errorType, MethodSignature methodSignature)
 {
     myMethodSignature = methodSignature;
     ErrorType         = errorType;
 }
예제 #30
0
        private MemberInfo GetMemberRef(int index, Type[] genericTypeArguments, Type[] genericMethodArguments)
        {
            if (memberRefs == null)
            {
                memberRefs = new MemberInfo[MemberRef.records.Length];
            }
            if (memberRefs[index] == null)
            {
                int    owner = MemberRef.records[index].Class;
                int    sig   = MemberRef.records[index].Signature;
                string name  = GetString(MemberRef.records[index].Name);
                switch (owner >> 24)
                {
                case MethodDefTable.Index:
                    return(GetMethodAt(null, (owner & 0xFFFFFF) - 1));

                case ModuleRefTable.Index:
                    memberRefs[index] = ResolveTypeMemberRef(ResolveModuleType(owner), name, ByteReader.FromBlob(blobHeap, sig));
                    break;

                case TypeDefTable.Index:
                case TypeRefTable.Index:
                    memberRefs[index] = ResolveTypeMemberRef(ResolveType(owner), name, ByteReader.FromBlob(blobHeap, sig));
                    break;

                case TypeSpecTable.Index:
                {
                    Type type = ResolveType(owner, genericTypeArguments, genericMethodArguments);
                    if (type.IsArray)
                    {
                        MethodSignature methodSig = MethodSignature.ReadSig(this, ByteReader.FromBlob(blobHeap, sig), new GenericContext(genericTypeArguments, genericMethodArguments));
                        return(type.FindMethod(name, methodSig)
                               ?? universe.GetMissingMethodOrThrow(type, name, methodSig));
                    }
                    else if (type.IsConstructedGenericType)
                    {
                        MemberInfo member = ResolveTypeMemberRef(type.GetGenericTypeDefinition(), name, ByteReader.FromBlob(blobHeap, sig));
                        MethodBase mb     = member as MethodBase;
                        if (mb != null)
                        {
                            member = mb.BindTypeParameters(type);
                        }
                        FieldInfo fi = member as FieldInfo;
                        if (fi != null)
                        {
                            member = fi.BindTypeParameters(type);
                        }
                        return(member);
                    }
                    else
                    {
                        return(ResolveTypeMemberRef(type, name, ByteReader.FromBlob(blobHeap, sig)));
                    }
                }

                default:
                    throw new BadImageFormatException();
                }
            }
            return(memberRefs[index]);
        }
예제 #31
0
        public MethodIL EmitIL()
        {
            MethodSignature targetMethodSignature = _targetMethod.Signature;

            // We have 4 code streams:
            // - _marshallingCodeStream is used to convert each argument into a native type and
            // store that into the local
            // - callsiteSetupCodeStream is used to used to load each previously generated local
            // and call the actual target native method.
            // - _returnValueMarshallingCodeStream is used to convert the native return value
            // to managed one.
            // - _unmarshallingCodestream is used to propagate [out] native arguments values to
            // managed ones.
            _emitter = new ILEmitter();
            ILCodeStream fnptrLoadStream = _emitter.NewCodeStream();

            _marshallingCodeStream = _emitter.NewCodeStream();
            ILCodeStream callsiteSetupCodeStream = _emitter.NewCodeStream();

            _returnValueMarshallingCodeStream = _emitter.NewCodeStream();
            _unmarshallingCodestream          = _emitter.NewCodeStream();

            TypeDesc[] nativeParameterTypes = new TypeDesc[targetMethodSignature.Length];

            //
            // Parameter marshalling
            //

            //
            // Convert each argument to something we can pass to native and store it in a local.
            // Then load the local in the second code stream.
            //
            for (int i = 0; i < targetMethodSignature.Length; i++)
            {
                // TODO: throw if there's custom marshalling

                _marshallingCodeStream.EmitLdArg(i);

                TypeDesc nativeType = MarshalArgument(targetMethodSignature[i]);

                nativeParameterTypes[i] = nativeType;

                ILLocalVariable vMarshalledTypeTemp = _emitter.NewLocal(nativeType);
                _marshallingCodeStream.EmitStLoc(vMarshalledTypeTemp);

                callsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp);
            }

            //
            // Return value marshalling
            //

            // TODO: throw if SetLastError is true
            // TODO: throw if there's custom marshalling

            TypeDesc nativeReturnType = MarshalReturnValue(targetMethodSignature.ReturnType);

            if (UseLazyResolution(_targetMethod, _importMetadata.Module))
            {
                MetadataType lazyHelperType   = _targetMethod.Context.GetHelperType("InteropHelpers");
                FieldDesc    lazyDispatchCell = new PInvokeLazyFixupField((DefType)_targetMethod.OwningType, _importMetadata);
                fnptrLoadStream.Emit(ILOpcode.ldsflda, _emitter.NewToken(lazyDispatchCell));
                fnptrLoadStream.Emit(ILOpcode.call, _emitter.NewToken(lazyHelperType.GetKnownMethod("ResolvePInvoke", null)));

                MethodSignatureFlags unmanagedCallConv = PInvokeMetadata.GetUnmanagedCallingConvention(_importMetadata.Attributes);

                MethodSignature nativeCalliSig = new MethodSignature(
                    targetMethodSignature.Flags | unmanagedCallConv, 0, nativeReturnType, nativeParameterTypes);

                ILLocalVariable vNativeFunctionPointer = _emitter.NewLocal(_targetMethod.Context.GetWellKnownType(WellKnownType.IntPtr));
                fnptrLoadStream.EmitStLoc(vNativeFunctionPointer);
                callsiteSetupCodeStream.EmitLdLoc(vNativeFunctionPointer);
                callsiteSetupCodeStream.Emit(ILOpcode.calli, _emitter.NewToken(nativeCalliSig));
            }
            else
            {
                // Eager call
                PInvokeMetadata nativeImportMetadata =
                    new PInvokeMetadata(_importMetadata.Module, _importMetadata.Name ?? _targetMethod.Name, _importMetadata.Attributes);

                MethodSignature nativeSig = new MethodSignature(
                    targetMethodSignature.Flags, 0, nativeReturnType, nativeParameterTypes);

                MethodDesc nativeMethod =
                    new PInvokeTargetNativeMethod(_targetMethod.OwningType, nativeSig, nativeImportMetadata);

                callsiteSetupCodeStream.Emit(ILOpcode.call, _emitter.NewToken(nativeMethod));
            }

            _unmarshallingCodestream.Emit(ILOpcode.ret);

            return(_emitter.Link(_targetMethod));
        }
예제 #32
0
        internal static (IType returnType, IParameter[] parameters, ModifiedType returnTypeModifier) DecodeSignature(
            MetadataModule module, IParameterizedMember owner,
            MethodSignature <IType> signature, ParameterHandleCollection?parameterHandles,
            Nullability nullableContext, TypeSystemOptions typeSystemOptions,
            CustomAttributeHandleCollection?returnTypeAttributes = null)
        {
            var metadata = module.metadata;
            int i        = 0;

            IParameter[] parameters = new IParameter[signature.RequiredParameterCount
                                                     + (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs ? 1 : 0)];
            IType parameterType;

            if (parameterHandles != null)
            {
                foreach (var parameterHandle in parameterHandles)
                {
                    var par = metadata.GetParameter(parameterHandle);
                    if (par.SequenceNumber == 0)
                    {
                        // "parameter" holds return type attributes.
                        // Note: for properties, the attributes normally stored on a method's return type
                        // are instead stored as normal attributes on the property.
                        // So MetadataProperty provides a non-null value for returnTypeAttributes,
                        // which then should be preferred over the attributes on the accessor's parameters.
                        if (returnTypeAttributes == null)
                        {
                            returnTypeAttributes = par.GetCustomAttributes();
                        }
                    }
                    else if (i < par.SequenceNumber && par.SequenceNumber <= signature.RequiredParameterCount)
                    {
                        // "Successive rows of the Param table that are owned by the same method shall be
                        // ordered by increasing Sequence value - although gaps in the sequence are allowed"
                        Debug.Assert(par.SequenceNumber <= signature.ParameterTypes.Length);
                        Debug.Assert(par.SequenceNumber <= parameters.Length);
                        // Fill gaps in the sequence with non-metadata parameters:
                        while (i < par.SequenceNumber - 1)
                        {
                            parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType(
                                signature.ParameterTypes[i], module.Compilation, null, metadata, typeSystemOptions, nullableContext);
                            parameters[i] = new DefaultParameter(parameterType, name: string.Empty, owner,
                                                                 referenceKind: parameterType.Kind == TypeKind.ByReference ? ReferenceKind.Ref : ReferenceKind.None);
                            i++;
                        }
                        parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType(
                            signature.ParameterTypes[i], module.Compilation,
                            par.GetCustomAttributes(), metadata, typeSystemOptions, nullableContext);
                        parameters[i] = new MetadataParameter(module, owner, parameterType, parameterHandle);
                        i++;
                    }
                }
            }
            while (i < signature.RequiredParameterCount)
            {
                parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType(
                    signature.ParameterTypes[i], module.Compilation, null, metadata, typeSystemOptions, nullableContext);
                parameters[i] = new DefaultParameter(parameterType, name: string.Empty, owner,
                                                     referenceKind: parameterType.Kind == TypeKind.ByReference ? ReferenceKind.Ref : ReferenceKind.None);
                i++;
            }
            if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs)
            {
                parameters[i] = new DefaultParameter(SpecialType.ArgList, name: string.Empty, owner);
                i++;
            }
            Debug.Assert(i == parameters.Length);
            var returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType(signature.ReturnType,
                                                                             module.Compilation, returnTypeAttributes, metadata, typeSystemOptions, nullableContext,
                                                                             isSignatureReturnType: true);

            return(returnType, parameters, signature.ReturnType as ModifiedType);
        }
            //-------------------------------------------------------------------------------------------------------------------------------------------------
            public LogMethodWriter(TemplateMethodWriter underlyingWriter, Field<IThreadLogAppender> threadLogAppenderField)
            {
                _underlyingWriter = underlyingWriter;
                _threadLogAppenderField = threadLogAppenderField;
                _declaration = underlyingWriter.OwnerMethod.MethodDeclaration;
                _signature = underlyingWriter.OwnerMethod.Signature;
                _parameters = _declaration.GetParameters();
                _messageId = GetMessageId(_declaration);
                _attribute = _declaration.GetCustomAttribute<LogAttributeBase>();
                _mustCreateException = _declaration.ReturnType.IsExceptionType();
                _exceptionArgumentIndex = new List<int>();
                _isValueArgument = new bool[_signature.ArgumentCount];
                _valueArgumentFormat = new string[_signature.ArgumentCount];
                _valueArgumentDetails = new DetailAttribute[_signature.ArgumentCount];
                _nameValuePairLocals = new List<IOperand>();

                ValidateSignature();
            }
예제 #34
0
        private string GetMethodTypeName(MethodSignature method)
        {
            var containingTypeName = method.ContainingType.TypeName.Split('.').Last();

            return(string.Concat(containingTypeName, ".", method.Name));
        }
예제 #35
0
 private static void GetAllMethods(Type type, HashSet<MethodSignature> considered, List<MethodSignature> todo, string source)
 {
     foreach (MethodInfo mi in type.GetMethods(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
     {
         MethodSignature ms = new MethodSignature(mi, source);
         if (!considered.Contains(ms)
             && (mi.IsPublic || mi.IsFamily)
             && !mi.IsStatic
             && !mi.IsFinal
             && !"Dispose".Equals(mi.Name))
             todo.Add(ms);
         considered.Add(ms);
     }
 }
예제 #36
0
 public DummyType GetFunctionPointerType(MethodSignature <DummyType> signature)
 {
     return(DummyType.Instance);
 }
        GetParameters(MetadataReader reader, TypeReferenceTypeProvider typeProvider, GenericContext genericContext, MethodSignature <MetadataTypeReference> signature, ParameterHandleCollection handles)
        {
            var parameters            = new IMetadataParameter[handles.Count];
            var returnValueAttributes = (IReadOnlyList <IMetadataAttribute>)null;

            var maxSequenceNumber = 0;

            foreach (var handle in handles)
            {
                var parameter = reader.GetParameter(handle);
                if (parameter.SequenceNumber == 0)
                {
                    returnValueAttributes = GetAttributes(reader, typeProvider, parameter.GetCustomAttributes(), genericContext);
                    continue;
                }
                if (maxSequenceNumber < parameter.SequenceNumber)
                {
                    maxSequenceNumber = parameter.SequenceNumber;
                }
                var parameterIndex = parameter.SequenceNumber - 1;
                parameters[parameterIndex] = new ReaderParameter(reader, typeProvider, parameter, genericContext, signature.ParameterTypes[parameterIndex]);
            }

            if (maxSequenceNumber == parameters.Length)
            {
                return(parameters, Array.Empty <IMetadataAttribute>());
            }

            // Account for skipping the return parameter
            var correctedLength = new IMetadataParameter[maxSequenceNumber];

            Array.Copy(parameters, correctedLength, correctedLength.Length);
            return(correctedLength, returnValueAttributes);
        }
예제 #38
0
 public IHtmlString Render(MethodSignature method, MethodRenderOption option)
 {
     return(_methodRenderer.Render(_languageProvider, method, option));
 }
예제 #39
0
 public PInvokeTargetNativeMethod(MethodDesc declMethod, MethodSignature signature)
 {
     _declMethod = declMethod;
     _signature  = signature;
 }
예제 #40
0
        /// <summary>
        /// Compute the canonical instantiation of a dynamic invoke thunk needed to invoke a method
        /// This algorithm is shared with the runtime, so if a thunk requires generic instantiation
        /// to be used, it must match this algorithm, and cannot be different with different MetadataManagers
        /// NOTE: This function may return null in cases where an exact instantiation does not exist. (Universal Generics)
        /// </summary>
        protected MethodDesc InstantiateCanonicalDynamicInvokeMethodForMethod(MethodDesc thunk, MethodDesc method)
        {
            if (thunk.Instantiation.Length == 0)
            {
                // nothing to instantiate
                return(thunk);
            }

            MethodSignature   sig     = method.Signature;
            TypeSystemContext context = method.Context;

            //
            // Instantiate the generic thunk over the parameters and the return type of the target method
            //

            ParameterMetadata[] paramMetadata = null;
            TypeDesc[]          instantiation = new TypeDesc[sig.ReturnType.IsVoid ? sig.Length : sig.Length + 1];
            Debug.Assert(thunk.Instantiation.Length == instantiation.Length);
            for (int i = 0; i < sig.Length; i++)
            {
                TypeDesc parameterType = sig[i];
                if (parameterType.IsByRef)
                {
                    // strip ByRefType off the parameter (the method already has ByRef in the signature)
                    parameterType = ((ByRefType)parameterType).ParameterType;

                    Debug.Assert(!parameterType.IsPointer); // TODO: support for methods returning pointer types - https://github.com/dotnet/corert/issues/2113
                }
                else if (parameterType.IsPointer || parameterType.IsFunctionPointer)
                {
                    // For pointer typed parameters, instantiate the method over IntPtr
                    parameterType = context.GetWellKnownType(WellKnownType.IntPtr);
                }
                else if (parameterType.IsEnum)
                {
                    // If the invoke method takes an enum as an input parameter and there is no default value for
                    // that paramter, we don't need to specialize on the exact enum type (we only need to specialize
                    // on the underlying integral type of the enum.)
                    if (paramMetadata == null)
                    {
                        paramMetadata = method.GetParameterMetadata();
                    }

                    bool hasDefaultValue = false;
                    foreach (var p in paramMetadata)
                    {
                        // Parameter metadata indexes are 1-based (0 is reserved for return "parameter")
                        if (p.Index == (i + 1) && p.HasDefault)
                        {
                            hasDefaultValue = true;
                            break;
                        }
                    }

                    if (!hasDefaultValue)
                    {
                        parameterType = parameterType.UnderlyingType;
                    }
                }

                instantiation[i] = parameterType;
            }

            if (!sig.ReturnType.IsVoid)
            {
                TypeDesc returnType = sig.ReturnType;
                Debug.Assert(!returnType.IsByRef);

                // If the invoke method return an object reference, we don't need to specialize on the
                // exact type of the object reference, as the behavior is not different.
                if ((returnType.IsDefType && !returnType.IsValueType) || returnType.IsArray)
                {
                    returnType = context.GetWellKnownType(WellKnownType.Object);
                }

                instantiation[sig.Length] = returnType;
            }

            Debug.Assert(thunk.Instantiation.Length == instantiation.Length);

            // Check if at least one of the instantiation arguments is a universal canonical type, and if so, we
            // won't create a dynamic invoker instantiation. The arguments will be interpreted at runtime by the
            // calling convention converter during the dynamic invocation
            foreach (TypeDesc type in instantiation)
            {
                if (type.IsCanonicalSubtype(CanonicalFormKind.Universal))
                {
                    return(null);
                }
            }

            // If the thunk ends up being shared code, return the canonical method body.
            // The concrete dictionary for the thunk will be built at runtime and is not interesting for the compiler.
            Instantiation canonInstantiation = context.ConvertInstantiationToCanonForm(new Instantiation(instantiation), CanonicalFormKind.Specific);

            MethodDesc instantiatedDynamicInvokeMethod = thunk.Context.GetInstantiatedMethod(thunk, canonInstantiation);

            return(instantiatedDynamicInvokeMethod);
        }
예제 #41
0
        private Object ResolveMemberReference(MemberReferenceHandle handle)
        {
            MemberReference memberReference = _metadataReader.GetMemberReference(handle);

            Object parent = GetObject(memberReference.Parent);

            TypeDesc parentTypeDesc = parent as TypeDesc;

            if (parentTypeDesc != null)
            {
                BlobReader signatureReader = _metadataReader.GetBlobReader(memberReference.Signature);

                EcmaSignatureParser parser = new EcmaSignatureParser(this, signatureReader);

                string name = _metadataReader.GetString(memberReference.Name);

                if (parser.IsFieldSignature)
                {
                    FieldDesc field = parentTypeDesc.GetField(name);
                    if (field != null)
                    {
                        return(field);
                    }

                    // TODO: Better error message
                    throw new MissingMemberException("Field not found " + parent.ToString() + "." + name);
                }
                else
                {
                    MethodSignature sig = parser.ParseMethodSignature();
                    TypeDesc        typeDescToInspect = parentTypeDesc;

                    // Try to resolve the name and signature in the current type, or any of the base types.
                    do
                    {
                        // TODO: handle substitutions
                        MethodDesc method = typeDescToInspect.GetMethod(name, sig);
                        if (method != null)
                        {
                            // If this resolved to one of the base types, make sure it's not a constructor.
                            // Instance constructors are not inherited.
                            if (typeDescToInspect != parentTypeDesc && method.IsConstructor)
                            {
                                break;
                            }

                            return(method);
                        }
                        typeDescToInspect = typeDescToInspect.BaseType;
                    } while (typeDescToInspect != null);

                    // TODO: Better error message
                    throw new MissingMemberException("Method not found " + parent.ToString() + "." + name);
                }
            }
            else if (parent is MethodDesc)
            {
                throw new NotSupportedException("Vararg methods not supported in .NET Core.");
            }
            else if (parent is ModuleDesc)
            {
                throw new NotImplementedException("MemberRef to a global function or variable.");
            }

            throw new BadImageFormatException();
        }
예제 #42
0
 public InvokableMethod(Delegate invokableMethod, MethodSignature signature)
 {
     Debug.Assert(invokableMethod != null);
     this.invokableMethod = invokableMethod;
     this.signature       = signature;
 }
예제 #43
0
 public EventDef(IImSeq<Annotation> annotations, ISeq<CustomAttribute> customAttributes, string name, bool isStatic, MethodSignature add, MethodSignature remove, TypeRef handlerType)
     : base(annotations, customAttributes, name, isStatic)
 {
     Add = add;
     Remove = remove;
     HandlerType = handlerType;
 }
예제 #44
0
 /// <summary>
 ///   Builds the name of the method.
 /// </summary>
 /// <param name="info">The method information.</param>
 /// <returns>The method name.</returns>
 private static string BuildMethodName(MethodBase info) =>
 MethodSignature.FormatWith(
     info.DeclaringType?.Name,
     info.Name,
     info.GetParameters().Select(x => ParameterName.FormatWith(x.ParameterType.Name, x.Name)).ToCommaSeparatedString());
예제 #45
0
        public void GetCallRefMap(MethodDesc method, bool isUnboxingStub)
        {
            TransitionBlock transitionBlock = TransitionBlock.FromTarget(method.Context.Target);

            MethodSignature signature = method.Signature;

            bool hasThis = (signature.Flags & MethodSignatureFlags.Static) == 0;

            // This pointer is omitted for string constructors
            bool fCtorOfVariableSizedObject = hasThis && method.OwningType.IsString && method.IsConstructor;

            if (fCtorOfVariableSizedObject)
            {
                hasThis = false;
            }

            bool       isVarArg   = false;
            TypeHandle returnType = new TypeHandle(signature.ReturnType);

            TypeHandle[] parameterTypes = new TypeHandle[signature.Length];
            for (int parameterIndex = 0; parameterIndex < parameterTypes.Length; parameterIndex++)
            {
                parameterTypes[parameterIndex] = new TypeHandle(signature[parameterIndex]);
            }
            CallingConventions callingConventions = (hasThis ? CallingConventions.ManagedInstance : CallingConventions.ManagedStatic);
            bool hasParamType = method.RequiresInstArg() && !isUnboxingStub;

            // On X86 the Array address method doesn't use IL stubs, and instead has a custom calling convention
            if ((method.Context.Target.Architecture == TargetArchitecture.X86) &&
                method.IsArrayAddressMethod())
            {
                hasParamType = true;
            }

            bool extraFunctionPointerArg = false;

            bool[]          forcedByRefParams   = new bool[parameterTypes.Length];
            bool            skipFirstArg        = false;
            bool            extraObjectFirstArg = false;
            ArgIteratorData argIteratorData     = new ArgIteratorData(hasThis, isVarArg, parameterTypes, returnType);

            ArgIterator argit = new ArgIterator(
                method.Context,
                argIteratorData,
                callingConventions,
                hasParamType,
                extraFunctionPointerArg,
                forcedByRefParams,
                skipFirstArg,
                extraObjectFirstArg);

            int nStackBytes = argit.SizeOfFrameArgumentArray();

            // Allocate a fake stack
            CORCOMPILE_GCREFMAP_TOKENS[] fakeStack = new CORCOMPILE_GCREFMAP_TOKENS[transitionBlock.SizeOfTransitionBlock + nStackBytes];

            // Fill it in
            FakeGcScanRoots(method, argit, fakeStack, isUnboxingStub);

            // Encode the ref map
            uint nStackSlots;

            if (_target.Architecture == TargetArchitecture.X86)
            {
                uint cbStackPop = argit.CbStackPop();
                WriteStackPop(cbStackPop / (uint)_target.PointerSize);

                nStackSlots = (uint)(nStackBytes / _target.PointerSize + _transitionBlock.NumArgumentRegisters);
            }
            else
            {
                nStackSlots = (uint)((transitionBlock.SizeOfTransitionBlock + nStackBytes - _transitionBlock.OffsetOfFirstGCRefMapSlot) / _target.PointerSize);
            }

            for (uint pos = 0; pos < nStackSlots; pos++)
            {
                int offset = _transitionBlock.OffsetFromGCRefMapPos(checked ((int)pos));
                CORCOMPILE_GCREFMAP_TOKENS token = fakeStack[offset];

                if (token != CORCOMPILE_GCREFMAP_TOKENS.GCREFMAP_SKIP)
                {
                    WriteToken(pos, (byte)token);
                }
            }

            Flush();
        }
예제 #46
0
        public MethodIL EmitIL()
        {
            // We have two code streams - one is used to convert each argument into a native type
            // and store that into the local. The other is used to load each previously generated local
            // and call the actual target native method.
            _emitter = new ILEmitter();
            _marshallingCodeStream = _emitter.NewCodeStream();
            ILCodeStream callsiteSetupCodeStream = _emitter.NewCodeStream();

            // TODO: throw if SetLastError is true
            // TODO: throw if there's custom marshalling
            TypeDesc nativeReturnType = _targetMethod.Signature.ReturnType;

            if (!IsBlittableType(nativeReturnType) && !nativeReturnType.IsVoid)
            {
                throw new NotSupportedException();
            }

            TypeDesc[] nativeParameterTypes = new TypeDesc[_targetMethod.Signature.Length];

            //
            // Convert each argument to something we can pass to native and store it in a local.
            // Then load the local in the second code stream.
            //
            for (int i = 0; i < _targetMethod.Signature.Length; i++)
            {
                // TODO: throw if there's custom marshalling
                TypeDesc parameterType = _targetMethod.Signature[i];

                _marshallingCodeStream.EmitLdArg(i);

                TypeDesc nativeType;
                if (parameterType.IsSzArray)
                {
                    nativeType = EmitArrayMarshalling((ArrayType)parameterType);
                }
                else if (parameterType.IsByRef)
                {
                    nativeType = EmitByRefMarshalling((ByRefType)parameterType);
                }
                else if (parameterType.IsString)
                {
                    nativeType = EmitStringMarshalling();
                }
                else
                {
                    if (!IsBlittableType(parameterType))
                    {
                        throw new NotSupportedException();
                    }

                    nativeType = parameterType.UnderlyingType;
                }

                nativeParameterTypes[i] = nativeType;

                ILLocalVariable vMarshalledTypeTemp = _emitter.NewLocal(nativeType);
                _marshallingCodeStream.EmitStLoc(vMarshalledTypeTemp);

                callsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp);
            }

            MethodSignature nativeSig = new MethodSignature(
                _targetMethod.Signature.Flags, 0, nativeReturnType, nativeParameterTypes);
            MethodDesc nativeMethod =
                new PInvokeTargetNativeMethod(_targetMethod.OwningType, nativeSig, _importMetadata);

            // Call the native method
            callsiteSetupCodeStream.Emit(ILOpcode.call, _emitter.NewToken(nativeMethod));
            callsiteSetupCodeStream.Emit(ILOpcode.ret);

            return(_emitter.Link());
        }
예제 #47
0
 private InterceptorState FindInterceptorStateByMethodSignature(MethodSignature signature)
 {
     return InterceptorStateCollection.Where(m => m.MethodSignature.Equals(signature)).SingleOrDefault();
 }
예제 #48
0
 public PInvokeTargetNativeMethod(TypeDesc owningType, MethodSignature signature, PInvokeMetadata methodMetadata)
 {
     _owningType     = owningType;
     _signature      = signature;
     _methodMetadata = methodMetadata;
 }
예제 #49
0
        // TODO: Define an extension to proxy that allows overriding getters/setters on properties.
        private static void AddInterfaceProperties(
            TypeBuilder proxyTB,
            Type superclass,
            HashSet<Type> allInterfaces,
            HashSet<MethodBuilder> specialMethods)
        {
            HashSet<MethodSignature> considered = new HashSet<MethodSignature>();
            List<PropertyInfo> properties = new List<PropertyInfo>();

            PropertyInfo[] pinfos = superclass.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (PropertyInfo p in pinfos)
            {
                MethodSignature sig = new MethodSignature(p);
                if (!considered.Contains(sig))
                    properties.Add(p);
                considered.Add(sig);
            }

            foreach (Type ifType in allInterfaces)
                foreach (PropertyInfo p in ifType.GetProperties())
                {
                    MethodSignature sig = new MethodSignature(p);
                    if (!considered.Contains(sig))
                        properties.Add(p);
                    considered.Add(sig);
                }
            foreach (PropertyInfo pi in properties)
            {
                PropertyBuilder pb = proxyTB.DefineProperty(pi.Name,
                    pi.Attributes,
                    pi.PropertyType,
                    pi.GetIndexParameters().Select<ParameterInfo, Type>(p => p.ParameterType).ToArray<Type>());
                string getterName = "get_" + pi.Name;
                string setterName = "set_" + pi.Name;
                MethodBuilder getter = specialMethods.Where(m => m.Name.Equals(getterName)).FirstOrDefault();
                MethodBuilder setter = specialMethods.Where(m => m.Name.Equals(setterName)).FirstOrDefault();
                if ( getter != null )
                    pb.SetGetMethod(getter);
                if ( setter != null )
                    pb.SetSetMethod(setter);

                //Console.Write("Generating proxy property {0} ({1})", pi.Name, pi.PropertyType);
                //if (getter != null)
                //    Console.Write(", get = {0}", getter.Name);
                //if (setter != null)
                //    Console.Write(", set = {0}", setter.Name);
                //Console.WriteLine();

            }
        }
예제 #50
0
        private static void EmitForwardingMethod(TypeBuilder proxyTB,
                                                 bool isStatic,
                                                 FieldBuilder regularFB,
                                                 FieldBuilder overloadFB,
                                                 MethodSignature sig,
                                                 ElseGenDelegate elseGen)
        {
            MethodAttributes   attributes;
            CallingConventions conventions;

            if (isStatic)
            {
                attributes  = MethodAttributes.Public | MethodAttributes.Static;
                conventions = CallingConventions.Standard;
            }
            else
            {
                attributes  = MethodAttributes.Public | MethodAttributes.Virtual;
                conventions = CallingConventions.HasThis;
            }

            MethodBuilder mb  = proxyTB.DefineMethod(sig.Name, attributes, conventions, sig.ReturnType, sig.ParamTypes);
            CljILGen      gen = new CljILGen(mb.GetILGenerator());

            Label foundLabel = gen.DefineLabel();
            Label elseLabel  = gen.DefineLabel();
            Label endLabel   = gen.DefineLabel();

            if (sig.ParamTypes.Length > 18)
            {
                elseGen(gen);
            }
            else
            {
                if (overloadFB != null)
                {
                    EmitGetVar(gen, overloadFB);
                    gen.Emit(OpCodes.Dup);
                    gen.Emit(OpCodes.Brtrue_S, foundLabel);
                    gen.Emit(OpCodes.Pop);
                }
                EmitGetVar(gen, regularFB);
                gen.Emit(OpCodes.Dup);
                gen.Emit(OpCodes.Brfalse_S, elseLabel);

                if (overloadFB != null)
                {
                    gen.MarkLabel(foundLabel);
                }
                gen.Emit(OpCodes.Castclass, typeof(IFn));

                if (!isStatic)
                {
                    gen.EmitLoadArg(0);                     // gen.Emit(OpCodes.Ldarg_0);
                }
                for (int i = 0; i < sig.ParamTypes.Length; i++)
                {
                    gen.EmitLoadArg(isStatic ? i : i + 1);                 // gen.Emit(OpCodes.Ldarg, i + 1);
                    if (sig.ParamTypes[i].IsValueType)
                    {
                        gen.Emit(OpCodes.Box, sig.ParamTypes[i]);
                    }
                }
                gen.EmitCall(Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]);
                //gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]);
                if (sig.ReturnType == typeof(void))
                {
                    gen.Emit(OpCodes.Pop);
                }
                else if (sig.ReturnType.IsValueType)
                {
                    gen.Emit(OpCodes.Unbox_Any, sig.ReturnType);
                }
                else
                {
                    gen.Emit(OpCodes.Castclass, sig.ReturnType);
                }
                gen.Emit(OpCodes.Br_S, endLabel);

                gen.MarkLabel(elseLabel);
                gen.Emit(OpCodes.Pop);
                elseGen(gen);

                gen.MarkLabel(endLabel);
                gen.Emit(OpCodes.Ret);
            }
        }
예제 #51
0
        private static void EmitForwardingMethod(TypeBuilder proxyTB, 
            bool isStatic,
            FieldBuilder regularFB,
            FieldBuilder overloadFB,
            MethodSignature sig,
            ElseGenDelegate elseGen)
        {
            MethodAttributes attributes;
            CallingConventions conventions;

            if (isStatic)
            {
                attributes = MethodAttributes.Public | MethodAttributes.Static;
                conventions = CallingConventions.Standard;
            }
            else
            {
                attributes = MethodAttributes.Public | MethodAttributes.Virtual;
                conventions = CallingConventions.HasThis;
            }

            MethodBuilder mb = proxyTB.DefineMethod(sig.Name, attributes, conventions, sig.ReturnType, sig.ParamTypes);
            ILGen gen = new ILGen(mb.GetILGenerator());

            Label foundLabel = gen.DefineLabel();
            Label elseLabel = gen.DefineLabel();
            Label endLabel = gen.DefineLabel();

            if (sig.ParamTypes.Length > 18)
                elseGen(gen);
            else
            {

                if (overloadFB != null)
                {
                    EmitGetVar(gen, overloadFB);
                    gen.Emit(OpCodes.Dup);
                    gen.Emit(OpCodes.Brtrue_S, foundLabel);
                    gen.Emit(OpCodes.Pop);
                }
                EmitGetVar(gen, regularFB);
                gen.Emit(OpCodes.Dup);
                gen.Emit(OpCodes.Brfalse_S, elseLabel);

                if (overloadFB != null)
                    gen.MarkLabel(foundLabel);
                gen.Emit(OpCodes.Castclass, typeof(IFn));

                if (!isStatic)
                    gen.EmitLoadArg(0);                     // gen.Emit(OpCodes.Ldarg_0);

                for (int i = 0; i < sig.ParamTypes.Length; i++)
                {
                    gen.EmitLoadArg(isStatic ? i : i + 1);                 // gen.Emit(OpCodes.Ldarg, i + 1);
                    if (sig.ParamTypes[i].IsValueType)
                        gen.Emit(OpCodes.Box, sig.ParamTypes[i]);

                }
                gen.EmitCall(Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]);
                //gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]);
                if (sig.ReturnType == typeof(void))
                    gen.Emit(OpCodes.Pop);
                else if (sig.ReturnType.IsValueType)
                    gen.Emit(OpCodes.Unbox_Any,sig.ReturnType);
                gen.Emit(OpCodes.Br_S, endLabel);

                gen.MarkLabel(elseLabel);
                gen.Emit(OpCodes.Pop);
                elseGen(gen);

                gen.MarkLabel(endLabel);
                gen.Emit(OpCodes.Ret);
            }
        }
예제 #52
0
        public void SimpleSignatureProviderCoverage()
        {
            using (FileStream stream = File.OpenRead(typeof(SignaturesToDecode <>).GetTypeInfo().Assembly.Location))
                using (var peReader = new PEReader(stream))
                {
                    MetadataReader       reader     = peReader.GetMetadataReader();
                    var                  provider   = new DisassemblingTypeProvider();
                    TypeDefinitionHandle typeHandle = TestMetadataResolver.FindTestType(reader, typeof(SignaturesToDecode <>));
                    Assert.Equal("System.Reflection.Metadata.Decoding.Tests.SignatureDecoderTests/SignaturesToDecode`1", provider.GetTypeFromHandle(reader, genericContext: null, handle: typeHandle));

                    TypeDefinition type = reader.GetTypeDefinition(typeHandle);
                    Dictionary <string, string> expectedFields        = GetExpectedFieldSignatures();
                    ImmutableArray <string>     genericTypeParameters = type.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray();

                    var genericTypeContext = new DisassemblingGenericContext(genericTypeParameters, ImmutableArray <string> .Empty);

                    foreach (var fieldHandle in type.GetFields())
                    {
                        FieldDefinition field     = reader.GetFieldDefinition(fieldHandle);
                        string          fieldName = reader.GetString(field.Name);
                        string          expected;
                        Assert.True(expectedFields.TryGetValue(fieldName, out expected), "Unexpected field: " + fieldName);
                        Assert.Equal(expected, field.DecodeSignature(provider, genericTypeContext));
                    }

                    Dictionary <string, string> expectedMethods = GetExpectedMethodSignatures();
                    foreach (var methodHandle in type.GetMethods())
                    {
                        MethodDefinition method = reader.GetMethodDefinition(methodHandle);

                        ImmutableArray <string> genericMethodParameters = method.GetGenericParameters().Select(h => reader.GetString(reader.GetGenericParameter(h).Name)).ToImmutableArray();
                        var genericMethodContext = new DisassemblingGenericContext(genericTypeParameters, genericMethodParameters);

                        string methodName = reader.GetString(method.Name);
                        string expected;
                        Assert.True(expectedMethods.TryGetValue(methodName, out expected), "Unexpected method: " + methodName);
                        MethodSignature <string> signature = method.DecodeSignature(provider, genericMethodContext);
                        Assert.True(signature.Header.Kind == SignatureKind.Method);

                        if (methodName.StartsWith("Generic"))
                        {
                            Assert.Equal(1, signature.GenericParameterCount);
                        }
                        else
                        {
                            Assert.Equal(0, signature.GenericParameterCount);
                        }

                        Assert.True(signature.GenericParameterCount <= 1 && (methodName != "GenericMethodParameter" || signature.GenericParameterCount == 1));
                        Assert.Equal(expected, provider.GetFunctionPointerType(signature));
                    }

                    Dictionary <string, string> expectedProperties = GetExpectedPropertySignatures();
                    foreach (var propertyHandle in type.GetProperties())
                    {
                        PropertyDefinition property     = reader.GetPropertyDefinition(propertyHandle);
                        string             propertyName = reader.GetString(property.Name);
                        string             expected;
                        Assert.True(expectedProperties.TryGetValue(propertyName, out expected), "Unexpected property: " + propertyName);
                        MethodSignature <string> signature = property.DecodeSignature(provider, genericTypeContext);
                        Assert.True(signature.Header.Kind == SignatureKind.Property);
                        Assert.Equal(expected, provider.GetFunctionPointerType(signature));
                    }

                    Dictionary <string, string> expectedEvents = GetExpectedEventSignatures();
                    foreach (var eventHandle in type.GetEvents())
                    {
                        EventDefinition @event    = reader.GetEventDefinition(eventHandle);
                        string          eventName = reader.GetString(@event.Name);
                        string          expected;
                        Assert.True(expectedEvents.TryGetValue(eventName, out expected), "Unexpected event: " + eventName);

                        Assert.Equal(expected, provider.GetTypeFromHandle(reader, genericTypeContext, @event.Type));
                    }

                    Assert.Equal($"[{CollectionsAssemblyName}]System.Collections.Generic.List`1<!T>", provider.GetTypeFromHandle(reader, genericTypeContext, handle: type.BaseType));
                }
        }
예제 #53
0
        //private static void GetMethodFields(string name, IPersistentMap overloads, Dictionary<string, FieldBuilder> varMap, out FieldBuilder overloadFB, out FieldBuilder regularFB)
        //{
        //    if ( overloads.containsKey(name) )
        //}
        static List<MethodSignature> GetAllSignatures(Type superClass, List<Type> interfaces, ISeq methods)
        {
            HashSet<MethodSignature> considered = new HashSet<MethodSignature>();
            List<MethodSignature> todo = new List<MethodSignature>();

            GetAllMethods(superClass,considered,todo,"super");
            foreach( Type t in interfaces)
                GetAllMethods(t,considered,todo,"interface");

            for (ISeq s = methods; s != null; s = s.next())
            {
                IPersistentVector v = (IPersistentVector)s.first();
                // v == [name [paramTypes...] returnType]
                string name = ((Symbol)v.nth(0)).Name;
                Type[] paramTypes = CreateTypeArray((ISeq)v.nth(1));
                Type returnType = (Type)v.nth(2);
                bool isStatic = RT.booleanCast(v.nth(3));
                MethodSignature sig = new MethodSignature(name, paramTypes, returnType, isStatic, "other");
                if ( ! considered.Contains(sig) )
                    todo.Add(sig);
                considered.Add(sig);
            }
            return todo;
        }
예제 #54
0
        //Single Entry point for CarFast
        //TODO: support other parameter types
        private void generateSingleEntry()
        {
            program += "\npublic static void singleEntry(";

            StringBuilder param = new StringBuilder();

            for (int i = 0; i < ProgGenUtil.maxNoOfParameters; i++)
            {
                param.Append("int i" + i + ",");
            }

            string st = param.ToString();

            st  = st.Substring(0, st.Length - 1);
            st += "){\n";

            program += st;


            program += this.fileName + " obj = new " + this.fileName + "();\n";
            foreach (Method method in this.methodList)
            {
                HashSet <int?> set     = new HashSet <int?>();
                StringBuilder  builder = new StringBuilder();

                MethodSignature signature = method.MethodSignature;
                if (!signature.Static)
                {
                    builder.Append("obj.");
                }

                builder.Append(signature.Name + "(");

                foreach (Variable variable in signature.ParameterList)
                {
                    Type type = variable.Type;
                    if (type.getType() == Type.Primitives.OBJECT)
                    {
                        builder.Append("new " + type.ToString() + "()");
                        builder.Append(",");
                    }
                    else
                    {
                        if (variable.Name.Equals("recursionCounter"))
                        {
                            builder.Append((new Random()).Next(ProgGenUtil.maxRecursionDepth));
                        }
                        else
                        {
                            if (type.getType() != Type.Primitives.INT)
                            {
                                builder.Append(new Literal(type.getType()));
                            }
                            else
                            {
                                bool addedToSet = false;
                                do
                                {
                                    int @var = (new Random()).Next(ProgGenUtil.maxNoOfParameters);
                                    addedToSet = set.Add(@var);
                                    if (addedToSet)
                                    {
                                        builder.Append("i" + @var);
                                    }
                                }while (!addedToSet);
                            }
                        }
                        builder.Append(",");
                    }
                }
                string str = builder.ToString();
                str  = str.Substring(0, str.Length - 1);
                str += ");\n";

                program += str;
            }
            program += "}\n";
        }
예제 #55
0
 public void __SetCallingConvention(CallingConventions callingConvention)
 {
     this.callingConvention = callingConvention;
     this.methodSignature   = null;
 }
예제 #56
0
 public DynamicInvokeMethodSignature(MethodSignature concreteSignature)
 {
     Debug.Assert(DynamicInvokeMethodThunk.SupportsSignature(concreteSignature));
     _signature = concreteSignature;
 }
 // We'll never get function pointer types in any types we care about, so we can
 // just return the empty string.  Similarly, as we never construct generics,
 // there is no need to provide anything for the generic parameter names.
 public EntityHandle GetFunctionPointerType(MethodSignature <EntityHandle> signature) => default;
예제 #58
0
        public override MethodIL EmitIL()
        {
            ILEmitter    emitter                   = new ILEmitter();
            ILCodeStream argSetupStream            = emitter.NewCodeStream();
            ILCodeStream thisCallSiteSetupStream   = emitter.NewCodeStream();
            ILCodeStream staticCallSiteSetupStream = emitter.NewCodeStream();
            ILCodeStream returnCodeStream          = emitter.NewCodeStream();

            // This function will look like
            //
            // !For each parameter to the method
            //    !if (parameter is In Parameter)
            //       localX is TypeOfParameterX&
            //       ldarg.2
            //       ldtoken TypeOfParameterX
            //       call DynamicInvokeParamHelperIn(ref ArgSetupState, RuntimeTypeHandle)
            //       stloc localX
            //    !else
            //       localX is TypeOfParameter
            //       ldarg.2
            //       ldtoken TypeOfParameterX
            //       call DynamicInvokeParamHelperRef(ref ArgSetupState, RuntimeTypeHandle)
            //       stloc localX

            // ldarg.2
            // call DynamicInvokeArgSetupComplete(ref ArgSetupState)

            // *** Thiscall instruction stream starts here ***

            // ldarg.3 // Load targetIsThisCall
            // brfalse Not_this_call

            // ldarg.0 // Load this pointer
            // !For each parameter
            //    !if (parameter is In Parameter)
            //       ldloc localX
            //       ldobj TypeOfParameterX
            //    !else
            //       ldloc localX
            // ldarg.1
            // calli ReturnType thiscall(TypeOfParameter1, ...)
            // br Process_return

            // *** Static call instruction stream starts here ***

            // Not_this_call:
            // !For each parameter
            //    !if (parameter is In Parameter)
            //       ldloc localX
            //       ldobj TypeOfParameterX
            //    !else
            //       ldloc localX
            // ldarg.1
            // calli ReturnType (TypeOfParameter1, ...)

            // *** Return code stream starts here ***

            // Process_return:
            // !if (ReturnType is Byref)
            //    dup
            //    brfalse ByRefNull
            //    ldobj ReturnType
            // !if ((ReturnType == void)
            //    ldnull
            // !elif (ReturnType is pointer)
            //    System.Reflection.Pointer.Box(ReturnType)
            // !else
            //    box ReturnType
            // ret
            //
            // !if (ReturnType is ByRef)
            //   ByRefNull:
            //   throw NullReferenceException

            ILCodeLabel lStaticCall    = emitter.NewCodeLabel();
            ILCodeLabel lProcessReturn = emitter.NewCodeLabel();

            thisCallSiteSetupStream.EmitLdArg(3); // targetIsThisCall
            thisCallSiteSetupStream.Emit(ILOpcode.brfalse, lStaticCall);
            staticCallSiteSetupStream.EmitLabel(lStaticCall);

            thisCallSiteSetupStream.EmitLdArg(0); // thisPtr

            ILToken tokDynamicInvokeParamHelperRef =
                emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeParamHelperRef", null));
            ILToken tokDynamicInvokeParamHelperIn =
                emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeParamHelperIn", null));

            TypeDesc[] targetMethodSignature = new TypeDesc[_targetSignature.Length];

            for (int paramIndex = 0; paramIndex < _targetSignature.Length; paramIndex++)
            {
                TypeDesc paramType = Context.GetSignatureVariable(paramIndex, true);
                DynamicInvokeMethodParameterKind paramKind = _targetSignature[paramIndex];

                for (int i = 0; i < _targetSignature.GetNumberOfParameterPointerIndirections(paramIndex); i++)
                {
                    paramType = paramType.MakePointerType();
                }

                ILToken         tokParamType = emitter.NewToken(paramType);
                ILLocalVariable local        = emitter.NewLocal(paramType.MakeByRefType());

                thisCallSiteSetupStream.EmitLdLoc(local);
                staticCallSiteSetupStream.EmitLdLoc(local);

                argSetupStream.EmitLdArg(2); // argSetupState
                argSetupStream.Emit(ILOpcode.ldtoken, tokParamType);

                if (paramKind == DynamicInvokeMethodParameterKind.Reference)
                {
                    argSetupStream.Emit(ILOpcode.call, tokDynamicInvokeParamHelperRef);

                    targetMethodSignature[paramIndex] = paramType.MakeByRefType();
                }
                else
                {
                    argSetupStream.Emit(ILOpcode.call, tokDynamicInvokeParamHelperIn);

                    thisCallSiteSetupStream.EmitLdInd(paramType);
                    staticCallSiteSetupStream.EmitLdInd(paramType);

                    targetMethodSignature[paramIndex] = paramType;
                }
                argSetupStream.EmitStLoc(local);
            }

            argSetupStream.EmitLdArg(2); // argSetupState
            argSetupStream.Emit(ILOpcode.call, emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeArgSetupComplete", null)));

            thisCallSiteSetupStream.EmitLdArg(1);   // methodToCall
            staticCallSiteSetupStream.EmitLdArg(1); // methodToCall

            DynamicInvokeMethodParameterKind returnKind = _targetSignature.ReturnType;
            TypeDesc returnType = returnKind != DynamicInvokeMethodParameterKind.None ?
                                  Context.GetSignatureVariable(_targetSignature.Length, true) :
                                  Context.GetWellKnownType(WellKnownType.Void);

            for (int i = 0; i < _targetSignature.GetNumerOfReturnTypePointerIndirections(); i++)
            {
                returnType = returnType.MakePointerType();
            }

            if (returnKind == DynamicInvokeMethodParameterKind.Reference)
            {
                returnType = returnType.MakeByRefType();
            }

            MethodSignature thisCallMethodSig = new MethodSignature(0, 0, returnType, targetMethodSignature);

            thisCallSiteSetupStream.Emit(ILOpcode.calli, emitter.NewToken(thisCallMethodSig));
            thisCallSiteSetupStream.Emit(ILOpcode.br, lProcessReturn);

            MethodSignature staticCallMethodSig = new MethodSignature(MethodSignatureFlags.Static, 0, returnType, targetMethodSignature);

            staticCallSiteSetupStream.Emit(ILOpcode.calli, emitter.NewToken(staticCallMethodSig));

            returnCodeStream.EmitLabel(lProcessReturn);

            ILCodeLabel lByRefReturnNull = null;

            if (returnKind == DynamicInvokeMethodParameterKind.None)
            {
                returnCodeStream.Emit(ILOpcode.ldnull);
            }
            else
            {
                TypeDesc returnTypeForBoxing = returnType;

                if (returnType.IsByRef)
                {
                    // If this is a byref return, we need to dereference first
                    returnTypeForBoxing = ((ByRefType)returnType).ParameterType;
                    lByRefReturnNull    = emitter.NewCodeLabel();
                    returnCodeStream.Emit(ILOpcode.dup);
                    returnCodeStream.Emit(ILOpcode.brfalse, lByRefReturnNull);
                    returnCodeStream.EmitLdInd(returnTypeForBoxing);
                }

                if (returnTypeForBoxing.IsPointer)
                {
                    // Pointers box differently
                    returnCodeStream.Emit(ILOpcode.ldtoken, emitter.NewToken(returnTypeForBoxing));
                    MethodDesc getTypeFromHandleMethod =
                        Context.SystemModule.GetKnownType("System", "Type").GetKnownMethod("GetTypeFromHandle", null);
                    returnCodeStream.Emit(ILOpcode.call, emitter.NewToken(getTypeFromHandleMethod));

                    MethodDesc pointerBoxMethod =
                        Context.SystemModule.GetKnownType("System.Reflection", "Pointer").GetKnownMethod("Box", null);
                    returnCodeStream.Emit(ILOpcode.call, emitter.NewToken(pointerBoxMethod));
                }
                else
                {
                    ILToken tokReturnType = emitter.NewToken(returnTypeForBoxing);
                    returnCodeStream.Emit(ILOpcode.box, tokReturnType);
                }
            }

            returnCodeStream.Emit(ILOpcode.ret);

            if (lByRefReturnNull != null)
            {
                returnCodeStream.EmitLabel(lByRefReturnNull);
                MethodDesc nullReferencedExceptionHelper = Context.GetHelperEntryPoint("ThrowHelpers", "ThrowInvokeNullRefReturned");
                returnCodeStream.EmitCallThrowHelper(emitter, nullReferencedExceptionHelper);
            }

            return(emitter.Link(this));
        }
예제 #59
0
 /// <summary>
 /// Checks if at least one Method satisfies a given MethodSignature.
 /// </summary>
 /// <param name="self">The TypeReference on which the extension method can be called.</param>
 /// <param name="signature">The MethodSignature to match.</param>
 /// <returns>True if at least one method matches the signature. Otherwise false.</returns>
 public static bool HasMethod(this TypeReference self, MethodSignature signature)
 {
     return((self != null) && self.GetMethod(signature) != null);
 }
예제 #60
0
        public MutableMethodInfo CreateMethod(
            MutableType declaringType,
            string name,
            MethodAttributes attributes,
            IEnumerable <GenericParameterDeclaration> genericParameters,
            Func <GenericParameterContext, Type> returnTypeProvider,
            Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > parameterProvider,
            Func <MethodBodyCreationContext, Expression> bodyProvider)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNull("genericParameters", genericParameters);
            ArgumentUtility.CheckNotNull("returnTypeProvider", returnTypeProvider);
            ArgumentUtility.CheckNotNull("parameterProvider", parameterProvider);
            // Body provider may be null (for abstract methods).

            // TODO 5478: virtual and static is an invalid combination

            var isAbstract = attributes.IsSet(MethodAttributes.Abstract);

            if (!isAbstract && bodyProvider == null)
            {
                throw new ArgumentNullException("bodyProvider", "Non-abstract methods must have a body.");
            }
            if (isAbstract && bodyProvider != null)
            {
                throw new ArgumentException("Abstract methods cannot have a body.", "bodyProvider");
            }

            MemberAttributesUtility.ValidateAttributes("methods", MemberAttributesUtility.InvalidMethodAttributes, attributes, "attributes");

            var isVirtual = attributes.IsSet(MethodAttributes.Virtual);
            var isNewSlot = attributes.IsSet(MethodAttributes.NewSlot);

            if (isAbstract && !isVirtual)
            {
                throw new ArgumentException("Abstract methods must also be virtual.", "attributes");
            }
            if (!isVirtual && isNewSlot)
            {
                throw new ArgumentException("NewSlot methods must also be virtual.", "attributes");
            }

            var methodItems = GetMethodSignatureItems(declaringType, genericParameters, returnTypeProvider, parameterProvider);

            var signature = new MethodSignature(
                methodItems.ReturnType,
                methodItems.ParameterDeclarations.Select(pd => pd.Type),
                methodItems.GenericParameters.Count,
                s_methodSignatureStringBuilderHelper);

            if (declaringType.AddedMethods.Any(m => m.Name == name && MethodSignature.Create(m).Equals(signature)))
            {
                throw new InvalidOperationException("Method with equal name and signature already exists.");
            }

            var baseMethod = GetBaseMethod(declaringType, name, signature, isVirtual, isNewSlot);
            // TODO 5478: if it is an implicit overriddenMethod override, it needs at least the same ore more public visibility

            var body = GetMethodBody(declaringType, attributes, bodyProvider, methodItems, baseMethod);

            return(new MutableMethodInfo(
                       declaringType, name, attributes, methodItems.GenericParameters, methodItems.ReturnType, methodItems.ParameterDeclarations, baseMethod, body));
        }