Ejemplo n.º 1
0
        public static void EmitLoadLocal(YaleIlGenerator ilg, int index)
        {
            Debug.Assert(index >= 0, "Invalid index");

            if (index >= 0 & index <= 3)
            {
                switch (index)
                {
                case 0:
                    ilg.Emit(OpCodes.Ldloc_0);
                    break;

                case 1:
                    ilg.Emit(OpCodes.Ldloc_1);
                    break;

                case 2:
                    ilg.Emit(OpCodes.Ldloc_2);
                    break;

                case 3:
                    ilg.Emit(OpCodes.Ldloc_3);
                    break;
                }
            }
            else
            {
                Debug.Assert(index < 256, "local index too large");
                ilg.Emit(OpCodes.Ldloc_S, Convert.ToByte(index));
            }
        }
Ejemplo n.º 2
0
        private static bool ImplicitConvertToInt64(TypeCode sourceTypeCode, YaleIlGenerator ilGenerator)
        {
            switch (sourceTypeCode)
            {
            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.Int32:
                EmitConvert(ilGenerator, OpCodes.Conv_I8);
                break;

            case TypeCode.Char:
            case TypeCode.Byte:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
                EmitConvert(ilGenerator, OpCodes.Conv_U8);
                break;

            case TypeCode.Int64:
                break;

            default:
                return(false);
            }

            return(true);
        }
