protected override void EmitMarshalFieldNativeToManaged() { ILEmitter emitter = _ilCodeStreams.Emitter; ILCodeStream codeStream = _ilCodeStreams.UnmarshallingCodestream; codeStream.EmitLdArg(1); codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldflda, emitter.NewToken(_nativeField)); codeStream.Emit(ILOpcode.conv_u); EmitElementCount(codeStream, MarshalDirection.Reverse); codeStream.Emit(ILOpcode.call, emitter.NewToken(GetNativeToManagedHelper())); codeStream.Emit(ILOpcode.stfld, emitter.NewToken(_managedField)); }
//TODO: https://github.com/dotnet/corert/issues/2675 // This exception messages need to localized // TODO: Log as warning public static MethodIL EmitExceptionBody(string message, MethodDesc method) { ILEmitter emitter = new ILEmitter(); TypeSystemContext context = method.Context; MethodSignature ctorSignature = new MethodSignature(0, 0, context.GetWellKnownType(WellKnownType.Void), new TypeDesc[] { context.GetWellKnownType(WellKnownType.String) }); MethodDesc exceptionCtor = method.Context.GetWellKnownType(WellKnownType.Exception).GetKnownMethod(".ctor", ctorSignature); ILCodeStream codeStream = emitter.NewCodeStream(); codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(message)); codeStream.Emit(ILOpcode.newobj, emitter.NewToken(exceptionCtor)); codeStream.Emit(ILOpcode.throw_); return(new PInvokeILStubMethodIL((ILStubMethodIL)emitter.Link(method), isStubRequired: true)); }
protected override void EmitMarshalArgumentManagedToNative() { ILCodeStream marshallingCodeStream = _ilCodeStreams.MarshallingCodeStream; ILEmitter emitter = _ilCodeStreams.Emitter; var arrayType = (ArrayType)ManagedParameterType; Debug.Assert(arrayType.IsSzArray); IL.Stubs.ILLocalVariable vPinnedFirstElement = emitter.NewLocal(arrayType.ParameterType.MakeByRefType(), true); IL.Stubs.ILLocalVariable vArray = emitter.NewLocal(arrayType); ILCodeLabel lNullArray = emitter.NewCodeLabel(); // Check for null array, or 0 element array. marshallingCodeStream.Emit(ILOpcode.dup); marshallingCodeStream.EmitStLoc(vArray); marshallingCodeStream.Emit(ILOpcode.brfalse, lNullArray); marshallingCodeStream.EmitLdLoc(vArray); marshallingCodeStream.Emit(ILOpcode.ldlen); marshallingCodeStream.Emit(ILOpcode.conv_i4); marshallingCodeStream.Emit(ILOpcode.brfalse, lNullArray); // Array has elements. marshallingCodeStream.EmitLdLoc(vArray); marshallingCodeStream.EmitLdc(0); marshallingCodeStream.Emit(ILOpcode.ldelema, emitter.NewToken(arrayType.ElementType)); marshallingCodeStream.EmitStLoc(vPinnedFirstElement); // Fall through. If array didn't have elements, vPinnedFirstElement is zeroinit. marshallingCodeStream.EmitLabel(lNullArray); marshallingCodeStream.EmitLdLoc(vPinnedFirstElement); marshallingCodeStream.Emit(ILOpcode.conv_i); NativeParameterType = PInvokeMethodData.Context.GetWellKnownType(WellKnownType.IntPtr); }
protected override void TransformNativeToManaged(ILCodeStream codeStream) { string helperMethodName = _isAnsi ? "AnsiStringToStringBuilder" : "UnicodeStringToStringBuilder"; var helper = Context.GetHelperEntryPoint("InteropHelpers", helperMethodName); LoadNativeValue(codeStream); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken(helper)); }
protected override void TransformNativeToManaged(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; var helper = Context.GetHelperEntryPoint("InteropHelpers", "AnsiCharToWideChar"); LoadNativeValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreManagedValue(codeStream); }
public override MethodIL EmitIL() { if (_owningType.BoxedValue == null) { // If this is the fake unboxing thunk for ByRef-like types, just make a method that throws. return(new ILStubMethodIL(this, new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ }, Array.Empty <LocalVariableDefinition>(), Array.Empty <object>())); } // Generate the unboxing stub. This loosely corresponds to following C#: // return BoxedValue.InstanceMethod(this.m_pEEType, [rest of parameters]) ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); FieldDesc eeTypeField = Context.GetWellKnownType(WellKnownType.Object).GetKnownField("m_pEEType"); FieldDesc boxedValueField = _owningType.BoxedValue.InstantiateAsOpen(); // Load ByRef to the field with the value of the boxed valuetype codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldflda, emit.NewToken(boxedValueField)); // Load the EEType of the boxed valuetype (this is the hidden generic context parameter expected // by the (canonical) instance method, but normally not part of the signature in IL). codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emit.NewToken(eeTypeField)); // Load rest of the arguments for (int i = 0; i < _targetMethod.Signature.Length; i++) { codeStream.EmitLdArg(i + 1); } // Call an instance method on the target valuetype that has a fake instantiation parameter // in it's signature. This will be swapped by the actual instance method after codegen is done. codeStream.Emit(ILOpcode.call, emit.NewToken(_nakedTargetMethod.InstantiateAsOpen())); codeStream.Emit(ILOpcode.ret); return(emit.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()); } 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()); } return(null); }
public override MethodIL EmitIL() { ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); codeStream.MarkDebuggerStepThroughPoint(); for (int i = 0; i < Signature.Length; i++) { codeStream.EmitLdArg(i); } codeStream.MarkDebuggerStepInPoint(); codeStream.Emit(ILOpcode.call, emit.NewToken(WrappedMethod)); codeStream.Emit(ILOpcode.ret); return(emit.Link(this)); }
public override MethodIL EmitIL() { ILEmitter emitter = new ILEmitter(); ILCodeStream codeStream = emitter.NewCodeStream(); MetadataType appContextType = Context.SystemModule.GetKnownType("System", "AppContext"); MethodDesc setSwitchMethod = appContextType.GetKnownMethod("SetSwitch", null); ILToken setSwitchToken = emitter.NewToken(setSwitchMethod); foreach (string switchName in _switches) { codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(switchName)); codeStream.EmitLdc(1); codeStream.Emit(ILOpcode.call, setSwitchToken); } codeStream.Emit(ILOpcode.ret); return(emitter.Link(this)); }
protected override void TransformNativeToManaged(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; LoadNativeValue(codeStream); MethodDesc helper = Context.GetHelperEntryPoint("InteropHelpers", "ConvertNativeComInterfaceToManaged"); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreManagedValue(codeStream); }
protected override void AllocManagedToNative(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; var helper = Context.GetHelperEntryPoint("InteropHelpers", "AllocMemoryForAnsiCharArray"); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreNativeValue(codeStream); }
protected override TypeDesc MarshalArgument(TypeDesc managedType, ILEmitter emitter, ILCodeStream marshallingCodeStream, ILCodeStream unmarshallingCodeStream) { var byRefType = (ByRefType)managedType; IL.Stubs.ILLocalVariable vPinnedByRef = emitter.NewLocal(byRefType, true); marshallingCodeStream.EmitStLoc(vPinnedByRef); marshallingCodeStream.EmitLdLoc(vPinnedByRef); marshallingCodeStream.Emit(ILOpcode.conv_i); return(PInvokeMethodData.Context.GetWellKnownType(WellKnownType.IntPtr)); }
public override MethodIL EmitIL() { ILEmitter emitter = new ILEmitter(); ILCodeStream codeStream = emitter.NewCodeStream(); MetadataType appContextType = Context.SystemModule.GetKnownType("System", "AppContext"); MethodDesc setDataMethod = appContextType.GetKnownMethod("SetData", null); ILToken setDataToken = emitter.NewToken(setDataMethod); foreach (KeyValuePair <string, string> keyValue in _switches) { codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(keyValue.Key)); codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(keyValue.Value)); codeStream.Emit(ILOpcode.call, setDataToken); } codeStream.Emit(ILOpcode.ret); return(emitter.Link(this)); }
protected override void EmitCleanupManaged(ILCodeStream codeStream) { // Only do cleanup if it is IN if (!In) { return; } ILEmitter emitter = _ilCodeStreams.Emitter; ILCodeLabel lNull = emitter.NewCodeLabel(); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.brfalse, lNull); LoadNativeValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken( InteropStateManager.GetStructMarshallingCleanupThunk(ManagedType))); codeStream.EmitLabel(lNull); }
public override MethodIL EmitIL() { // Generate the instantiating stub. This loosely corresponds to following C#: // return Interface.Method(this, GetOrdinalInterface(this.m_pEEType, Index), [rest of parameters]) ILEmitter emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); FieldDesc eeTypeField = Context.GetWellKnownType(WellKnownType.Object).GetKnownField("m_pEEType"); MethodDesc getOrdinalInterfaceMethod = Context.GetHelperEntryPoint("SharedCodeHelpers", "GetOrdinalInterface"); MethodDesc getCurrentContext = Context.GetHelperEntryPoint("SharedCodeHelpers", "GetCurrentSharedThunkContext"); // Load "this" codeStream.EmitLdArg(0); // Load the instantiating argument. if (_interfaceIndex == UseContextFromRuntime) { codeStream.Emit(ILOpcode.call, emit.NewToken(getCurrentContext)); } else { codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emit.NewToken(eeTypeField)); codeStream.EmitLdc(_interfaceIndex); codeStream.Emit(ILOpcode.call, emit.NewToken(getOrdinalInterfaceMethod)); } // Load rest of the arguments for (int i = 0; i < _targetMethod.Signature.Length; i++) { codeStream.EmitLdArg(i + 1); } // Call an instance method on the target interface that has a fake instantiation parameter // in it's signature. This will be swapped by the actual instance method after codegen is done. codeStream.Emit(ILOpcode.call, emit.NewToken(_nakedTargetMethod)); codeStream.Emit(ILOpcode.ret); return(emit.Link(this)); }
protected override void EmitElementCount(ILCodeStream codeStream, MarshalDirection direction) { ILEmitter emitter = _ilCodeStreams.Emitter; if (MarshalAsDescriptor == null || !MarshalAsDescriptor.SizeConst.HasValue) { throw new InvalidProgramException("SizeConst is required for ByValArray."); } if (direction == MarshalDirection.Forward) { // In forward direction ElementCount = Min(managed.length, SizeConst); var vLength = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32)); var lSmaller = emitter.NewCodeLabel(); var lDone = emitter.NewCodeLabel(); codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField)); var lNullCheck = emitter.NewCodeLabel(); codeStream.Emit(ILOpcode.brfalse, lNullCheck); codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField)); codeStream.Emit(ILOpcode.ldlen); codeStream.Emit(ILOpcode.conv_i4); codeStream.EmitStLoc(vLength); codeStream.EmitLabel(lNullCheck); Debug.Assert(MarshalAsDescriptor.SizeConst.HasValue); int sizeConst = (int)MarshalAsDescriptor.SizeConst.Value; codeStream.EmitLdc(sizeConst); codeStream.EmitLdLoc(vLength); codeStream.Emit(ILOpcode.blt, lSmaller); codeStream.EmitLdLoc(vLength); codeStream.Emit(ILOpcode.br, lDone); codeStream.EmitLabel(lSmaller); codeStream.EmitLdc(sizeConst); codeStream.EmitLabel(lDone); } else { // In reverse direction ElementCount = SizeConst; Debug.Assert(MarshalAsDescriptor.SizeConst.HasValue); int sizeConst = (int)MarshalAsDescriptor.SizeConst.Value; codeStream.EmitLdc(sizeConst); } }
protected override void EmitCleanupManaged(ILCodeStream codeStream) { // Only do cleanup if it is IN if (!In) { return; } ILEmitter emitter = _ilCodeStreams.Emitter; ILCodeLabel lNull = emitter.NewCodeLabel(); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.brfalse, lNull); LoadNativeValue(codeStream); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken( Context.GetHelperEntryPoint("InteropHelpers", "AsAnyCleanupNative"))); codeStream.EmitLabel(lNull); }
protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; var helper = Context.GetHelperEntryPoint("InteropHelpers", "ConvertManagedComInterfaceToNative"); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreNativeValue(codeStream); }
protected override void EmitCleanupManaged(ILCodeStream codeStream) { // Only do cleanup if it is IN if (!In) { return; } LoadNativeAddr(codeStream); codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken( InteropStateManager.GetStructMarshallingCleanupThunk(ManagedType))); }
protected override void TransformManagedToNative(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; LoadManagedValue(codeStream); var helper = InteropTypes.GetMarshal(Context).GetKnownMethod("StringToBSTR", null); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreNativeValue(codeStream); }
protected override void AllocManagedToNative(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; string helperMethodName = _isAnsi ? "AllocMemoryForAnsiStringBuilder" : "AllocMemoryForUnicodeStringBuilder"; var helper = Context.GetHelperEntryPoint("InteropHelpers", helperMethodName); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreNativeValue(codeStream); }
protected override void TransformManagedToNative(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; LoadManagedValue(codeStream); var helper = Context.GetHelperEntryPoint("InteropHelpers", "DecimalToOleCurrency"); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreNativeValue(codeStream); }
public override MethodIL EmitIL() { ILEmitter emitter = new ILEmitter(); ILCodeStream codeStream = emitter.NewCodeStream(); MetadataType startup = Context.GetHelperType("StartupCodeHelpers"); // Initialize command line args string initArgsName = (Context.Target.OperatingSystem == TargetOS.Windows) ? "InitializeCommandLineArgsW" : "InitializeCommandLineArgs"; MethodDesc initArgs = startup.GetKnownMethod(initArgsName, null); codeStream.Emit(ILOpcode.ldarg_0); // argc codeStream.Emit(ILOpcode.ldarg_1); // argv codeStream.Emit(ILOpcode.call, emitter.NewToken(initArgs)); // Call program Main if (_mainMethod.Signature.Length > 0) { codeStream.Emit(ILOpcode.call, emitter.NewToken(startup.GetKnownMethod("GetMainMethodArguments", null))); } codeStream.Emit(ILOpcode.call, emitter.NewToken(_mainMethod)); if (_mainMethod.Signature.ReturnType.IsVoid) { codeStream.EmitLdc(0); } codeStream.Emit(ILOpcode.ret); return emitter.Link(this); }
protected override void EmitMarshalFieldManagedToNative() { ILEmitter emitter = _ilCodeStreams.Emitter; ILCodeStream codeStream = _ilCodeStreams.MarshallingCodeStream; var nativeArrayType = NativeType as InlineArrayType; Debug.Assert(nativeArrayType != null); codeStream.EmitLdArg(0); codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(_managedField)); codeStream.EmitLdArg(1); codeStream.Emit(ILOpcode.ldflda, emitter.NewToken(_nativeField)); codeStream.Emit(ILOpcode.conv_u); EmitElementCount(codeStream, MarshalDirection.Forward); if (IsAnsi) { codeStream.Emit(PInvokeFlags.BestFitMapping ? ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0); codeStream.Emit(PInvokeFlags.ThrowOnUnmappableChar ? ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0); } codeStream.Emit(ILOpcode.call, emitter.NewToken(GetManagedToNativeHelper())); }
protected virtual void EmitByRefManagedToNative() { ILCodeStream marshallingCodeStream = _ilCodeStreams.MarshallingCodeStream; ILEmitter emitter = _ilCodeStreams.Emitter; var byRefType = (ByRefType)ManagedParameterType; IL.Stubs.ILLocalVariable vPinnedByRef = emitter.NewLocal(byRefType, true); marshallingCodeStream.EmitStLoc(vPinnedByRef); marshallingCodeStream.EmitLdLoc(vPinnedByRef); marshallingCodeStream.Emit(ILOpcode.conv_i); NativeParameterType = PInvokeMethodData.Context.GetWellKnownType(WellKnownType.IntPtr); }
protected override void AllocManagedToNative(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; ILCodeLabel lNull = emitter.NewCodeLabel(); codeStream.EmitLdc(0); codeStream.Emit(ILOpcode.conv_i); StoreNativeValue(codeStream); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.brfalse, lNull); TypeDesc nativeStructType = InteropStateManager.GetStructMarshallingNativeType(ManagedType); ILLocalVariable lNativeType = emitter.NewLocal(nativeStructType); codeStream.EmitLdLoca(lNativeType); codeStream.Emit(ILOpcode.initobj, emitter.NewToken(nativeStructType)); codeStream.EmitLdLoca(lNativeType); StoreNativeValue(codeStream); codeStream.EmitLabel(lNull); }
protected override void AllocNativeToManaged(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; MethodDesc ctor = ManagedType.GetParameterlessConstructor(); if (ctor == null) { throw new InvalidProgramException(); } codeStream.Emit(ILOpcode.newobj, emitter.NewToken(ctor)); StoreManagedValue(codeStream); }
/// <summary> /// Generates IL for the IsSupported property that reads this information from a field initialized by the runtime /// at startup. Only works for intrinsics that the code generator can generate detection code for. /// </summary> public static MethodIL EmitIsSupportedIL(MethodDesc method, FieldDesc isSupportedField) { Debug.Assert(IsIsSupportedMethod(method)); Debug.Assert(isSupportedField.IsStatic && isSupportedField.FieldType.IsWellKnownType(WellKnownType.Int32)); string id = InstructionSetSupport.GetHardwareIntrinsicId(method.Context.Target.Architecture, method.OwningType); Debug.Assert(method.Context.Target.Architecture == TargetArchitecture.X64 || method.Context.Target.Architecture == TargetArchitecture.X86); int flag = XArchIntrinsicConstants.FromHardwareIntrinsicId(id); var emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); codeStream.Emit(ILOpcode.ldsfld, emit.NewToken(isSupportedField)); codeStream.EmitLdc(flag); codeStream.Emit(ILOpcode.and); codeStream.EmitLdc(0); codeStream.Emit(ILOpcode.cgt_un); codeStream.Emit(ILOpcode.ret); return(emit.Link(method)); }
protected override void TransformNativeToManaged(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; ILCodeLabel lNonNull = emitter.NewCodeLabel(); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.brtrue, lNonNull); MethodDesc ctor = ManagedType.GetParameterlessConstructor(); if (ctor == null) { throw new InvalidProgramException(); } codeStream.Emit(ILOpcode.newobj, emitter.NewToken(ctor)); StoreManagedValue(codeStream); codeStream.EmitLabel(lNonNull); LoadNativeAddr(codeStream); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken( InteropStateManager.GetStructMarshallingNativeToManagedThunk(ManagedType))); }
protected override void TransformNativeToManaged(ILCodeStream codeStream) { var lMarshaller = InitializeMarshallerVariable(); var customMarshallerType = Context.SystemModule.GetKnownType("System.Runtime.InteropServices", "ICustomMarshaler"); ILEmitter emitter = _ilCodeStreams.Emitter; var marshalNativeToManagedMethod = customMarshallerType.GetKnownMethod( "MarshalNativeToManaged", new MethodSignature(MethodSignatureFlags.None, 0, Context.GetWellKnownType(WellKnownType.Object), new[] { Context.GetWellKnownType(WellKnownType.IntPtr) })); codeStream.EmitLdLoc(lMarshaller); LoadNativeValue(codeStream); codeStream.Emit(ILOpcode.callvirt, emitter.NewToken(marshalNativeToManagedMethod)); StoreManagedValue(codeStream); }