Пример #1
0
        public override MethodIL GetMethodIL(MethodDesc method)
        {
            if (method is EcmaMethod ecmaMethod)
            {
                if (method.IsIntrinsic)
                {
                    MethodIL result = TryGetIntrinsicMethodIL(method);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                // Check to see if there is an override for the EcmaMethodIL. If there is not
                // then simply return the EcmaMethodIL. In theory this could call
                // CreateCrossModuleInlineableTokensForILBody, but we explicitly do not want
                // to do that. The reason is that this method is called during the multithreaded
                // portion of compilation, and CreateCrossModuleInlineableTokensForILBody
                // will produce tokens which are order dependent thus violating the determinism
                // principles of the compiler.
                if (!_manifestModuleWrappedMethods.TryGetValue(ecmaMethod, out var methodIL))
                {
                    methodIL = EcmaMethodIL.Create(ecmaMethod);
                }

                if (methodIL != null)
                {
                    return(methodIL);
                }

                return(null);
            }
            else if (method is MethodForInstantiatedType || method is InstantiatedMethod)
            {
                // Intrinsics specialized per instantiation
                if (method.IsIntrinsic)
                {
                    MethodIL methodIL = TryGetPerInstantiationIntrinsicMethodIL(method);
                    if (methodIL != null)
                    {
                        return(methodIL);
                    }
                }

                var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition());
                if (methodDefinitionIL == null)
                {
                    return(null);
                }
                return(new InstantiatedMethodIL(method, methodDefinitionIL));
            }
            else
            {
                return(null);
            }
        }
Пример #2
0
        // Create the cross module inlineable tokens for a method
        // This method is order dependent, and must be called during the single threaded portion of compilation
        public void CreateCrossModuleInlineableTokensForILBody(EcmaMethod method)
        {
            Debug.Assert(_manifestMutableModule != null);
            Debug.Assert(!_compilationModuleGroup.VersionsWithMethodBody(method) &&
                         _compilationModuleGroup.CrossModuleInlineable(method));
            var wrappedMethodIL = new ManifestModuleWrappedMethodIL();

            if (!wrappedMethodIL.Initialize(_manifestMutableModule, EcmaMethodIL.Create(method)))
            {
                // If we could not initialize the wrapped method IL, we should store a null.
                // That will result in the IL code for the method being unavailable for use in
                // the compilation, which is version safe.
                wrappedMethodIL = null;
            }
            _manifestModuleWrappedMethods.Add(method, wrappedMethodIL);
            IncrementVersion();
        }
Пример #3
0
        public override MethodIL GetMethodIL(MethodDesc method)
        {
            if (method is EcmaMethod ecmaMethod)
            {
                if (method.IsIntrinsic)
                {
                    MethodIL result = TryGetIntrinsicMethodIL(method);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                MethodIL methodIL = EcmaMethodIL.Create(ecmaMethod);
                if (methodIL != null)
                {
                    return(methodIL);
                }

                return(null);
            }
            else if (method is MethodForInstantiatedType || method is InstantiatedMethod)
            {
                // Intrinsics specialized per instantiation
                if (method.IsIntrinsic)
                {
                    MethodIL methodIL = TryGetPerInstantiationIntrinsicMethodIL(method);
                    if (methodIL != null)
                    {
                        return(methodIL);
                    }
                }

                var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition());
                if (methodDefinitionIL == null)
                {
                    return(null);
                }
                return(new InstantiatedMethodIL(method, methodDefinitionIL));
            }
            else
            {
                return(null);
            }
        }
