Пример #1
0
 private static void EmitNullableToReferenceConversion(this ILGenerator il, Type typeFrom)
 {
     Debug.Assert(TypeUtils.IsNullableType(typeFrom));
     // We've got a conversion from nullable to Object, ValueType, Enum, etc.  Just box it so that
     // we get the nullable semantics.
     il.Emit(OpCodes.Box, typeFrom);
 }
Пример #2
0
        internal static void EmitGetValueOrDefault(this ILGenerator il, Type nullableType)
        {
            MethodInfo mi = nullableType.GetMethod("GetValueOrDefault", System.Type.EmptyTypes);

            Debug.Assert(nullableType.IsValueType);
            il.Emit(OpCodes.Call, mi);
        }
Пример #3
0
        internal static void EmitGetValue(this ILGenerator il, Type nullableType)
        {
            MethodInfo mi = nullableType.GetMethod("get_Value", BindingFlags.Instance | BindingFlags.Public);

            Debug.Assert(nullableType.IsValueType);
            il.Emit(OpCodes.Call, mi);
        }
Пример #4
0
        internal static void EmitLoadArg(this ILGenerator il, int index)
        {
            Debug.Assert(index >= 0);

            switch (index)
            {
            case 0:
                il.Emit(OpCodes.Ldarg_0);
                break;

            case 1:
                il.Emit(OpCodes.Ldarg_1);
                break;

            case 2:
                il.Emit(OpCodes.Ldarg_2);
                break;

            case 3:
                il.Emit(OpCodes.Ldarg_3);
                break;

            default:
                if (index <= Byte.MaxValue)
                {
                    il.Emit(OpCodes.Ldarg_S, (byte)index);
                }
                else
                {
                    il.Emit(OpCodes.Ldarg, index);
                }
                break;
            }
        }
Пример #5
0
        /// <summary>
        /// Creates a lambda compiler that will compile to a dynamic method
        /// </summary>
        private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda)
        {
            Type[] parameterTypes = GetParameterTypes(lambda).AddFirst(typeof(Closure));

#if SILVERLIGHT && MICROSOFT_SCRIPTING_CORE
            var method = new DynamicMethod(lambda.Name ?? "lambda_method", lambda.ReturnType, parameterTypes);
#else
            var method = new DynamicMethod(lambda.Name ?? "lambda_method", lambda.ReturnType, parameterTypes, true);
#endif

            _tree   = tree;
            _lambda = lambda;
            _method = method;

#if MICROSOFT_SCRIPTING_CORE || SILVERLIGHT
            _ilg = new OffsetTrackingILGenerator(method.GetILGenerator());
#else
            _ilg = method.GetILGenerator();
#endif

            _hasClosureArgument = true;

            // These are populated by AnalyzeTree/VariableBinder
            _scope          = tree.Scopes[lambda];
            _boundConstants = tree.Constants[lambda];

            InitializeMethod();
        }
Пример #6
0
 internal static void EmitDecimal(this ILGenerator il, decimal value)
 {
     if (Decimal.Truncate(value) == value)
     {
         if (Int32.MinValue <= value && value <= Int32.MaxValue)
         {
             int intValue = Decimal.ToInt32(value);
             il.EmitInt(intValue);
             il.EmitNew(typeof(Decimal).GetConstructor(new Type[] { typeof(int) }));
         }
         else if (Int64.MinValue <= value && value <= Int64.MaxValue)
         {
             long longValue = Decimal.ToInt64(value);
             il.EmitLong(longValue);
             il.EmitNew(typeof(Decimal).GetConstructor(new Type[] { typeof(long) }));
         }
         else
         {
             il.EmitDecimalBits(value);
         }
     }
     else
     {
         il.EmitDecimalBits(value);
     }
 }
Пример #7
0
        internal static void EmitType(this ILGenerator il, Type type)
        {
            ContractUtils.RequiresNotNull(type, "type");

            il.Emit(OpCodes.Ldtoken, type);
            il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
        }
