예제 #1
0
파일: AndOr.cs 프로젝트: riskfirst/Flee
 /// <summary>
 /// Note a label's position if we are in mark mode
 /// </summary>
 /// <param name="info"></param>
 /// <param name="target"></param>
 /// <param name="ilg"></param>
 private static void MarkBranchTarget(ShortCircuitInfo info, Label target, FleeILGenerator ilg)
 {
     if (ilg.IsTemp == true)
     {
         info.Branches.MarkLabel(ilg, target);
     }
 }
예제 #2
0
파일: AndOr.cs 프로젝트: riskfirst/Flee
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            MethodInfo overloadedMethod = this.GetOverloadedAndOrOperator();

            if ((overloadedMethod != null))
            {
                // Emit a call to an overloaded operator
                this.EmitOverloadedOperatorCall(overloadedMethod, ilg, services);
            }
            else
            {
                Type resultType = this.ResultType;

                if (object.ReferenceEquals(resultType, typeof(bool)))
                {
                    this.DoEmitLogical(ilg, services);
                }
                else
                {
                    MyLeftChild.Emit(ilg, services);
                    ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, resultType, ilg);
                    MyRightChild.Emit(ilg, services);
                    ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, resultType, ilg);
                    EmitBitwiseOperation(ilg, _myOperation);
                }
            }
        }
예제 #3
0
파일: AndOr.cs 프로젝트: riskfirst/Flee
        /// <summary>
        /// Emit the end cases for a short-circuit
        /// </summary>
        /// <param name="info"></param>
        /// <param name="ilg"></param>
        /// <param name="endLabel"></param>
        private static void EmitTerminals(ShortCircuitInfo info, FleeILGenerator ilg, Label endLabel)
        {
            // Emit the false case if it was used
            if (info.Branches.HasLabel(OurFalseTerminalKey) == true)
            {
                Label falseLabel = info.Branches.FindLabel(OurFalseTerminalKey);

                // Mark the label and note its position
                ilg.MarkLabel(falseLabel);
                MarkBranchTarget(info, falseLabel, ilg);

                ilg.Emit(OpCodes.Ldc_I4_0);

                // If we also have a true terminal, then skip over it
                if (info.Branches.HasLabel(OurTrueTerminalKey) == true)
                {
                    ilg.Emit(OpCodes.Br_S, endLabel);
                }
            }

            // Emit the true case if it was used
            if (info.Branches.HasLabel(OurTrueTerminalKey) == true)
            {
                Label trueLabel = info.Branches.FindLabel(OurTrueTerminalKey);

                // Mark the label and note its position
                ilg.MarkLabel(trueLabel);
                MarkBranchTarget(info, trueLabel, ilg);

                ilg.Emit(OpCodes.Ldc_I4_1);
            }
        }
예제 #4
0
파일: AndOr.cs 프로젝트: riskfirst/Flee
        /// <summary>
        /// Emit a short-circuited logical operation sequence
        /// The idea: Store all the leaf operands in a stack with the leftmost at the top and rightmost at the bottom.
        /// For each operand, emit it and try to find an end point for when it short-circuits.  This means we go up through
        /// the stack of operators (ignoring siblings) until we find a different operation (then emit a branch to its right operand)
        /// or we reach the root (emit a branch to a true/false).
        /// Repeat the process for all operands and then emit the true/false/last operand end cases.
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="info"></param>
        /// <param name="services"></param>
        private void EmitLogical(FleeILGenerator ilg, ShortCircuitInfo info, IServiceProvider services)
        {
            // We always have an end label
            info.Branches.GetLabel(OurEndLabelKey, ilg);

            // Populate our data structures
            this.PopulateData(info);

            // Emit the sequence
            EmitLogicalShortCircuit(ilg, info, services);

            // Get the last operand
            ExpressionElement terminalOperand = (ExpressionElement)info.Operands.Pop();

            // Emit it
            EmitOperand(terminalOperand, info, ilg, services);
            // And jump to the end
            Label endLabel = info.Branches.FindLabel(OurEndLabelKey);

            ilg.Emit(OpCodes.Br_S, endLabel);

            // Emit our true/false terminals
            EmitTerminals(info, ilg, endLabel);

            // Mark the end
            ilg.MarkLabel(endLabel);
        }