Ejemplo n.º 3
0
 public static void SyncFleeIlGeneratorLabels(YaleIlGenerator source, YaleIlGenerator target)
 {
     while (source.LabelCount != target.LabelCount)
     {
         target.DefineLabel();
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Add a branch from a location to a target label
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <remarks></remarks>
        public void AddBranch(YaleIlGenerator ilg, Label target)
        {
            var startLoc   = new ILLocation(ilg.Length);
            var branchInfo = new BranchInfo(startLoc, target);

            branchInfos.Add(branchInfo);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Set the position for a label
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <remarks></remarks>
        public void MarkLabel(YaleIlGenerator ilg, Label target)
        {
            var pos = ilg.Length;

            foreach (var branchInfo in branchInfos)
            {
                branchInfo.Mark(target, pos);
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Get a label by a key.  Create the label if it is not present.
 /// </summary>
 /// <param name="key"></param>
 /// <param name="ilg"></param>
 /// <returns></returns>
 /// <remarks></remarks>
 public Label GetLabel(object key, YaleIlGenerator ilg)
 {
     if (keyLabelMap.TryGetValue(key, out var lbl) == false)
     {
         lbl = ilg.DefineLabel();
         keyLabelMap.Add(key, lbl);
     }
     return(lbl);
 }
Ejemplo n.º 7
0
        public static void EmitArrayLoad(YaleIlGenerator ilg, Type elementType)
        {
            var typeCode = Type.GetTypeCode(elementType);

            switch (typeCode)
            {
            case TypeCode.Byte:
                ilg.Emit(OpCodes.Ldelem_U1);
                break;

            case TypeCode.SByte:
            case TypeCode.Boolean:
                ilg.Emit(OpCodes.Ldelem_I1);
                break;

            case TypeCode.Int16:
                ilg.Emit(OpCodes.Ldelem_I2);
                break;

            case TypeCode.UInt16:
                ilg.Emit(OpCodes.Ldelem_U2);
                break;

            case TypeCode.Int32:
                ilg.Emit(OpCodes.Ldelem_I4);
                break;

            case TypeCode.UInt32:
                ilg.Emit(OpCodes.Ldelem_U4);
                break;

            case TypeCode.Int64:
            case TypeCode.UInt64:
                ilg.Emit(OpCodes.Ldelem_I8);
                break;

            case TypeCode.Single:
                ilg.Emit(OpCodes.Ldelem_R4);
                break;

            case TypeCode.Double:
                ilg.Emit(OpCodes.Ldelem_R8);
                break;

            case TypeCode.Object:
            case TypeCode.String:
                ilg.Emit(OpCodes.Ldelem_Ref);
                break;

            default:
                // Must be a non-primitive value type
                ilg.Emit(OpCodes.Ldelema, elementType);
                ilg.Emit(OpCodes.Ldobj, elementType);
                return;
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Determine if a branch from a point to a label will be long
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool IsLongBranch(YaleIlGenerator ilg, Label target)
        {
            var startLoc   = new ILLocation(ilg.Length);
            var branchInfo = new BranchInfo(startLoc, target);

            var index = branchInfos.IndexOf(branchInfo);

            branchInfo = branchInfos[index];

            return(branchInfo.IsLongBranch);
        }
Ejemplo n.º 9
0
        public static void EmitLoadLocalAddress(YaleIlGenerator ilg, int index)
        {
            Debug.Assert(index >= 0, "Invalid index");

            if (index <= byte.MaxValue)
            {
                ilg.Emit(OpCodes.Ldloca_S, Convert.ToByte(index));
            }
            else
            {
                ilg.Emit(OpCodes.Ldloca, index);
            }
        }
Ejemplo n.º 10
0
 private static void EmitConvert(YaleIlGenerator ilg, OpCode convertOpcode)
 {
     ilg?.Emit(convertOpcode);
 }
Ejemplo n.º 11
0
        /// <summary>
        ///Emit an implicit conversion (if the ilg is not null) and returns a value that determines whether the implicit conversion
        /// succeeded
        /// </summary>
        /// <param name="sourceType"></param>
        /// <param name="destinationType"></param>
        /// <param name="ilGenerator"></param>
        /// <returns></returns>
        public static bool EmitImplicitNumericConvert(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator)
        {
            var sourceTypeCode = Type.GetTypeCode(sourceType);
            var destTypeCode   = Type.GetTypeCode(destinationType);

            switch (destTypeCode)
            {
            case TypeCode.Int16:
                return(ImplicitConvertToInt16(sourceTypeCode));

            case TypeCode.UInt16:
                return(ImplicitConvertToUInt16(sourceTypeCode));

            case TypeCode.Int32:
                return(ImplicitConvertToInt32(sourceTypeCode));

            case TypeCode.UInt32:
                return(ImplicitConvertToUInt32(sourceTypeCode));

            case TypeCode.Double:
                return(ImplicitConvertToDouble(sourceTypeCode, ilGenerator));

            case TypeCode.Single:
                return(ImplicitConvertToSingle(sourceTypeCode, ilGenerator));

            case TypeCode.Int64:
                return(ImplicitConvertToInt64(sourceTypeCode, ilGenerator));

            case TypeCode.UInt64:
                return(ImplicitConvertToUInt64(sourceTypeCode, ilGenerator));

            default:
                return(false);
            }
        }
Ejemplo n.º 12
0
        private static bool ImplicitConvertToValueType(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator)
        {
            // We only handle value types
            if (sourceType.IsValueType == false && destinationType.IsValueType == false)
            {
                return(false);
            }

            // No implicit conversion to enum.  Have to do this check here since calling GetTypeCode on an enum will return the typecode
            // of the underlying type which screws us up.
            if (sourceType.IsEnum || destinationType.IsEnum)
            {
                return(false);
            }

            return(EmitImplicitNumericConvert(sourceType, destinationType, ilGenerator));
        }
Ejemplo n.º 13
0
        private static bool ImplicitConvertToReferenceType(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator)
        {
            if (destinationType.IsValueType)
            {
                return(false);
            }

            if (ReferenceEquals(sourceType, typeof(Null)))
            {
                // Null is always convertible to a reference type
                return(true);
            }

            if (destinationType.IsAssignableFrom(sourceType) == false)
            {
                return(false);
            }

            if (sourceType.IsValueType)
            {
                ilGenerator?.Emit(OpCodes.Box, sourceType);
            }

            return(true);
        }
Ejemplo n.º 14
0
        private static bool EmitOverloadedImplicitConvert(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator)
        {
            // Look for an implicit operator on the destination type
            var methodInfo = Utility.GetSimpleOverloadedOperator("Implicit", sourceType, destinationType);

            if (methodInfo == null)
            {
                return(false);
            }

            ilGenerator?.Emit(OpCodes.Call, methodInfo);

            return(true);
        }
Ejemplo n.º 15
0
        public static bool EmitImplicitConvert(Type sourceType, Type destinationType, YaleIlGenerator ilGenerator)
        {
            if (ReferenceEquals(sourceType, destinationType))
            {
                return(true);
            }

            if (EmitOverloadedImplicitConvert(sourceType, destinationType, ilGenerator))
            {
                return(true);
            }

            if (ImplicitConvertToReferenceType(sourceType, destinationType, ilGenerator))
            {
                return(true);
            }

            return(ImplicitConvertToValueType(sourceType, destinationType, ilGenerator));
        }
Ejemplo n.º 16
0
 public override void Emit(YaleIlGenerator ilGenerator, ExpressionContext context)
 {
     Utility.EmitLoadLocal(ilGenerator, _index);
 }