Пример #8
0
        internal static void EmitInt(this ILGenerator il, int value)
        {
            OpCode c;

            switch (value)
            {
            case -1:
                c = OpCodes.Ldc_I4_M1;
                break;

            case 0:
                c = OpCodes.Ldc_I4_0;
                break;

            case 1:
                c = OpCodes.Ldc_I4_1;
                break;

            case 2:
                c = OpCodes.Ldc_I4_2;
                break;

            case 3:
                c = OpCodes.Ldc_I4_3;
                break;

            case 4:
                c = OpCodes.Ldc_I4_4;
                break;

            case 5:
                c = OpCodes.Ldc_I4_5;
                break;

            case 6:
                c = OpCodes.Ldc_I4_6;
                break;

            case 7:
                c = OpCodes.Ldc_I4_7;
                break;

            case 8:
                c = OpCodes.Ldc_I4_8;
                break;

            default:
                if (value >= -128 && value <= 127)
                {
                    il.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
                }
                else
                {
                    il.Emit(OpCodes.Ldc_I4, value);
                }
                return;
            }
            il.Emit(c);
        }
Пример #9
0
 private static void EmitDecimalBits(this ILGenerator il, decimal value)
 {
     int[] bits = Decimal.GetBits(value);
     il.EmitInt(bits[0]);
     il.EmitInt(bits[1]);
     il.EmitInt(bits[2]);
     il.EmitBoolean((bits[3] & 0x80000000) != 0);
     il.EmitByte((byte)(bits[3] >> 16));
     il.EmitNew(typeof(decimal).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(bool), typeof(byte) }));
 }
Пример #10
0
        internal static void EmitNew(this ILGenerator il, Type type, Type[] paramTypes)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(paramTypes, "paramTypes");

            ConstructorInfo ci = type.GetConstructor(paramTypes);

            ContractUtils.Requires(ci != null, "type", Strings.TypeDoesNotHaveConstructorForTheSignature);
            il.EmitNew(ci);
        }
Пример #11
0
 /// <summary>
 /// Creates a lambda compiler for an inlined lambda
 /// </summary>
 private LambdaCompiler(LambdaCompiler parent, LambdaExpression lambda)
 {
     _tree               = parent._tree;
     _lambda             = lambda;
     _method             = parent._method;
     _ilg                = parent._ilg;
     _hasClosureArgument = parent._hasClosureArgument;
     _typeBuilder        = parent._typeBuilder;
     _scope              = _tree.Scopes[lambda];
     _boundConstants     = parent._boundConstants;
 }
Пример #12
0
        //
        // Note: we support emitting more things as IL constants than
        // Linq does
        internal static void EmitConstant(this ILGenerator il, object value, Type type)
        {
            if (value == null)
            {
                // Smarter than the Linq implementation which uses the initobj
                // pattern for all value types (works, but requires a local and
                // more IL)
                il.EmitDefault(type);
                return;
            }

            // Handle the easy cases
            if (il.TryEmitILConstant(value, type))
            {
                return;
            }

            // Check for a few more types that we support emitting as constants
            Type t = value as Type;

            if (t != null && ShouldLdtoken(t))
            {
                il.EmitType(t);
                if (type != typeof(Type))
                {
                    il.Emit(OpCodes.Castclass, type);
                }
                return;
            }

            MethodBase mb = value as MethodBase;

            if (mb != null && ShouldLdtoken(mb))
            {
                il.Emit(OpCodes.Ldtoken, mb);
                Type dt = mb.DeclaringType;
                if (dt != null && dt.IsGenericType)
                {
                    il.Emit(OpCodes.Ldtoken, dt);
                    il.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetMethodFromHandle", new Type[] { typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle) }));
                }
                else
                {
                    il.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetMethodFromHandle", new Type[] { typeof(RuntimeMethodHandle) }));
                }
                if (type != typeof(MethodBase))
                {
                    il.Emit(OpCodes.Castclass, type);
                }
                return;
            }

            throw ContractUtils.Unreachable;
        }
Пример #13
0
 internal static void EmitBoolean(this ILGenerator il, bool value)
 {
     if (value)
     {
         il.Emit(OpCodes.Ldc_I4_1);
     }
     else
     {
         il.Emit(OpCodes.Ldc_I4_0);
     }
 }
Пример #14
0
        internal static void EmitNew(this ILGenerator il, ConstructorInfo ci)
        {
            ContractUtils.RequiresNotNull(ci, "ci");

            if (ci.DeclaringType.ContainsGenericParameters)
            {
                throw Error.IllegalNewGenericParams(ci.DeclaringType);
            }

            il.Emit(OpCodes.Newobj, ci);
        }