Пример #4
0
        public override MethodIL GetMethodIL(MethodDesc method)
        {
            if (method is EcmaMethod ecmaMethod)
            {
                // TODO: Workaround: we should special case methods with Intrinsic attribute, but since
                //       CoreLib source is still not in the repo, we have to work with what we have, which is
                //       an MCG attribute on the type itself...
                if (((MetadataType)ecmaMethod.OwningType).HasCustomAttribute("System.Runtime.InteropServices", "McgIntrinsicsAttribute"))
                {
                    var name = ecmaMethod.Name;
                    if (name == "Call" || name.StartsWith("StdCall"))
                    {
                        return(CalliIntrinsic.EmitIL(ecmaMethod));
                    }
                    else
                    if (name == "AddrOf")
                    {
                        return(AddrOfIntrinsic.EmitIL(ecmaMethod));
                    }
                }

                if (ecmaMethod.IsIntrinsic)
                {
                    MethodIL result = TryGetIntrinsicMethodIL(ecmaMethod);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                if (ecmaMethod.IsRuntimeImplemented)
                {
                    MethodIL result = TryGetRuntimeImplementedMethodIL(ecmaMethod);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                // TODO: Remove: Workaround for missing ClearInitLocals transforms in CoreRT CoreLib
                bool clearInitLocals = ecmaMethod.Module == ecmaMethod.Context.SystemModule;

                MethodIL methodIL = EcmaMethodIL.Create(ecmaMethod, clearInitLocals);
                if (methodIL != null)
                {
                    return(methodIL);
                }

                return(null);
            }
            else
            if (method is MethodForInstantiatedType || method is InstantiatedMethod)
            {
                // Intrinsics specialized per instantiation
                if (method.IsIntrinsic)
                {
                    MethodIL methodIL = TryGetPerInstantiationIntrinsicMethodIL(method);
                    if (methodIL != null)
                    {
                        return(methodIL);
                    }
                }

                var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition());
                if (methodDefinitionIL == null)
                {
                    return(null);
                }
                return(new InstantiatedMethodIL(method, methodDefinitionIL));
            }
            else
            if (method is ILStubMethod)
            {
                return(((ILStubMethod)method).EmitIL());
            }
            else
            if (method is ArrayMethod)
            {
                return(ArrayMethodILEmitter.EmitIL((ArrayMethod)method));
            }
            else
            {
                Debug.Assert(!(method is PInvokeTargetNativeMethod), "Who is asking for IL of PInvokeTargetNativeMethod?");
                return(null);
            }
        }
Пример #5
0
        private MethodIL CreateMethodIL(MethodDesc method)
        {
            if (method is EcmaMethod)
            {
                // TODO: Workaround: we should special case methods with Intrinsic attribute, but since
                //       CoreLib source is still not in the repo, we have to work with what we have, which is
                //       an MCG attribute on the type itself...
                if (((MetadataType)method.OwningType).HasCustomAttribute("System.Runtime.InteropServices", "McgIntrinsicsAttribute"))
                {
                    var name = method.Name;
                    if (name == "Call")
                    {
                        return(CalliIntrinsic.EmitIL(method));
                    }
                    else
                    if (name == "AddrOf")
                    {
                        return(AddrOfIntrinsic.EmitIL(method));
                    }
                }

                if (method.IsIntrinsic)
                {
                    MethodIL result = TryGetIntrinsicMethodIL(method);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                if (method.IsPInvoke)
                {
                    var pregenerated = McgInteropSupport.TryGetPregeneratedPInvoke(method);
                    if (pregenerated == null)
                    {
                        return(PInvokeILEmitter.EmitIL(method));
                    }
                    method = pregenerated;
                }

                if (method.IsRuntimeImplemented)
                {
                    MethodIL result = TryGetRuntimeImplementedMethodIL(method);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                MethodIL methodIL = EcmaMethodIL.Create((EcmaMethod)method);
                if (methodIL != null)
                {
                    return(methodIL);
                }

                if (!method.IsInternalCall && !method.IsRuntimeImplemented)
                {
                    return(MissingMethodBodyILEmitter.EmitIL(method));
                }

                return(null);
            }
            else
            if (method is MethodForInstantiatedType || method is InstantiatedMethod)
            {
                if (method.IsIntrinsic && method.Name == "CreateInstanceIntrinsic")
                {
                    // CreateInstanceIntrinsic is specialized per instantiation
                    return(CreateInstanceIntrinsic.EmitIL(method));
                }

                var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition());
                if (methodDefinitionIL == null)
                {
                    return(null);
                }
                return(new InstantiatedMethodIL(method, methodDefinitionIL, method.OwningType.Instantiation, method.Instantiation));
            }
            else
            if (method is ILStubMethod)
            {
                return(((ILStubMethod)method).EmitIL());
            }
            else
            if (method is ArrayMethod)
            {
                return(ArrayMethodILEmitter.EmitIL((ArrayMethod)method));
            }
            else
            {
                Debug.Assert(!(method is PInvokeTargetNativeMethod), "Who is asking for IL of PInvokeTargetNativeMethod?");
                return(null);
            }
        }
Пример #6
0
        private MethodIL CreateMethodIL(MethodDesc method)
        {
            if (method is EcmaMethod)
            {
                // TODO: Workaround: we should special case methods with Intrinsic attribute, but since
                //       CoreLib source is still not in the repo, we have to work with what we have, which is
                //       an MCG attribute on the type itself...
                if (((MetadataType)method.OwningType).HasCustomAttribute("System.Runtime.InteropServices", "McgIntrinsicsAttribute"))
                {
                    var name = method.Name;
                    if (name == "Call")
                    {
                        return(CalliIntrinsic.EmitIL(method));
                    }
                    else
                    if (name == "AddrOf")
                    {
                        return(AddrOfIntrinsic.EmitIL(method));
                    }
                }

                if (method.IsIntrinsic)
                {
                    MethodIL result = TryGetIntrinsicMethodIL(method);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                if (method.IsPInvoke)
                {
                    var pregenerated = McgInteropSupport.TryGetPregeneratedPInvoke(method);
                    if (pregenerated == null)
                    {
                        return(PInvokeMarshallingILEmitter.EmitIL(method));
                    }
                    method = pregenerated;
                }

                return(EcmaMethodIL.Create((EcmaMethod)method));
            }
            else
            if (method is MethodForInstantiatedType)
            {
                var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition());
                if (methodDefinitionIL == null)
                {
                    return(null);
                }
                return(new InstantiatedMethodIL(methodDefinitionIL, method.OwningType.Instantiation, new Instantiation()));
            }
            else
            if (method is InstantiatedMethod)
            {
                var methodDefinitionIL = GetMethodIL(method.GetMethodDefinition());
                if (methodDefinitionIL == null)
                {
                    return(null);
                }
                return(new InstantiatedMethodIL(methodDefinitionIL, new Instantiation(), method.Instantiation));
            }
            else
            if (method is ILStubMethod)
            {
                return(((ILStubMethod)method).EmitIL());
            }
            else
            if (method is ArrayMethod)
            {
                return(ArrayMethodILEmitter.EmitIL((ArrayMethod)method));
            }
            else
            {
                return(null);
            }
        }
Пример #7
0
        public override MethodIL GetMethodIL(MethodDesc method)
        {
            if (method is EcmaMethod ecmaMethod)
            {
                if (ecmaMethod.IsIntrinsic)
                {
                    MethodIL result = TryGetIntrinsicMethodIL(ecmaMethod);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                if (ecmaMethod.IsRuntimeImplemented)
                {
                    MethodIL result = TryGetRuntimeImplementedMethodIL(ecmaMethod);
                    if (result != null)
                    {
                        return(result);
                    }
                }

                MethodIL methodIL = EcmaMethodIL.Create(ecmaMethod);
                if (methodIL != null)
                {
                    return(methodIL);
                }

                return(null);
            }
            else
            if (method is MethodForInstantiatedType || method is InstantiatedMethod)
            {
                // Intrinsics specialized per instantiation
                if (method.IsIntrinsic)
                {
                    MethodIL methodIL = TryGetPerInstantiationIntrinsicMethodIL(method);
                    if (methodIL != null)
                    {
                        return(methodIL);
                    }
                }

                var methodDefinitionIL = GetMethodIL(method.GetTypicalMethodDefinition());
                if (methodDefinitionIL == null)
                {
                    return(null);
                }
                return(new InstantiatedMethodIL(method, methodDefinitionIL));
            }
            else
            if (method is ILStubMethod)
            {
                return(((ILStubMethod)method).EmitIL());
            }
            else
            if (method is ArrayMethod)
            {
                return(ArrayMethodILEmitter.EmitIL((ArrayMethod)method));
            }
            else
            {
                Debug.Assert(!(method is PInvokeTargetNativeMethod), "Who is asking for IL of PInvokeTargetNativeMethod?");
                return(null);
            }
        }
Пример #8
0
            public bool Initialize(MutableModule mutableModule, EcmaMethodIL wrappedMethod)
            {
                bool failedToReplaceToken = false;

                try
                {
                    Debug.Assert(mutableModule.ModuleThatIsCurrentlyTheSourceOfNewReferences == null);
                    mutableModule.ModuleThatIsCurrentlyTheSourceOfNewReferences = ((EcmaMethod)wrappedMethod.OwningMethod).Module;
                    var owningMethodHandle = mutableModule.TryGetEntityHandle(wrappedMethod.OwningMethod);
                    if (!owningMethodHandle.HasValue)
                    {
                        return(false);
                    }
                    _mutableModule    = mutableModule;
                    _maxStack         = wrappedMethod.MaxStack;
                    _isInitLocals     = wrappedMethod.IsInitLocals;
                    _owningMethod     = wrappedMethod.OwningMethod;
                    _exceptionRegions = (ILExceptionRegion[])wrappedMethod.GetExceptionRegions().Clone();
                    _ilBytes          = (byte[])wrappedMethod.GetILBytes().Clone();
                    _locals           = (LocalVariableDefinition[])wrappedMethod.GetLocals();

                    for (int i = 0; i < _exceptionRegions.Length; i++)
                    {
                        var region = _exceptionRegions[i];
                        if (region.Kind == ILExceptionRegionKind.Catch)
                        {
                            var newHandle = _mutableModule.TryGetHandle((TypeSystemEntity)wrappedMethod.GetObject(region.ClassToken));
                            if (!newHandle.HasValue)
                            {
                                return(false);
                            }
                            _exceptionRegions[i] = new ILExceptionRegion(region.Kind, region.TryOffset, region.TryLength, region.HandlerOffset, region.HandlerLength, newHandle.Value, newHandle.Value);
                        }
                    }

                    ILTokenReplacer.Replace(_ilBytes, GetMutableModuleToken);
#if DEBUG
                    Debug.Assert(ReadyToRunStandaloneMethodMetadata.Compute((EcmaMethod)_owningMethod) != null);
#endif // DEBUG
                }
                finally
                {
                    mutableModule.ModuleThatIsCurrentlyTheSourceOfNewReferences = null;
                }


                return(!failedToReplaceToken);

                int GetMutableModuleToken(int token)
                {
                    object result = wrappedMethod.GetObject(token);
                    int?   newToken;

                    if (result is string str)
                    {
                        newToken = mutableModule.TryGetStringHandle(str);
                    }
                    else
                    {
                        newToken = mutableModule.TryGetHandle((TypeSystemEntity)result);
                    }
                    if (!newToken.HasValue)
                    {
                        // Toekn replacement has failed. Do not attempt to use this IL.
                        failedToReplaceToken = true;
                        return(1);
                    }
                    return(newToken.Value);
                }
            }