Пример #1
0
        private static bool ImplicitConvertToSingle(TypeCode sourceTypeCode, FleeILGenerator ilg)
        {
            switch (sourceTypeCode)
            {
            case TypeCode.Char:
            case TypeCode.Byte:
            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
            case TypeCode.Int64:
                EmitConvert(ilg, OpCodes.Conv_R4);
                break;

            case TypeCode.UInt32:
            case TypeCode.UInt64:
                EmitConvert(ilg, OpCodes.Conv_R_Un);
                EmitConvert(ilg, OpCodes.Conv_R4);
                break;

            case TypeCode.Single:
                break;

            default:
                return(false);
            }

            return(true);
        }
Пример #2
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(FleeILGenerator ilg, Label target)
        {
            ILLocation startLoc = new ILLocation(ilg.Length);

            BranchInfo bi = new BranchInfo(startLoc, target);

            MyBranchInfos.Add(bi);
        }
Пример #3
0
        /// <summary>
        /// Set the position for a label
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <remarks></remarks>
        public void MarkLabel(FleeILGenerator ilg, Label target)
        {
            int pos = ilg.Length;

            foreach (BranchInfo bi in MyBranchInfos)
            {
                bi.Mark(target, pos);
            }
        }
Пример #4
0
 public override void Emit(FleeILGenerator ilg, IServiceProvider services)
 {
     base.Emit(ilg, services);
     MyElement.Emit(ilg, services);
     if (MyElement.ResultType.IsValueType == true)
     {
         EmitValueTypeLoadAddress(ilg, this.ResultType);
     }
 }
Пример #5
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            MyCastExpression.Emit(ilg, services);

            Type sourceType = MyCastExpression.ResultType;
            Type destType   = MyDestType;

            this.EmitCast(ilg, sourceType, destType, services);
        }
Пример #6
0
        public static void EmitArrayLoad(FleeILGenerator ilg, Type elementType)
        {
            TypeCode tc = Type.GetTypeCode(elementType);

            switch (tc)
            {
            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;
            }
        }
Пример #7
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            Type resultType = this.ResultType;

            MyLeftChild.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg);
            MyRightChild.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg);
            ilg.Emit(OpCodes.Xor);
        }
Пример #8
0
        protected void EmitOverloadedOperatorCall(MethodInfo method, FleeILGenerator ilg, IServiceProvider services)
        {
            ParameterInfo[] parameters = method.GetParameters();
            ParameterInfo   pLeft      = parameters[0];
            ParameterInfo   pRight     = parameters[1];

            EmitChildWithConvert(MyLeftChild, pLeft.ParameterType, ilg, services);
            EmitChildWithConvert(MyRightChild, pRight.ParameterType, ilg, services);
            ilg.Emit(OpCodes.Call, method);
        }
Пример #9
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(FleeILGenerator ilg, Label target)
        {
            ILLocation startLoc = new ILLocation(ilg.Length);
            BranchInfo bi       = new BranchInfo(startLoc, target);

            int index = MyBranchInfos.IndexOf(bi);

            bi = MyBranchInfos[index];

            return(bi.IsLongBranch);
        }
Пример #10
0
 private void EmitValueTypeArrayLoad(FleeILGenerator ilg, Type elementType)
 {
     if (this.NextRequiresAddress == true)
     {
         ilg.Emit(OpCodes.Ldelema, elementType);
     }
     else
     {
         Utility.EmitArrayLoad(ilg, elementType);
     }
 }