예제 #5
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            BranchManager bm = new BranchManager();

            bm.GetLabel("falseLabel", ilg);
            bm.GetLabel("endLabel", ilg);

            if (ilg.IsTemp == true)
            {
                // If this is a fake emit, then do a fake emit and return
                this.EmitConditional(ilg, services, bm);
                return;
            }

            FleeILGenerator ilgTemp = this.CreateTempFleeILGenerator(ilg);

            Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp);

            // Emit fake conditional to get branch target positions
            this.EmitConditional(ilgTemp, services, bm);

            bm.ComputeBranches();

            // Emit real conditional now that we have the branch target locations
            this.EmitConditional(ilg, services, bm);
        }
예제 #6
0
        /// <summary>
        /// Emit a string concatenation
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="services"></param>
        private void EmitStringConcat(FleeILGenerator ilg, IServiceProvider services)
        {
            Type argType = default(Type);

            System.Reflection.MethodInfo concatMethodInfo = default(System.Reflection.MethodInfo);

            // Pick the most specific concat method
            if (this.AreBothChildrenOfType(typeof(string)) == true)
            {
                concatMethodInfo = _ourStringConcatMethodInfo;
                argType          = typeof(string);
            }
            else
            {
                Debug.Assert(this.IsEitherChildOfType(typeof(string)), "one child must be a string");
                concatMethodInfo = _ourObjectConcatMethodInfo;
                argType          = typeof(object);
            }

            // Emit the operands and call the function
            MyLeftChild.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyLeftChild.ResultType, argType, ilg);
            MyRightChild.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyRightChild.ResultType, argType, ilg);
            ilg.Emit(OpCodes.Call, concatMethodInfo);
        }
예제 #7
0
        private void EmitOptimizedPower(FleeILGenerator ilg, bool emitOverflow, bool unsigned)
        {
            Int32LiteralElement right = (Int32LiteralElement)MyRightChild;

            if (right.Value == 0)
            {
                ilg.Emit(OpCodes.Pop);
                IntegralLiteralElement.EmitLoad(1, ilg);
                ImplicitConverter.EmitImplicitNumericConvert(typeof(Int32), MyLeftChild.ResultType, ilg);
                return;
            }

            if (right.Value == 1)
            {
                return;
            }

            // Start at 1 since left operand has already been emited once
            for (int i = 1; i <= right.Value - 1; i++)
            {
                ilg.Emit(OpCodes.Dup);
            }

            for (int i = 1; i <= right.Value - 1; i++)
            {
                this.EmitMultiply(ilg, emitOverflow, unsigned);
            }
        }
예제 #8
0
        private void DoEmitLogical(FleeILGenerator ilg, IServiceProvider services)
        {
            // We have to do a 'fake' emit so we can get the positions of the labels
            ShortCircuitInfo info = new ShortCircuitInfo();

            // Do the real emit
            this.EmitLogical(ilg, info, services);
        }
예제 #9
0
 private static Label GetLabel(object key, FleeILGenerator ilg, ShortCircuitInfo info)
 {
     if (info.HasLabel(key))
     {
         return(info.FindLabel(key));
     }
     return(info.AddLabel(key, ilg.DefineLabel()));
 }
예제 #10
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            EmitChild(_operand, _operand.ResultType, ilg, services);
            EmitChild(_from, _operand.ResultType, ilg, services);
            EmitChild(_to, _operand.ResultType, ilg, services);

            ilg.Emit(OpCodes.Call, _betweenMethodInfo.MakeGenericMethod(_operand.ResultType));
        }
예제 #11
0
파일: Cast.cs 프로젝트: chubbyerror/BpmNet
        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);
        }
예제 #12
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);
     }
 }
예제 #13
0
파일: Xor.cs 프로젝트: xiaoxiongnpu/Flee
        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);
        }