Пример #15
0
        internal static void EmitLong(this ILGenerator il, long value)
        {
            il.Emit(OpCodes.Ldc_I8, value);

            //
            // Now, emit convert to give the constant type information.
            //
            // Otherwise, it is treated as unsigned and overflow is not
            // detected if it's used in checked ops.
            //
            il.Emit(OpCodes.Conv_I8);
        }
Пример #16
0
        /// <summary>
        /// Emits a Stelem* instruction for the appropriate type.
        /// </summary>
        internal static void EmitStoreElement(this ILGenerator il, Type type)
        {
            ContractUtils.RequiresNotNull(type, "type");

            if (type.IsEnum)
            {
                il.Emit(OpCodes.Stelem, type);
                return;
            }
            switch (Type.GetTypeCode(type))
            {
            case TypeCode.Boolean:
            case TypeCode.SByte:
            case TypeCode.Byte:
                il.Emit(OpCodes.Stelem_I1);
                break;

            case TypeCode.Char:
            case TypeCode.Int16:
            case TypeCode.UInt16:
                il.Emit(OpCodes.Stelem_I2);
                break;

            case TypeCode.Int32:
            case TypeCode.UInt32:
                il.Emit(OpCodes.Stelem_I4);
                break;

            case TypeCode.Int64:
            case TypeCode.UInt64:
                il.Emit(OpCodes.Stelem_I8);
                break;

            case TypeCode.Single:
                il.Emit(OpCodes.Stelem_R4);
                break;

            case TypeCode.Double:
                il.Emit(OpCodes.Stelem_R8);
                break;

            default:
                if (type.IsValueType)
                {
                    il.Emit(OpCodes.Stelem, type);
                }
                else
                {
                    il.Emit(OpCodes.Stelem_Ref);
                }
                break;
            }
        }
Пример #17
0
        /// <summary>
        /// Emits a Ldind* instruction for the appropriate type
        /// </summary>
        internal static void EmitLoadValueIndirect(this ILGenerator il, Type type)
        {
            ContractUtils.RequiresNotNull(type, "type");

            if (type.IsValueType)
            {
                if (type == typeof(int))
                {
                    il.Emit(OpCodes.Ldind_I4);
                }
                else if (type == typeof(uint))
                {
                    il.Emit(OpCodes.Ldind_U4);
                }
                else if (type == typeof(short))
                {
                    il.Emit(OpCodes.Ldind_I2);
                }
                else if (type == typeof(ushort))
                {
                    il.Emit(OpCodes.Ldind_U2);
                }
                else if (type == typeof(long) || type == typeof(ulong))
                {
                    il.Emit(OpCodes.Ldind_I8);
                }
                else if (type == typeof(char))
                {
                    il.Emit(OpCodes.Ldind_I2);
                }
                else if (type == typeof(bool))
                {
                    il.Emit(OpCodes.Ldind_I1);
                }
                else if (type == typeof(float))
                {
                    il.Emit(OpCodes.Ldind_R4);
                }
                else if (type == typeof(double))
                {
                    il.Emit(OpCodes.Ldind_R8);
                }
                else
                {
                    il.Emit(OpCodes.Ldobj, type);
                }
            }
            else
            {
                il.Emit(OpCodes.Ldind_Ref);
            }
        }
Пример #18
0
        internal static void Emit(this ILGenerator il, OpCode opcode, MethodBase methodBase)
        {
            Debug.Assert(methodBase is MethodInfo || methodBase is ConstructorInfo);

            if (methodBase.MemberType == MemberTypes.Constructor)
            {
                il.Emit(opcode, (ConstructorInfo)methodBase);
            }
            else
            {
                il.Emit(opcode, (MethodInfo)methodBase);
            }
        }
Пример #19
0
        internal static void EmitStoreArg(this ILGenerator il, int index)
        {
            Debug.Assert(index >= 0);

            if (index <= Byte.MaxValue)
            {
                il.Emit(OpCodes.Starg_S, (byte)index);
            }
            else
            {
                il.Emit(OpCodes.Starg, index);
            }
        }
