internal static void TryArrayToWCharPtrConversion(ILGenerator method, LocalOrArg argIndex, Type argumentType, Label done) { Label nextTry = method.DefineLabel(); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("TryCheckWCharArray")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } }
MarshalCleanup INativeType.EmitMarshalling(ILGenerator /*!*/ method, LocalOrArg argIndex, List <object> /*!*/ constantPool, int constantPoolArgument) { Type argumentType = argIndex.Type; argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod(nameof(ModuleOps.CheckCDataType))); method.Emit(OpCodes.Call, typeof(CData).GetProperty(nameof(CData.UnsafeAddress)).GetGetMethod()); method.Emit(OpCodes.Ldobj, ((INativeType)this).GetNativeType()); return(null); }
internal static void TryToCharPtrConversion(ILGenerator method, LocalOrArg argIndex, Type argumentType, Label done) { TryBytesConversion(method, done); Label nextTry = method.DefineLabel(); argIndex.Emit(method); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod(nameof(ModuleOps.TryCheckCharArray))); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetProperty(nameof(CData.UnsafeAddress)).GetGetMethod()); method.Emit(OpCodes.Br, done); method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } }
internal static void MarshalWCharPointer(ILGenerator method, LocalOrArg argIndex) { Type argumentType = argIndex.Type; Label isNull; Label done; isNull = method.DefineLabel(); done = method.DefineLabel(); method.Emit(OpCodes.Brfalse, isNull); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } if (StringGetPinnableReference is null) { LocalBuilder lb = method.DeclareLocal(typeof(string), true); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); method.Emit(OpCodes.Conv_I); #pragma warning disable CS0618 // Type or member is obsolete method.Emit(OpCodes.Ldc_I4, RuntimeHelpers.OffsetToStringData); #pragma warning restore CS0618 // Type or member is obsolete method.Emit(OpCodes.Add); } else { method.Emit(OpCodes.Call, StringGetPinnableReference); } method.Emit(OpCodes.Br, done); method.MarkLabel(isNull); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_I); method.MarkLabel(done); }
private static void EmitInt32ToObject(ILGenerator method, LocalOrArg value) { Label intVal, done; intVal = method.DefineLabel(); done = method.DefineLabel(); method.Emit(OpCodes.Ldc_I4, Int32.MaxValue); method.Emit(value.Type == typeof(uint) ? OpCodes.Conv_U4 : OpCodes.Conv_U8); method.Emit(OpCodes.Ble, intVal); value.Emit(method); method.Emit(OpCodes.Call, typeof(BigInteger).GetMethod("op_Implicit", new[] { value.Type })); method.Emit(OpCodes.Box, typeof(BigInteger)); method.Emit(OpCodes.Br, done); method.MarkLabel(intVal); value.Emit(method); method.Emit(OpCodes.Conv_I4); method.Emit(OpCodes.Box, typeof(int)); method.MarkLabel(done); }
MarshalCleanup INativeType.EmitMarshalling(ILGenerator /*!*/ method, LocalOrArg argIndex, List <object> /*!*/ constantPool, int constantPoolArgument) { MarshalCleanup cleanup = null; Label marshalled = method.DefineLabel(); Type argumentType = argIndex.Type; if (!argumentType.IsValueType && _type != SimpleTypeKind.Object && _type != SimpleTypeKind.Pointer) { // check if we have an explicit CData instance. If we have a CData but it's the // wrong type CheckSimpleCDataType will throw. Label primitive = method.DefineLabel(); argIndex.Emit(method); constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckSimpleCDataType")); method.Emit(OpCodes.Brfalse, primitive); argIndex.Emit(method); method.Emit(OpCodes.Castclass, typeof(CData)); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Ldobj, ((INativeType)this).GetNativeType()); method.Emit(OpCodes.Br, marshalled); method.MarkLabel(primitive); } argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } switch (_type) { case SimpleTypeKind.Boolean: case SimpleTypeKind.Char: case SimpleTypeKind.SignedByte: case SimpleTypeKind.UnsignedByte: case SimpleTypeKind.SignedShort: case SimpleTypeKind.UnsignedShort: case SimpleTypeKind.WChar: case SimpleTypeKind.SignedInt: case SimpleTypeKind.UnsignedInt: case SimpleTypeKind.UnsignedLong: case SimpleTypeKind.SignedLong: case SimpleTypeKind.Single: case SimpleTypeKind.Double: case SimpleTypeKind.UnsignedLongLong: case SimpleTypeKind.SignedLongLong: case SimpleTypeKind.VariantBool: constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("Get" + _type)); break; case SimpleTypeKind.Pointer: Label done = method.DefineLabel(); TryBytesConversion(method, done); Label nextTry = method.DefineLabel(); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Isinst, typeof(string)); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); LocalBuilder lb = method.DeclareLocal(typeof(string), true); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Ldc_I4, RuntimeHelpers.OffsetToStringData); method.Emit(OpCodes.Add); method.Emit(OpCodes.Br, done); method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("GetPointer")); method.MarkLabel(done); break; case SimpleTypeKind.Object: // TODO: Need cleanup here method.Emit(OpCodes.Call, typeof(CTypes).GetMethod("PyObj_ToPtr")); break; case SimpleTypeKind.CharPointer: done = method.DefineLabel(); TryToCharPtrConversion(method, argIndex, argumentType, done); cleanup = MarshalCharPointer(method, argIndex); method.MarkLabel(done); break; case SimpleTypeKind.WCharPointer: done = method.DefineLabel(); TryArrayToWCharPtrConversion(method, argIndex, argumentType, done); MarshalWCharPointer(method, argIndex); method.MarkLabel(done); break; } method.MarkLabel(marshalled); return(cleanup); }
private static void EmitInt32ToObject(ILGenerator method, LocalOrArg value) { Label intVal, done; intVal = method.DefineLabel(); done = method.DefineLabel(); method.Emit(OpCodes.Ldc_I4, Int32.MaxValue); method.Emit(value.Type == typeof(uint) ? OpCodes.Conv_U4 : OpCodes.Conv_U8); method.Emit(OpCodes.Ble, intVal); value.Emit(method); method.Emit(OpCodes.Call, typeof(BigInteger).GetMethod("op_Implicit", new[] { value.Type })); #if !CLR2 method.Emit(OpCodes.Box, typeof(BigInteger)); #endif method.Emit(OpCodes.Br, done); method.MarkLabel(intVal); value.Emit(method); method.Emit(OpCodes.Conv_I4); method.Emit(OpCodes.Box, typeof(int)); method.MarkLabel(done); }
void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List <object> constantPool, int constantPoolArgument) { // TODO: Implement me value.Emit(method); }
void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List<object> constantPool, int constantPoolArgument) { value.Emit(method); EmitCDataCreation(this, method, constantPool, constantPoolArgument); }
void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List<object> constantPool, int constantPoolArgument) { // TODO: Implement me value.Emit(method); }
internal static void TryToCharPtrConversion(ILGenerator method, LocalOrArg argIndex, Type argumentType, Label done) { TryBytesConversion(method, done); Label nextTry = method.DefineLabel(); argIndex.Emit(method); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("TryCheckCharArray")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } }
MarshalCleanup INativeType.EmitMarshalling(ILGenerator/*!*/ method, LocalOrArg argIndex, List<object>/*!*/ constantPool, int constantPoolArgument) { MarshalCleanup cleanup = null; Label marshalled = method.DefineLabel(); Type argumentType = argIndex.Type; if (!argumentType.IsValueType && _type != SimpleTypeKind.Object && _type != SimpleTypeKind.Pointer) { // check if we have an explicit CData instance. If we have a CData but it's the // wrong type CheckSimpleCDataType will throw. Label primitive = method.DefineLabel(); argIndex.Emit(method); constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckSimpleCDataType")); method.Emit(OpCodes.Brfalse, primitive); argIndex.Emit(method); method.Emit(OpCodes.Castclass, typeof(CData)); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Ldobj, ((INativeType)this).GetNativeType()); method.Emit(OpCodes.Br, marshalled); method.MarkLabel(primitive); } argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } switch (_type) { case SimpleTypeKind.Boolean: case SimpleTypeKind.Char: case SimpleTypeKind.SignedByte: case SimpleTypeKind.UnsignedByte: case SimpleTypeKind.SignedShort: case SimpleTypeKind.UnsignedShort: case SimpleTypeKind.WChar: case SimpleTypeKind.SignedInt: case SimpleTypeKind.UnsignedInt: case SimpleTypeKind.UnsignedLong: case SimpleTypeKind.SignedLong: case SimpleTypeKind.Single: case SimpleTypeKind.Double: case SimpleTypeKind.UnsignedLongLong: case SimpleTypeKind.SignedLongLong: case SimpleTypeKind.VariantBool: constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("Get" + _type)); break; case SimpleTypeKind.Pointer: Label done = method.DefineLabel(); TryBytesConversion(method, done); Label nextTry = method.DefineLabel(); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Isinst, typeof(string)); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); LocalBuilder lb = method.DeclareLocal(typeof(string), true); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Ldc_I4, RuntimeHelpers.OffsetToStringData); method.Emit(OpCodes.Add); method.Emit(OpCodes.Br, done); method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("GetPointer")); method.MarkLabel(done); break; case SimpleTypeKind.Object: // TODO: Need cleanup here method.Emit(OpCodes.Call, typeof(CTypes).GetMethod("PyObj_ToPtr")); break; case SimpleTypeKind.CharPointer: done = method.DefineLabel(); TryToCharPtrConversion(method, argIndex, argumentType, done); cleanup = MarshalCharPointer(method, argIndex); method.MarkLabel(done); break; case SimpleTypeKind.WCharPointer: done = method.DefineLabel(); TryArrayToWCharPtrConversion(method, argIndex, argumentType, done); MarshalWCharPointer(method, argIndex); method.MarkLabel(done); break; } method.MarkLabel(marshalled); return cleanup; }
void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List<object> constantPool, int constantPoolArgument) { value.Emit(method); switch (_type) { case SimpleTypeKind.SignedByte: case SimpleTypeKind.UnsignedByte: case SimpleTypeKind.SignedShort: case SimpleTypeKind.UnsignedShort: method.Emit(OpCodes.Conv_I4); break; case SimpleTypeKind.SignedInt: case SimpleTypeKind.SignedLong: case SimpleTypeKind.Boolean: break; case SimpleTypeKind.Single: method.Emit(OpCodes.Conv_R8); break; case SimpleTypeKind.Double: break; case SimpleTypeKind.UnsignedLongLong: case SimpleTypeKind.UnsignedInt: case SimpleTypeKind.UnsignedLong: EmtInt32ToObject(method, value); break; case SimpleTypeKind.SignedLongLong: EmitInt64ToObject(method, value); break; case SimpleTypeKind.Object: break; case SimpleTypeKind.WCharPointer: method.Emit(OpCodes.Call, typeof(Marshal).GetMethod("PtrToStringUni", new[] { typeof(IntPtr) })); break; case SimpleTypeKind.CharPointer: method.Emit(OpCodes.Call, typeof(Marshal).GetMethod("PtrToStringAnsi", new[] { typeof(IntPtr) })); break; case SimpleTypeKind.Char: method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CharToString")); break; case SimpleTypeKind.WChar: method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("WCharToString")); break; case SimpleTypeKind.Pointer: if (IntPtr.Size == 4) { LocalBuilder tmpLocal = method.DeclareLocal(typeof(uint)); method.Emit(OpCodes.Conv_U4); method.Emit(OpCodes.Stloc, tmpLocal); method.Emit(OpCodes.Ldloc, tmpLocal); EmtInt32ToObject(method, new Local(tmpLocal)); } else { LocalBuilder tmpLocal = method.DeclareLocal(typeof(long)); method.Emit(OpCodes.Conv_I8); method.Emit(OpCodes.Stloc, tmpLocal); method.Emit(OpCodes.Ldloc, tmpLocal); EmtInt32ToObject(method, new Local(tmpLocal)); } break; } }
MarshalCleanup INativeType.EmitMarshalling(ILGenerator/*!*/ method, LocalOrArg argIndex, List<object>/*!*/ constantPool, int constantPoolArgument) { Type argumentType = argIndex.Type; Label nextTry = method.DefineLabel(); Label done = method.DefineLabel(); if (!argumentType.IsValueType) { argIndex.Emit(method); method.Emit(OpCodes.Ldnull); method.Emit(OpCodes.Bne_Un, nextTry); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Br, done); } method.MarkLabel(nextTry); nextTry = method.DefineLabel(); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } constantPool.Add(this); SimpleType st = _type as SimpleType; MarshalCleanup res = null; if (st != null && !argIndex.Type.IsValueType) { if (st._type == SimpleTypeKind.Char || st._type == SimpleTypeKind.WChar) { if (st._type == SimpleTypeKind.Char) { SimpleType.TryToCharPtrConversion(method, argIndex, argumentType, done); } else { SimpleType.TryArrayToWCharPtrConversion(method, argIndex, argumentType, done); } Label notStr = method.DefineLabel(); LocalOrArg str = argIndex; if (argumentType != typeof(string)) { LocalBuilder lb = method.DeclareLocal(typeof(string)); method.Emit(OpCodes.Isinst, typeof(string)); method.Emit(OpCodes.Brfalse, notStr); argIndex.Emit(method); method.Emit(OpCodes.Castclass, typeof(string)); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); str = new Local(lb); } if (st._type == SimpleTypeKind.Char) { res = SimpleType.MarshalCharPointer(method, str); } else { SimpleType.MarshalWCharPointer(method, str); } method.Emit(OpCodes.Br, done); method.MarkLabel(notStr); argIndex.Emit(method); } } // native argument being pased (byref) method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckNativeArgument")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); // lone cdata being passed method.MarkLabel(nextTry); nextTry = method.DefineLabel(); method.Emit(OpCodes.Pop); // extra null native arg argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("TryCheckCDataPointerType")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); // pointer object being passed method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); // extra null cdata argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckCDataType")); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Ldind_I); method.MarkLabel(done); return res; }
MarshalCleanup INativeType.EmitMarshalling(ILGenerator/*!*/ method, LocalOrArg argIndex, List<object>/*!*/ constantPool, int constantPoolArgument) { Type argumentType = argIndex.Type; argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } // native argument being pased (byref) Label nextTry = method.DefineLabel(); Label done = method.DefineLabel(); constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckNativeArgument")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); // lone cdata being passed method.MarkLabel(nextTry); nextTry = method.DefineLabel(); method.Emit(OpCodes.Pop); // extra null native arg argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("TryCheckCDataPointerType")); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); // pointer object being passed method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); // extra null cdata argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckCDataType")); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Ldobj, typeof(IntPtr)); method.MarkLabel(done); return null; }
void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List <object> constantPool, int constantPoolArgument) { value.Emit(method); switch (_type) { case SimpleTypeKind.SignedByte: case SimpleTypeKind.UnsignedByte: case SimpleTypeKind.SignedShort: case SimpleTypeKind.UnsignedShort: case SimpleTypeKind.VariantBool: method.Emit(OpCodes.Conv_I4); break; case SimpleTypeKind.SignedInt: case SimpleTypeKind.SignedLong: case SimpleTypeKind.Boolean: break; case SimpleTypeKind.Single: method.Emit(OpCodes.Conv_R8); break; case SimpleTypeKind.Double: break; case SimpleTypeKind.UnsignedInt: case SimpleTypeKind.UnsignedLong: EmitInt32ToObject(method, value); break; case SimpleTypeKind.UnsignedLongLong: case SimpleTypeKind.SignedLongLong: EmitInt64ToObject(method, value); break; case SimpleTypeKind.Object: method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("IntPtrToObject")); break; case SimpleTypeKind.WCharPointer: method.Emit(OpCodes.Call, typeof(Marshal).GetMethod("PtrToStringUni", new[] { typeof(IntPtr) })); break; case SimpleTypeKind.CharPointer: method.Emit(OpCodes.Call, typeof(Marshal).GetMethod("PtrToStringAnsi", new[] { typeof(IntPtr) })); break; case SimpleTypeKind.Char: method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CharToString")); break; case SimpleTypeKind.WChar: method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("WCharToString")); break; case SimpleTypeKind.Pointer: Label done, notNull; done = method.DefineLabel(); notNull = method.DefineLabel(); if (IntPtr.Size == 4) { LocalBuilder tmpLocal = method.DeclareLocal(typeof(uint)); method.Emit(OpCodes.Conv_U4); method.Emit(OpCodes.Stloc, tmpLocal); method.Emit(OpCodes.Ldloc, tmpLocal); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_U4); method.Emit(OpCodes.Bne_Un, notNull); method.Emit(OpCodes.Ldnull); method.Emit(OpCodes.Br, done); method.MarkLabel(notNull); method.Emit(OpCodes.Ldloc, tmpLocal); EmitInt32ToObject(method, new Local(tmpLocal)); } else { LocalBuilder tmpLocal = method.DeclareLocal(typeof(long)); method.Emit(OpCodes.Conv_I8); method.Emit(OpCodes.Stloc, tmpLocal); method.Emit(OpCodes.Ldloc, tmpLocal); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_U8); method.Emit(OpCodes.Bne_Un, notNull); method.Emit(OpCodes.Ldnull); method.Emit(OpCodes.Br, done); method.MarkLabel(notNull); method.Emit(OpCodes.Ldloc, tmpLocal); EmitInt64ToObject(method, new Local(tmpLocal)); } method.MarkLabel(done); break; } if (IsSubClass) { LocalBuilder tmp = method.DeclareLocal(typeof(object)); if (GetPythonTypeWorker().IsValueType) { method.Emit(OpCodes.Box, GetPythonTypeWorker()); } method.Emit(OpCodes.Stloc, tmp); constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Ldloc, tmp); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CreateSubclassInstance")); } }
MarshalCleanup INativeType.EmitMarshalling(ILGenerator/*!*/ method, LocalOrArg argIndex, List<object>/*!*/ constantPool, int constantPoolArgument) { Type argumentType = argIndex.Type; Label done = method.DefineLabel(); if (!argumentType.IsValueType) { Label next = method.DefineLabel(); argIndex.Emit(method); method.Emit(OpCodes.Ldnull); method.Emit(OpCodes.Bne_Un, next); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Br, done); method.MarkLabel(next); } argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckCDataType")); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.MarkLabel(done); return null; }
internal static void MarshalWCharPointer(ILGenerator method, LocalOrArg argIndex) { Type argumentType = argIndex.Type; Label isNull; Label done; LocalBuilder lb; isNull = method.DefineLabel(); done = method.DefineLabel(); method.Emit(OpCodes.Brfalse, isNull); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } lb = method.DeclareLocal(typeof(string), true); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Ldc_I4, RuntimeHelpers.OffsetToStringData); method.Emit(OpCodes.Add); method.Emit(OpCodes.Br, done); method.MarkLabel(isNull); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_I); method.MarkLabel(done); }
MarshalCleanup INativeType.EmitMarshalling(ILGenerator/*!*/ method, LocalOrArg argIndex, List<object>/*!*/ constantPool, int constantPoolArgument) { Type argumentType = argIndex.Type; argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckCDataType")); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Ldobj, ((INativeType)this).GetNativeType()); return null; }
internal static MarshalCleanup MarshalCharPointer(ILGenerator method, LocalOrArg argIndex) { Type argumentType = argIndex.Type; Label isNull, done; LocalBuilder lb; isNull = method.DefineLabel(); done = method.DefineLabel(); method.Emit(OpCodes.Brfalse, isNull); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } lb = method.DeclareLocal(typeof(IntPtr)); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("StringToHGlobalAnsi")); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); method.Emit(OpCodes.Br, done); method.MarkLabel(isNull); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_I); method.MarkLabel(done); return new StringCleanup(lb); }
MarshalCleanup INativeType.EmitMarshalling(ILGenerator /*!*/ method, LocalOrArg argIndex, List <object> /*!*/ constantPool, int constantPoolArgument) { Type argumentType = argIndex.Type; Label nextTry = method.DefineLabel(); Label done = method.DefineLabel(); if (!argumentType.IsValueType) { argIndex.Emit(method); method.Emit(OpCodes.Ldnull); method.Emit(OpCodes.Bne_Un, nextTry); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Br, done); } method.MarkLabel(nextTry); nextTry = method.DefineLabel(); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } constantPool.Add(this); SimpleType st = _type as SimpleType; MarshalCleanup res = null; if (st != null && !argIndex.Type.IsValueType) { if (st._type == SimpleTypeKind.Char || st._type == SimpleTypeKind.WChar) { if (st._type == SimpleTypeKind.Char) { SimpleType.TryToCharPtrConversion(method, argIndex, argumentType, done); } else { SimpleType.TryArrayToWCharPtrConversion(method, argIndex, argumentType, done); } Label notStr = method.DefineLabel(); LocalOrArg str = argIndex; if (argumentType != typeof(string)) { LocalBuilder lb = method.DeclareLocal(typeof(string)); method.Emit(OpCodes.Isinst, typeof(string)); method.Emit(OpCodes.Brfalse, notStr); argIndex.Emit(method); method.Emit(OpCodes.Castclass, typeof(string)); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); str = new Local(lb); } if (st._type == SimpleTypeKind.Char) { res = SimpleType.MarshalCharPointer(method, str); } else { SimpleType.MarshalWCharPointer(method, str); } method.Emit(OpCodes.Br, done); method.MarkLabel(notStr); argIndex.Emit(method); } } // native argument being pased (byref) method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckNativeArgument")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); // lone cdata being passed method.MarkLabel(nextTry); nextTry = method.DefineLabel(); method.Emit(OpCodes.Pop); // extra null native arg argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("TryCheckCDataPointerType")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); // pointer object being passed method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); // extra null cdata argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckCDataType")); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Ldind_I); method.MarkLabel(done); return(res); }
void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List<object> constantPool, int constantPoolArgument) { value.Emit(method); switch (_type) { case SimpleTypeKind.SignedByte: case SimpleTypeKind.UnsignedByte: case SimpleTypeKind.SignedShort: case SimpleTypeKind.UnsignedShort: case SimpleTypeKind.VariantBool: method.Emit(OpCodes.Conv_I4); break; case SimpleTypeKind.SignedInt: case SimpleTypeKind.SignedLong: case SimpleTypeKind.Boolean: break; case SimpleTypeKind.Single: method.Emit(OpCodes.Conv_R8); break; case SimpleTypeKind.Double: break; case SimpleTypeKind.UnsignedInt: case SimpleTypeKind.UnsignedLong: EmitInt32ToObject(method, value); break; case SimpleTypeKind.UnsignedLongLong: case SimpleTypeKind.SignedLongLong: EmitInt64ToObject(method, value); break; case SimpleTypeKind.Object: method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("IntPtrToObject")); break; case SimpleTypeKind.WCharPointer: method.Emit(OpCodes.Call, typeof(Marshal).GetMethod("PtrToStringUni", new[] { typeof(IntPtr) })); break; case SimpleTypeKind.CharPointer: method.Emit(OpCodes.Call, typeof(Marshal).GetMethod("PtrToStringAnsi", new[] { typeof(IntPtr) })); break; case SimpleTypeKind.Char: method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CharToString")); break; case SimpleTypeKind.WChar: method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("WCharToString")); break; case SimpleTypeKind.Pointer: Label done, notNull; done = method.DefineLabel(); notNull = method.DefineLabel(); if (IntPtr.Size == 4) { LocalBuilder tmpLocal = method.DeclareLocal(typeof(uint)); method.Emit(OpCodes.Conv_U4); method.Emit(OpCodes.Stloc, tmpLocal); method.Emit(OpCodes.Ldloc, tmpLocal); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_U4); method.Emit(OpCodes.Bne_Un, notNull); method.Emit(OpCodes.Ldnull); method.Emit(OpCodes.Br, done); method.MarkLabel(notNull); method.Emit(OpCodes.Ldloc, tmpLocal); EmitInt32ToObject(method, new Local(tmpLocal)); } else { LocalBuilder tmpLocal = method.DeclareLocal(typeof(long)); method.Emit(OpCodes.Conv_I8); method.Emit(OpCodes.Stloc, tmpLocal); method.Emit(OpCodes.Ldloc, tmpLocal); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_U8); method.Emit(OpCodes.Bne_Un, notNull); method.Emit(OpCodes.Ldnull); method.Emit(OpCodes.Br, done); method.MarkLabel(notNull); method.Emit(OpCodes.Ldloc, tmpLocal); EmitInt64ToObject(method, new Local(tmpLocal)); } method.MarkLabel(done); break; } if (IsSubClass) { LocalBuilder tmp = method.DeclareLocal(typeof(object)); if (GetPythonTypeWorker().IsValueType) { method.Emit(OpCodes.Box, GetPythonTypeWorker()); } method.Emit(OpCodes.Stloc, tmp); constantPool.Add(this); method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Ldloc, tmp); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CreateSubclassInstance")); } }
void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List <object> constantPool, int constantPoolArgument) { value.Emit(method); EmitCDataCreation(this, method, constantPool, constantPoolArgument); }
private static void EmitInt64ToObject(ILGenerator method, LocalOrArg value) { Label done; Label bigInt = method.DefineLabel(); done = method.DefineLabel(); method.Emit(OpCodes.Ldc_I4, Int32.MaxValue); method.Emit(OpCodes.Conv_I8); method.Emit(OpCodes.Bgt, bigInt); value.Emit(method); method.Emit(OpCodes.Ldc_I4, Int32.MinValue); method.Emit(OpCodes.Conv_I8); method.Emit(OpCodes.Blt, bigInt); value.Emit(method); method.Emit(OpCodes.Conv_I4); method.Emit(OpCodes.Box, typeof(int)); method.Emit(OpCodes.Br, done); method.MarkLabel(bigInt); value.Emit(method); method.Emit(OpCodes.Call, typeof(BigInteger).GetMethod("op_Implicit", new[] { value.Type })); #if !CLR2 method.Emit(OpCodes.Box, typeof(BigInteger)); #endif method.MarkLabel(done); }