public static MethodIL EmitIL(MethodDesc method) { ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); MethodDesc typeLoadExceptionHelper = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowTypeLoadException"); codeStream.EmitCallThrowHelper(emit, typeLoadExceptionHelper); return(emit.Link()); }
public override MethodIL EmitIL() { var emitter = new ILEmitter(); ILCodeStream codeStream = emitter.NewCodeStream(); MetadataType throwHelpersType = Context.SystemModule.GetKnownType("Internal.Runtime.CompilerHelpers", "ThrowHelpers"); MethodDesc throwHelper = throwHelpersType.GetKnownMethod("ThrowNotSupportedException", null); codeStream.EmitCallThrowHelper(emitter, throwHelper); return(emitter.Link(this)); }
public static MethodIL EmitIL(MethodDesc method) { Debug.Assert(method.OwningType.IsDelegate); Debug.Assert(method.IsRuntimeImplemented); if (method.Name == "BeginInvoke" || method.Name == "EndInvoke") { // BeginInvoke and EndInvoke are not supported on .NET Core ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); MethodDesc notSupportedExceptionHelper = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException"); codeStream.EmitCallThrowHelper(emit, notSupportedExceptionHelper); return(emit.Link(method)); } if (method.Name == ".ctor") { TypeSystemContext context = method.Context; ILEmitter emit = new ILEmitter(); TypeDesc delegateType = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; MethodDesc objectCtorMethod = context.GetWellKnownType(WellKnownType.Object).GetDefaultConstructor(); FieldDesc functionPointerField = delegateType.GetKnownField("m_functionPointer"); FieldDesc firstParameterField = delegateType.GetKnownField("m_firstParameter"); ILCodeStream codeStream = emit.NewCodeStream(); codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.call, emit.NewToken(objectCtorMethod)); codeStream.EmitLdArg(0); codeStream.EmitLdArg(1); codeStream.Emit(ILOpcode.stfld, emit.NewToken(firstParameterField)); codeStream.EmitLdArg(0); codeStream.EmitLdArg(2); codeStream.Emit(ILOpcode.stfld, emit.NewToken(functionPointerField)); codeStream.Emit(ILOpcode.ret); return(emit.Link(method)); } return(null); }
public static MethodIL EmitIL(MethodDesc method) { Debug.Assert(method.OwningType.IsDelegate); Debug.Assert(method.IsRuntimeImplemented); if (method.Name == "BeginInvoke" || method.Name == "EndInvoke") { // BeginInvoke and EndInvoke are not supported on .NET Core ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); MethodDesc notSupportedExceptionHelper = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException"); codeStream.EmitCallThrowHelper(emit, notSupportedExceptionHelper); return(emit.Link(method)); } if (method.Name == ".ctor") { // TODO: this should be an assert that codegen never asks for this. // This is just a workaround for https://github.com/dotnet/corert/issues/2102 // The code below is making a wild guess that we're creating a closed // instance delegate. Without shared generics, this should only happen // for virtual method (so we're fine there). With shared generics, this can // happen for anything and might be pretty wrong. TypeSystemContext context = method.Context; ILEmitter emit = new ILEmitter(); TypeDesc delegateType = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; MethodDesc initializeMethod = delegateType.GetKnownMethod("InitializeClosedInstanceSlow", null); ILCodeStream codeStream = emit.NewCodeStream(); codeStream.EmitLdArg(0); codeStream.EmitLdArg(1); codeStream.EmitLdArg(2); codeStream.Emit(ILOpcode.call, emit.NewToken(initializeMethod)); codeStream.Emit(ILOpcode.ret); return(emit.Link(method)); } return(null); }
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)); }
public static MethodIL EmitIL(MethodDesc method) { Debug.Assert(method.OwningType.IsDelegate); Debug.Assert(method.OwningType.IsTypeDefinition); Debug.Assert(method.IsRuntimeImplemented); if (method.Name == "BeginInvoke" || method.Name == "EndInvoke") { // BeginInvoke and EndInvoke are not supported on .NET Core ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); MethodDesc notSupportedExceptionHelper = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException"); codeStream.EmitCallThrowHelper(emit, notSupportedExceptionHelper); return(emit.Link(method)); } if (method.Name == ".ctor") { // We only support delegate creation if the IL follows the delegate creation verifiability requirements // described in ECMA-335 III.4.21 (newobj - create a new object). The codegen is expected to // intrinsically expand the pattern. // If the delegate creation doesn't follow the pattern, we generate code that throws at runtime. // We could potentially implement this (unreliably) through the use of reflection metadata, // but it remains to be proven that this is an actual customer scenario. ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); MethodDesc notSupportedExceptionHelper = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException"); codeStream.EmitCallThrowHelper(emit, notSupportedExceptionHelper); return(emit.Link(method)); } if (method.Name == "Invoke") { TypeSystemContext context = method.Context; ILEmitter emit = new ILEmitter(); TypeDesc delegateType = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; FieldDesc firstParameterField = delegateType.GetKnownField("m_firstParameter"); FieldDesc functionPointerField = delegateType.GetKnownField("m_functionPointer"); ILCodeStream codeStream = emit.NewCodeStream(); codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emit.NewToken(firstParameterField.InstantiateAsOpen())); for (int i = 0; i < method.Signature.Length; i++) { codeStream.EmitLdArg(i + 1); } codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emit.NewToken(functionPointerField.InstantiateAsOpen())); MethodSignature signature = method.Signature; if (method.OwningType.HasInstantiation) { // If the owning type is generic, the signature will contain T's and U's. // We need !0's and !1's. TypeDesc[] typesToReplace = new TypeDesc[method.OwningType.Instantiation.Length]; TypeDesc[] replacementTypes = new TypeDesc[typesToReplace.Length]; for (int i = 0; i < typesToReplace.Length; i++) { typesToReplace[i] = method.OwningType.Instantiation[i]; replacementTypes[i] = context.GetSignatureVariable(i, method: false); } TypeDesc[] parameters = new TypeDesc[method.Signature.Length]; for (int i = 0; i < parameters.Length; i++) { parameters[i] = method.Signature[i].ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes); } TypeDesc returnType = method.Signature.ReturnType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes); signature = new MethodSignature(signature.Flags, signature.GenericParameterCount, returnType, parameters); } codeStream.Emit(ILOpcode.calli, emit.NewToken(signature)); codeStream.Emit(ILOpcode.ret); return(emit.Link(method)); } return(null); }
public static MethodIL EmitIL(MethodDesc method) { Debug.Assert(method.OwningType.IsDelegate); Debug.Assert(method.OwningType.IsTypeDefinition); Debug.Assert(method.IsRuntimeImplemented); if (method.Name == "BeginInvoke" || method.Name == "EndInvoke") { // BeginInvoke and EndInvoke are not supported on .NET Core ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); MethodDesc notSupportedExceptionHelper = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException"); codeStream.EmitCallThrowHelper(emit, notSupportedExceptionHelper); return(emit.Link(method)); } if (method.Name == ".ctor") { // TODO: this should be an assert that codegen never asks for this. // This is just a workaround for https://github.com/dotnet/corert/issues/2102 // The code below is making a wild guess that we're creating a closed // instance delegate. Without shared generics, this should only happen // for virtual method (so we're fine there). With shared generics, this can // happen for anything and might be pretty wrong. TypeSystemContext context = method.Context; ILEmitter emit = new ILEmitter(); TypeDesc delegateType = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; MethodDesc initializeMethod = delegateType.GetKnownMethod("InitializeClosedInstanceSlow", null); ILCodeStream codeStream = emit.NewCodeStream(); codeStream.EmitLdArg(0); codeStream.EmitLdArg(1); codeStream.EmitLdArg(2); codeStream.Emit(ILOpcode.call, emit.NewToken(initializeMethod)); codeStream.Emit(ILOpcode.ret); return(emit.Link(method)); } if (method.Name == "Invoke") { TypeSystemContext context = method.Context; ILEmitter emit = new ILEmitter(); TypeDesc delegateType = context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType; FieldDesc firstParameterField = delegateType.GetKnownField("m_firstParameter"); FieldDesc functionPointerField = delegateType.GetKnownField("m_functionPointer"); ILCodeStream codeStream = emit.NewCodeStream(); codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emit.NewToken(firstParameterField.InstantiateAsOpen())); for (int i = 0; i < method.Signature.Length; i++) { codeStream.EmitLdArg(i + 1); } codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emit.NewToken(functionPointerField.InstantiateAsOpen())); MethodSignature signature = method.Signature; if (method.OwningType.HasInstantiation) { // If the owning type is generic, the signature will contain T's and U's. // We need !0's and !1's. TypeDesc[] typesToReplace = new TypeDesc[method.OwningType.Instantiation.Length]; TypeDesc[] replacementTypes = new TypeDesc[typesToReplace.Length]; for (int i = 0; i < typesToReplace.Length; i++) { typesToReplace[i] = method.OwningType.Instantiation[i]; replacementTypes[i] = context.GetSignatureVariable(i, method: false); } TypeDesc[] parameters = new TypeDesc[method.Signature.Length]; for (int i = 0; i < parameters.Length; i++) { parameters[i] = method.Signature[i].ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes); } TypeDesc returnType = method.Signature.ReturnType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes); signature = new MethodSignature(signature.Flags, signature.GenericParameterCount, returnType, parameters); } codeStream.Emit(ILOpcode.calli, emit.NewToken(signature)); codeStream.Emit(ILOpcode.ret); return(emit.Link(method)); } return(null); }