Esempio n. 1
0
            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);
                }
            }
Esempio n. 2
0
            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);
            }
Esempio n. 3
0
            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);
                }
            }
Esempio n. 4
0
            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);
            }
Esempio n. 5
0
            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);
            }
Esempio n. 6
0
            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);
            }
Esempio n. 7
0
            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);
            }
Esempio n. 8
0
 void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List <object> constantPool, int constantPoolArgument)
 {
     // TODO: Implement me
     value.Emit(method);
 }
Esempio n. 9
0
 void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List<object> constantPool, int constantPoolArgument) {
     value.Emit(method);
     EmitCDataCreation(this, method, constantPool, constantPoolArgument);
 }
Esempio n. 10
0
 void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List<object> constantPool, int constantPoolArgument) {
     // TODO: Implement me
     value.Emit(method);
 }
Esempio n. 11
0
            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);
                }
            }
Esempio n. 12
0
            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;
            }
Esempio n. 13
0
 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;
     }
 }
Esempio n. 14
0
            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;
            }
Esempio n. 15
0
            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;
            }
Esempio n. 16
0
            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"));
                }
            }
Esempio n. 17
0
            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;
            }
Esempio n. 18
0
            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);
            }
Esempio n. 19
0
 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;
 }
Esempio n. 20
0
            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);
            }
Esempio n. 21
0
            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);
            }
Esempio n. 22
0
            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"));
                }
            }
Esempio n. 23
0
 void INativeType.EmitReverseMarshalling(ILGenerator method, LocalOrArg value, List <object> constantPool, int constantPoolArgument)
 {
     value.Emit(method);
     EmitCDataCreation(this, method, constantPool, constantPoolArgument);
 }
Esempio n. 24
0
            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);
            }