예제 #14
0
        protected void EmitOverloadedOperatorCall(MethodInfo method, FleeILGenerator ilg, IServiceProvider services)
        {
            ParameterInfo[] @params = method.GetParameters();
            ParameterInfo   pLeft   = @params[0];
            ParameterInfo   pRight  = @params[1];

            EmitChildWithConvert(MyLeftChild, pLeft.ParameterType, ilg, services);
            EmitChildWithConvert(MyRightChild, pRight.ParameterType, ilg, services);
            ilg.Emit(OpCodes.Call, method);
        }
예제 #15
0
 public override void Emit(FleeILGenerator ilg, IServiceProvider services)
 {
     if ((_myTargetCollectionType != null))
     {
         this.EmitCollectionIn(ilg, services);
     }
     else
     {
         EmitCustomInMethod(ilg, services);
     }
 }
예제 #16
0
 private static void EmitReferenceTypeMethodCall(MethodInfo mi, FleeILGenerator ilg)
 {
     if (mi.IsStatic == true)
     {
         ilg.Emit(OpCodes.Call, mi);
     }
     else
     {
         ilg.Emit(OpCodes.Callvirt, mi);
     }
 }
예제 #17
0
 private void EmitValueTypeArrayLoad(FleeILGenerator ilg, Type elementType)
 {
     if (this.NextRequiresAddress == true)
     {
         ilg.Emit(OpCodes.Ldelema, elementType);
     }
     else
     {
         Utility.EmitArrayLoad(ilg, elementType);
     }
 }
예제 #18
0
 protected static void EmitLoad(bool value, FleeILGenerator ilg)
 {
     if (value == true)
     {
         ilg.Emit(OpCodes.Ldc_I4_1);
     }
     else
     {
         ilg.Emit(OpCodes.Ldc_I4_0);
     }
 }
예제 #19
0
        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="fi"></param>
        /// <param name="ilg"></param>
        /// <param name="services"></param>
        private static void EmitLiteral(System.Reflection.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);
        }
예제 #20
0
 private void EmitPower(FleeILGenerator ilg, bool emitOverflow, bool unsigned)
 {
     if (this.IsOptimizablePower == true)
     {
         this.EmitOptimizedPower(ilg, emitOverflow, unsigned);
     }
     else
     {
         ilg.Emit(OpCodes.Call, _ourPowerMethodInfo);
     }
 }
예제 #21
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);
        }
예제 #22
0
 private static void EmitBranch(AndOrElement op, FleeILGenerator ilg, Label target, ShortCircuitInfo info)
 {
     // Get the branch opcode
     if (op._myOperation == AndOrOperation.And)
     {
         ilg.EmitBranchFalse(target);
     }
     else
     {
         ilg.EmitBranchTrue(target);
     }
 }
예제 #23
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            int index = ilg.GetTempLocalIndex(typeof(TimeSpan));

            Utility.EmitLoadLocalAddress(ilg, index);

            LiteralElement.EmitLoad(_myValue.Ticks, ilg);

            ilg.Emit(OpCodes.Call, _timeSpanConstructor);

            Utility.EmitLoadLocal(ilg, index);
        }
예제 #24
0
 public override void Emit(FleeILGenerator ilg, IServiceProvider services)
 {
     if ((MyTargetCollectionType != null))
     {
         this.EmitCollectionIn(ilg, services);
     }
     else
     {
         // Do the real emit
         this.EmitListIn(ilg, services);
     }
 }
예제 #25
0
파일: Not.cs 프로젝트: QuickOrBeDead/Flee
 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);
     }
 }
예제 #26
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);
        }
예제 #27
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);
            }
        }
예제 #28
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            _myChild.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(_myChild.ResultType, _myResultType, ilg);

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

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

            ilg.Emit(OpCodes.Ret);
        }
예제 #29
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            int index = ilg.GetTempLocalIndex(typeof(DateTime));

            Utility.EmitLoadLocalAddress(ilg, index);

            LiteralElement.EmitLoad(_myValue.Ticks, ilg);

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

            ilg.Emit(OpCodes.Call, ci);

            Utility.EmitLoadLocal(ilg, index);
        }
예제 #30
0
파일: Cast.cs 프로젝트: chubbyerror/BpmNet
        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);
                    }
                }
            }
        }