Пример #20
0
        internal static void EmitFieldSet(this ILGenerator il, FieldInfo fi)
        {
            ContractUtils.RequiresNotNull(fi, "fi");

            if (fi.IsStatic)
            {
                il.Emit(OpCodes.Stsfld, fi);
            }
            else
            {
                il.Emit(OpCodes.Stfld, fi);
            }
        }
Пример #21
0
 private static void EmitNullableToNonNullableConversion(this ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
 {
     Debug.Assert(TypeUtils.IsNullableType(typeFrom));
     Debug.Assert(!TypeUtils.IsNullableType(typeTo));
     if (typeTo.IsValueType)
     {
         il.EmitNullableToNonNullableStructConversion(typeFrom, typeTo, isChecked);
     }
     else
     {
         il.EmitNullableToReferenceConversion(typeFrom);
     }
 }
Пример #22
0
        internal static void EmitLoadArgAddress(this ILGenerator il, int index)
        {
            Debug.Assert(index >= 0);

            if (index <= Byte.MaxValue)
            {
                il.Emit(OpCodes.Ldarga_S, (byte)index);
            }
            else
            {
                il.Emit(OpCodes.Ldarga, index);
            }
        }
Пример #23
0
        /// <summary>
        /// Emits an array of constant values provided in the given list.
        /// The array is strongly typed.
        /// </summary>
        internal static void EmitArray <T>(this ILGenerator il, IList <T> items)
        {
            ContractUtils.RequiresNotNull(items, "items");

            il.EmitInt(items.Count);
            il.Emit(OpCodes.Newarr, typeof(T));
            for (int i = 0; i < items.Count; i++)
            {
                il.Emit(OpCodes.Dup);
                il.EmitInt(i);
                il.EmitConstant(items[i], typeof(T));
                il.EmitStoreElement(typeof(T));
            }
        }
Пример #24
0
        private static void EmitNullableToNonNullableStructConversion(this ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            Debug.Assert(TypeUtils.IsNullableType(typeFrom));
            Debug.Assert(!TypeUtils.IsNullableType(typeTo));
            Debug.Assert(typeTo.IsValueType);
            LocalBuilder locFrom = null;

            locFrom = il.DeclareLocal(typeFrom);
            il.Emit(OpCodes.Stloc, locFrom);
            il.Emit(OpCodes.Ldloca, locFrom);
            il.EmitGetValue(typeFrom);
            Type nnTypeFrom = TypeUtils.GetNonNullableType(typeFrom);

            il.EmitConvertToType(nnTypeFrom, typeTo, isChecked);
        }
Пример #25
0
        private static void EmitNonNullableToNullableConversion(this ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            Debug.Assert(!TypeUtils.IsNullableType(typeFrom));
            Debug.Assert(TypeUtils.IsNullableType(typeTo));
            LocalBuilder locTo = null;

            locTo = il.DeclareLocal(typeTo);
            Type nnTypeTo = TypeUtils.GetNonNullableType(typeTo);

            il.EmitConvertToType(typeFrom, nnTypeTo, isChecked);
            ConstructorInfo ci = typeTo.GetConstructor(new Type[] { nnTypeTo });

            il.Emit(OpCodes.Newobj, ci);
            il.Emit(OpCodes.Stloc, locTo);
            il.Emit(OpCodes.Ldloc, locTo);
        }
Пример #26
0
        internal static void EmitConvertToType(this ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            if (TypeUtils.AreEquivalent(typeFrom, typeTo))
            {
                return;
            }

            if (typeFrom == typeof(void) || typeTo == typeof(void))
            {
                throw ContractUtils.Unreachable;
            }

            bool isTypeFromNullable = TypeUtils.IsNullableType(typeFrom);
            bool isTypeToNullable   = TypeUtils.IsNullableType(typeTo);

            Type nnExprType = TypeUtils.GetNonNullableType(typeFrom);
            Type nnType     = TypeUtils.GetNonNullableType(typeTo);

            if (typeFrom.IsInterface ||       // interface cast
                typeTo.IsInterface ||
                typeFrom == typeof(object) || // boxing cast
                typeTo == typeof(object))
            {
                il.EmitCastToType(typeFrom, typeTo);
            }
            else if (isTypeFromNullable || isTypeToNullable)
            {
                il.EmitNullableConversion(typeFrom, typeTo, isChecked);
            }
            else if (!(TypeUtils.IsConvertible(typeFrom) && TypeUtils.IsConvertible(typeTo)) // primitive runtime conversion
                     &&
                     (nnExprType.IsAssignableFrom(nnType) ||                                 // down cast
                      nnType.IsAssignableFrom(nnExprType)))                                  // up cast
            {
                il.EmitCastToType(typeFrom, typeTo);
            }
            else if (typeFrom.IsArray && typeTo.IsArray)
            {
                // See DevDiv Bugs #94657.
                il.EmitCastToType(typeFrom, typeTo);
            }
            else
            {
                il.EmitNumericConversion(typeFrom, typeTo, isChecked);
            }
        }
Пример #27
0
        /// <summary>
        /// Emits an array of values of count size.  The items are emitted via the callback
        /// which is provided with the current item index to emit.
        /// </summary>
        internal static void EmitArray(this ILGenerator il, Type elementType, int count, Action <int> emit)
        {
            ContractUtils.RequiresNotNull(elementType, "elementType");
            ContractUtils.RequiresNotNull(emit, "emit");
            ContractUtils.Requires(count >= 0, "count", Strings.CountCannotBeNegative);

            il.EmitInt(count);
            il.Emit(OpCodes.Newarr, elementType);
            for (int i = 0; i < count; i++)
            {
                il.Emit(OpCodes.Dup);
                il.EmitInt(i);

                emit(i);

                il.EmitStoreElement(elementType);
            }
        }
Пример #28
0
        private static void EmitNullableConversion(this ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            bool isTypeFromNullable = TypeUtils.IsNullableType(typeFrom);
            bool isTypeToNullable   = TypeUtils.IsNullableType(typeTo);

            Debug.Assert(isTypeFromNullable || isTypeToNullable);
            if (isTypeFromNullable && isTypeToNullable)
            {
                il.EmitNullableToNullableConversion(typeFrom, typeTo, isChecked);
            }
            else if (isTypeFromNullable)
            {
                il.EmitNullableToNonNullableConversion(typeFrom, typeTo, isChecked);
            }
            else
            {
                il.EmitNonNullableToNullableConversion(typeFrom, typeTo, isChecked);
            }
        }
Пример #29
0
        /// <summary>
        /// Emits an array construction code.
        /// The code assumes that bounds for all dimensions
        /// are already emitted.
        /// </summary>
        internal static void EmitArray(this ILGenerator il, Type arrayType)
        {
            ContractUtils.RequiresNotNull(arrayType, "arrayType");
            ContractUtils.Requires(arrayType.IsArray, "arrayType", Strings.ArrayTypeMustBeArray);

            int rank = arrayType.GetArrayRank();

            if (rank == 1)
            {
                il.Emit(OpCodes.Newarr, arrayType.GetElementType());
            }
            else
            {
                Type[] types = new Type[rank];
                for (int i = 0; i < rank; i++)
                {
                    types[i] = typeof(int);
                }
                il.EmitNew(arrayType, types);
            }
        }
Пример #30
0
 private static void EmitCastToType(this ILGenerator il, Type typeFrom, Type typeTo)
 {
     if (!typeFrom.IsValueType && typeTo.IsValueType)
     {
         il.Emit(OpCodes.Unbox_Any, typeTo);
     }
     else if (typeFrom.IsValueType && !typeTo.IsValueType)
     {
         il.Emit(OpCodes.Box, typeFrom);
         if (typeTo != typeof(object))
         {
             il.Emit(OpCodes.Castclass, typeTo);
         }
     }
     else if (!typeFrom.IsValueType && !typeTo.IsValueType)
     {
         il.Emit(OpCodes.Castclass, typeTo);
     }
     else
     {
         throw Error.InvalidCast(typeFrom, typeTo);
     }
 }
 internal virtual void MarkSequencePoint(LambdaExpression method, MethodBase methodBase, ILGenerator ilg, DebugInfoExpression sequencePoint) {
     MarkSequencePoint(method, ilg.ILOffset, sequencePoint);
 }
Пример #32
0
 internal LabelInfo(ILGenerator il, LabelTarget node, bool canReturn) {
     _ilg = il;
     _node = node;
     _canReturn = canReturn;
 }