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); } }
// 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(); }
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); } }
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); } }
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); } }
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); } }
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); } }
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); } }