예제 #1
0
        public void AddWellKnownTypes()
        {
            var stringType = _typeSystemContext.GetWellKnownType(WellKnownType.String);

            if (ContainsType(stringType))
            {
                _rootProvider.AddCompilationRoot(stringType, "String type is always generated");
            }
        }
예제 #2
0
        private void AddWellKnownTypes(IRootingServiceProvider rootProvider)
        {
            var stringType = _typeSystemContext.GetWellKnownType(WellKnownType.String);

            if (ContainsType(stringType))
            {
                rootProvider.AddCompilationRoot(stringType, "String type is always generated");
            }
        }
예제 #3
0
        /// <summary>
        /// Constructs a new instance of <see cref="DelegateCreationInfo"/> set up to construct a delegate of type
        /// '<paramref name="delegateType"/>' pointing to '<paramref name="targetMethod"/>'.
        /// </summary>
        public static DelegateCreationInfo Create(TypeDesc delegateType, MethodDesc targetMethod, NodeFactory factory, bool followVirtualDispatch)
        {
            CompilerTypeSystemContext context = factory.TypeSystemContext;
            DefType systemDelegate            = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType;

            int paramCountTargetMethod = targetMethod.Signature.Length;

            if (!targetMethod.Signature.IsStatic)
            {
                paramCountTargetMethod++;
            }

            DelegateInfo delegateInfo             = context.GetDelegateInfo(delegateType.GetTypeDefinition());
            int          paramCountDelegateClosed = delegateInfo.Signature.Length + 1;
            bool         closed = false;

            if (paramCountDelegateClosed == paramCountTargetMethod)
            {
                closed = true;
            }
            else
            {
                Debug.Assert(paramCountDelegateClosed == paramCountTargetMethod + 1);
            }

            if (targetMethod.Signature.IsStatic)
            {
                MethodDesc invokeThunk;
                MethodDesc initMethod;

                if (!closed)
                {
                    initMethod  = systemDelegate.GetKnownMethod("InitializeOpenStaticThunk", null);
                    invokeThunk = delegateInfo.Thunks[DelegateThunkKind.OpenStaticThunk];
                }
                else
                {
                    // Closed delegate to a static method (i.e. delegate to an extension method that locks the first parameter)
                    invokeThunk = delegateInfo.Thunks[DelegateThunkKind.ClosedStaticThunk];
                    initMethod  = systemDelegate.GetKnownMethod("InitializeClosedStaticThunk", null);
                }

                var instantiatedDelegateType = delegateType as InstantiatedType;
                if (instantiatedDelegateType != null)
                {
                    invokeThunk = context.GetMethodForInstantiatedType(invokeThunk, instantiatedDelegateType);
                }

                return(new DelegateCreationInfo(
                           factory.MethodEntrypoint(initMethod),
                           targetMethod,
                           TargetKind.ExactCallableAddress,
                           factory.MethodEntrypoint(invokeThunk)));
            }
            else
            {
                if (!closed)
                {
                    throw new NotImplementedException("Open instance delegates");
                }

                string     initializeMethodName = "InitializeClosedInstance";
                MethodDesc targetCanonMethod    = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                TargetKind kind;
                if (targetMethod.HasInstantiation)
                {
                    if (followVirtualDispatch && targetMethod.IsVirtual)
                    {
                        initializeMethodName = "InitializeClosedInstanceWithGVMResolution";
                        kind = TargetKind.MethodHandle;
                    }
                    else
                    {
                        if (targetMethod != targetCanonMethod)
                        {
                            // Closed delegates to generic instance methods need to be constructed through a slow helper that
                            // checks for the fat function pointer case (function pointer + instantiation argument in a single
                            // pointer) and injects an invocation thunk to unwrap the fat function pointer as part of
                            // the invocation if necessary.
                            initializeMethodName = "InitializeClosedInstanceSlow";
                        }

                        kind = TargetKind.ExactCallableAddress;
                    }
                }
                else
                {
                    if (followVirtualDispatch && targetMethod.IsVirtual)
                    {
                        if (targetMethod.OwningType.IsInterface)
                        {
                            kind = TargetKind.InterfaceDispatch;
                            initializeMethodName = "InitializeClosedInstanceToInterface";
                        }
                        else
                        {
                            kind         = TargetKind.VTableLookup;
                            targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                        }
                    }
                    else
                    {
                        kind         = TargetKind.CanonicalEntrypoint;
                        targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                    }
                }

                return(new DelegateCreationInfo(
                           factory.MethodEntrypoint(systemDelegate.GetKnownMethod(initializeMethodName, null)),
                           targetMethod,
                           kind));
            }
        }