Пример #11
0
        // Emit the load of a constant field. We can't emit a ldsfld/ldfld of a constant so we have to get its value
        // and then emit a ldc.
        private static void EmitLiteral(FieldInfo fi, FleeILGenerator ilg, IServiceProvider services)
        {
            object         value = fi.GetValue(null);
            Type           t     = value.GetType();
            TypeCode       code  = Type.GetTypeCode(t);
            LiteralElement elem  = default(LiteralElement);

            switch (code)
            {
            case TypeCode.Char:
            case TypeCode.Byte:
            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
                elem = new Int32LiteralElement(System.Convert.ToInt32(value));
                break;

            case TypeCode.UInt32:
                elem = new UInt32LiteralElement((UInt32)value);
                break;

            case TypeCode.Int64:
                elem = new Int64LiteralElement((Int64)value);
                break;

            case TypeCode.UInt64:
                elem = new UInt64LiteralElement((UInt64)value);
                break;

            case TypeCode.Double:
                elem = new DoubleLiteralElement((double)value);
                break;

            case TypeCode.Single:
                elem = new SingleLiteralElement((float)value);
                break;

            case TypeCode.Boolean:
                elem = new BooleanLiteralElement((bool)value);
                break;

            case TypeCode.String:
                elem = new StringLiteralElement((string)value);
                break;

            default:
                elem = null;
                Debug.Fail("Unsupported constant type");
                break;
            }

            elem.Emit(ilg, services);
        }
Пример #12
0
 private static void EmitReferenceTypeMethodCall(MethodInfo mi, FleeILGenerator ilg)
 {
     if (mi.IsStatic == true)
     {
         ilg.Emit(OpCodes.Call, mi);
     }
     else
     {
         ilg.Emit(OpCodes.Callvirt, mi);
     }
 }
Пример #13
0
 public override void Emit(FleeILGenerator ilg, IServiceProvider services)
 {
     if (MyValue == true)
     {
         ilg.Emit(OpCodes.Ldc_I4_1);
     }
     else
     {
         ilg.Emit(OpCodes.Ldc_I4_0);
     }
 }
Пример #14
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, FleeILGenerator ilg)
        {
            Label lbl = default(Label);

            if (MyKeyLabelMap.TryGetValue(key, out lbl) == false)
            {
                lbl = ilg.DefineLabel();
                MyKeyLabelMap.Add(key, lbl);
            }

            return(lbl);
        }
Пример #15
0
        private static void EmitSuperShort(Int32 value, FleeILGenerator ilg)
        {
            OpCode ldcOpcode = default(OpCode);

            switch (value)
            {
            case 0:
                ldcOpcode = OpCodes.Ldc_I4_0;
                break;

            case 1:
                ldcOpcode = OpCodes.Ldc_I4_1;
                break;

            case 2:
                ldcOpcode = OpCodes.Ldc_I4_2;
                break;

            case 3:
                ldcOpcode = OpCodes.Ldc_I4_3;
                break;

            case 4:
                ldcOpcode = OpCodes.Ldc_I4_4;
                break;

            case 5:
                ldcOpcode = OpCodes.Ldc_I4_5;
                break;

            case 6:
                ldcOpcode = OpCodes.Ldc_I4_6;
                break;

            case 7:
                ldcOpcode = OpCodes.Ldc_I4_7;
                break;

            case 8:
                ldcOpcode = OpCodes.Ldc_I4_8;
                break;

            case -1:
                ldcOpcode = OpCodes.Ldc_I4_M1;
                break;

            default:
                Debug.Assert(false, "value out of range");
                break;
            }

            ilg.Emit(ldcOpcode);
        }
Пример #16
0
 public override void Emit(FleeILGenerator ilg, IServiceProvider services)
 {
     if (object.ReferenceEquals(MyChild.ResultType, typeof(bool)))
     {
         this.EmitLogical(ilg, services);
     }
     else
     {
         MyChild.Emit(ilg, services);
         ilg.Emit(OpCodes.Not);
     }
 }
Пример #17
0
        private void EmitConditional(FleeILGenerator ilg, IServiceProvider services, BranchManager bm)
        {
            Label falseLabel = bm.FindLabel("falseLabel");
            Label endLabel   = bm.FindLabel("endLabel");

            // Emit the condition
            MyCondition.Emit(ilg, services);

            // On false go to the false operand
            if (ilg.IsTemp == true)
            {
                bm.AddBranch(ilg, falseLabel);
                ilg.Emit(OpCodes.Brfalse_S, falseLabel);
            }
            else if (bm.IsLongBranch(ilg, falseLabel) == false)
            {
                ilg.Emit(OpCodes.Brfalse_S, falseLabel);
            }
            else
            {
                ilg.Emit(OpCodes.Brfalse, falseLabel);
            }

            // Emit the true operand
            MyWhenTrue.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyWhenTrue.ResultType, MyResultType, ilg);

            // Jump to end
            if (ilg.IsTemp == true)
            {
                bm.AddBranch(ilg, endLabel);
                ilg.Emit(OpCodes.Br_S, endLabel);
            }
            else if (bm.IsLongBranch(ilg, endLabel) == false)
            {
                ilg.Emit(OpCodes.Br_S, endLabel);
            }
            else
            {
                ilg.Emit(OpCodes.Br, endLabel);
            }

            bm.MarkLabel(ilg, falseLabel);
            ilg.MarkLabel(falseLabel);

            // Emit the false operand
            MyWhenFalse.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyWhenFalse.ResultType, MyResultType, ilg);
            // Fall through to end
            bm.MarkLabel(ilg, endLabel);
            ilg.MarkLabel(endLabel);
        }
Пример #18
0
        public static void EmitLoadLocalAddress(FleeILGenerator ilg, int index)
        {
            Debug.Assert(index >= 0, "Invalid index");

            if (index <= byte.MaxValue)
            {
                ilg.Emit(OpCodes.Ldloca_S, (byte)index);
            }
            else
            {
                ilg.Emit(OpCodes.Ldloca, index);
            }
        }
Пример #19
0
        private static bool ImplicitConvertToUInt16(TypeCode sourceTypeCode, FleeILGenerator ilg)
        {
            switch (sourceTypeCode)
            {
            case TypeCode.Char:
            case TypeCode.Byte:
            case TypeCode.UInt16:
                return(true);

            default:
                return(false);
            }
        }
Пример #20
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            base.Emit(ilg, services);

            if (this.IsArray == true)
            {
                this.EmitArrayLoad(ilg, services);
            }
            else
            {
                this.EmitIndexer(ilg, services);
            }
        }
Пример #21
0
        private void EmitCast(FleeILGenerator ilg, Type sourceType, Type destType, IServiceProvider services)
        {
            MethodInfo explicitOperator = this.GetExplictOverloadedOperator(sourceType, destType);

            if (object.ReferenceEquals(sourceType, destType))
            {
                // Identity cast; do nothing
                return;
            }
            else if ((explicitOperator != null))
            {
                ilg.Emit(OpCodes.Call, explicitOperator);
            }
            else if (sourceType.IsEnum == true | destType.IsEnum == true)
            {
                this.EmitEnumCast(ilg, sourceType, destType, services);
            }
            else if (ImplicitConverter.EmitImplicitConvert(sourceType, destType, ilg) == true)
            {
                // Implicit numeric cast; do nothing
                return;
            }
            else if (IsCastableNumericType(sourceType) & IsCastableNumericType(destType))
            {
                // Explicit numeric cast
                EmitExplicitNumericCast(ilg, sourceType, destType, services);
            }
            else if (sourceType.IsValueType == true)
            {
                Debug.Assert(destType.IsValueType == false, "expecting reference type");
                ilg.Emit(OpCodes.Box, sourceType);
            }
            else
            {
                if (destType.IsValueType == true)
                {
                    // Reference type to value type
                    ilg.Emit(OpCodes.Unbox_Any, destType);
                }
                else
                {
                    // Reference type to reference type
                    if (destType.IsAssignableFrom(sourceType) == false)
                    {
                        // Only emit cast if it is an explicit cast
                        ilg.Emit(OpCodes.Castclass, destType);
                    }
                }
            }
        }
Пример #22
0
        private void EmitOnDemandFunction(ExpressionElement[] elements, FleeILGenerator ilg, IServiceProvider services)
        {
            // Load the variable collection
            EmitLoadVariables(ilg);
            // Load the function name
            ilg.Emit(OpCodes.Ldstr, MyName);
            // Load the arguments array
            EmitElementArrayLoad(elements, typeof(object), ilg, services);

            // Call the function to get the result
            MethodInfo mi = VariableCollection.GetFunctionInvokeMethod(MyOnDemandFunctionReturnType);

            this.EmitMethodCall(mi, ilg);
        }
Пример #23
0
        public override void Emit(FleeILGenerator ilg, System.IServiceProvider services)
        {
            int index = ilg.GetTempLocalIndex(typeof(TimeSpan));

            Utility.EmitLoadLocalAddress(ilg, index);

            LiteralElement.EmitInt64Load(MyValue.Ticks, ilg);

            ConstructorInfo ci = typeof(TimeSpan).GetConstructor(new Type[] { typeof(long) });

            ilg.Emit(OpCodes.Call, ci);

            Utility.EmitLoadLocal(ilg, index);
        }
Пример #24
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            MyChild.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyChild.ResultType, MyResultType, ilg);

            ExpressionOptions options = services.GetService(typeof(ExpressionOptions)) as ExpressionOptions;

            if (options.IsGeneric == false)
            {
                ImplicitConverter.EmitImplicitConvert(MyResultType, typeof(object), ilg);
            }

            ilg.Emit(OpCodes.Ret);
        }
Пример #25
0
 private void EmitFieldLoad(FieldInfo fi, FleeILGenerator ilg, IServiceProvider services)
 {
     if (fi.IsLiteral == true)
     {
         EmitLiteral(fi, ilg, services);
     }
     else if (this.ResultType.IsValueType == true & this.NextRequiresAddress == true)
     {
         EmitLdfld(fi, true, ilg);
     }
     else
     {
         EmitLdfld(fi, false, ilg);
     }
 }
Пример #26
0
        private void EmitCollectionIn(FleeILGenerator ilg, IServiceProvider services)
        {
            // Get the contains method
            MethodInfo    mi = this.GetCollectionContainsMethod();
            ParameterInfo p1 = mi.GetParameters()[0];

            // Load the collection
            MyTargetCollectionElement.Emit(ilg, services);
            // Load the argument
            MyOperand.Emit(ilg, services);
            // Do an implicit convert if necessary
            ImplicitConverter.EmitImplicitConvert(MyOperand.ResultType, p1.ParameterType, ilg);
            // Call the contains method
            ilg.Emit(OpCodes.Callvirt, mi);
        }
Пример #27
0
 public static void EmitInt32Load(Int32 value, FleeILGenerator ilg)
 {
     if (value >= -1 & value <= 8)
     {
         EmitSuperShort(value, ilg);
     }
     else if (value >= sbyte.MinValue & value <= sbyte.MaxValue)
     {
         ilg.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
     }
     else
     {
         ilg.Emit(OpCodes.Ldc_I4, value);
     }
 }
Пример #28
0
 private static void EmitBranchToTrueTerminal(FleeILGenerator ilg, Label trueTerminal, BranchManager bm)
 {
     if (ilg.IsTemp == true)
     {
         bm.AddBranch(ilg, trueTerminal);
         ilg.Emit(OpCodes.Brtrue_S, trueTerminal);
     }
     else if (bm.IsLongBranch(ilg, trueTerminal) == false)
     {
         ilg.Emit(OpCodes.Brtrue_S, trueTerminal);
     }
     else
     {
         ilg.Emit(OpCodes.Brtrue, trueTerminal);
     }
 }
Пример #29
0
 private void EmitEnumCast(FleeILGenerator ilg, Type sourceType, Type destType, IServiceProvider services)
 {
     if (destType.IsValueType == false)
     {
         ilg.Emit(OpCodes.Box, sourceType);
     }
     else if (sourceType.IsValueType == false)
     {
         ilg.Emit(OpCodes.Unbox_Any, destType);
     }
     else
     {
         sourceType = GetUnderlyingEnumType(sourceType);
         destType   = GetUnderlyingEnumType(destType);
         this.EmitCast(ilg, sourceType, destType, services);
     }
 }
Пример #30
0
        private void EmitArrayLoad(FleeILGenerator ilg, IServiceProvider services)
        {
            MyIndexerElement.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyIndexerElement.ResultType, typeof(Int32), ilg);

            Type elementType = this.ResultType;

            if (elementType.IsValueType == false)
            {
                // Simple reference load
                ilg.Emit(OpCodes.Ldelem_Ref);
            }
            else
            {
                this.EmitValueTypeArrayLoad(ilg, elementType);
            }
        }