示例#1
0
        protected static bool IsOwnerMemberAccessible(MemberInfo member, ExpressionOptions options)
        {
            bool accessAllowed = false;

            // Get the allowed access defined in the options
            if (IsMemberPublic(member) == true)
            {
                accessAllowed = (options.OwnerMemberAccess & BindingFlags.Public) != 0;
            }
            else
            {
                accessAllowed = (options.OwnerMemberAccess & BindingFlags.NonPublic) != 0;
            }

            // See if the member has our access attribute defined
            ExpressionOwnerMemberAccessAttribute attr = Attribute.GetCustomAttribute(member, typeof(ExpressionOwnerMemberAccessAttribute)) as ExpressionOwnerMemberAccessAttribute;

            if (attr == null)
            {
                // No, so return the access level
                return(accessAllowed);
            }
            else
            {
                // Member has our access attribute defined; use its access value instead
                return(attr.AllowAccess);
            }
        }
        internal ExpressionOptions Clone()
        {
            ExpressionOptions clonedOptions = this.MemberwiseClone() as ExpressionOptions;

            clonedOptions.MyProperties = MyProperties.Clone();
            return(clonedOptions);
        }
示例#3
0
 public void Resolve(IServiceProvider services)
 {
     MyServices = services;
     MyOptions  = services.GetService(typeof(ExpressionOptions)) as ExpressionOptions;
     MyContext  = services.GetService(typeof(ExpressionContext)) as ExpressionContext;
     this.ResolveInternal();
     this.Validate();
 }
示例#4
0
        private void SetupOptions(ExpressionOptions options, bool isGeneric)
        {
            // Make sure we clone the options
            MyOptions           = options;
            MyOptions.IsGeneric = isGeneric;

            if (isGeneric)
            {
                MyOptions.ResultType = typeof(T);
            }

            MyOptions.SetOwnerType(MyOwner.GetType());
        }
示例#5
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);
        }
示例#6
0
        private static void EmitStringEquality(FleeILGenerator ilg, LogicalCompareOperation op, IServiceProvider services)
        {
            // Get the StringComparison from the options
            ExpressionOptions   options = services.GetService(typeof(ExpressionOptions)) as ExpressionOptions;
            Int32LiteralElement ic      = new Int32LiteralElement((int)options.StringComparison);

            ic.Emit(ilg, services);

            // and emit the method call
            MethodInfo mi = typeof(string).GetMethod("Equals", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), typeof(string), typeof(StringComparison) }, null);

            ilg.Emit(OpCodes.Call, mi);

            if (op == LogicalCompareOperation.NotEqual)
            {
                ilg.Emit(OpCodes.Ldc_I4_0);
                ilg.Emit(OpCodes.Ceq);
            }
        }
        /// <summary>
        /// Create a variable
        /// </summary>
        /// <param name="variableValueType">The variable's type</param>
        /// <param name="variableValue">The actual value; may be null</param>
        /// <returns>A new variable for the value</returns>
        /// <remarks></remarks>
        private IVariable CreateVariable(Type variableValueType, object variableValue)
        {
            Type variableType = default(Type);

            // Is the variable value an expression?
            IExpression       expression = variableValue as IExpression;
            ExpressionOptions options    = null;

            if (expression != null)
            {
                options = expression.Context.Options;
                // Get its result type
                variableValueType = options.ResultType;
            }

            if (expression != null)
            {
                // Create a variable that wraps the expression

                if (options.IsGeneric == false)
                {
                    variableType = typeof(DynamicExpressionVariable <>);
                }
                else
                {
                    variableType = typeof(GenericExpressionVariable <>);
                }
            }
            else
            {
                // Create a variable for a regular value
                MyContext.AssertTypeIsAccessible(variableValueType);
                variableType = typeof(GenericVariable <>);
            }

            // Create the generic variable instance
            variableType = variableType.MakeGenericType(variableValueType);
            IVariable v = Activator.CreateInstance(variableType) as IVariable;

            return(v);
        }
示例#8
0
        private void Compile(string expression, ExpressionOptions options)
        {
            // Add the services that will be used by elements during the compile
            IServiceContainer services = new ServiceContainer();

            this.AddServices(services);

            // Parse and get the root element of the parse tree
            ExpressionElement topElement = MyContext.Parse(expression, services);

            if (options.ResultType == null)
            {
                options.ResultType = topElement.ResultType;
            }

            RootExpressionElement rootElement = new RootExpressionElement(topElement, options.ResultType);

            DynamicMethod dm = this.CreateDynamicMethod();

            FleeILGenerator ilg = new FleeILGenerator(dm.GetILGenerator(), 0, false);

            // Emit the IL
            rootElement.Emit(ilg, services);

            ilg.ValidateLength();

            // Emit to an assembly if required
            if (options.EmitToAssembly == true)
            {
                EmitToAssembly(rootElement, services);
            }

            Type delegateType = typeof(ExpressionEvaluator <>).MakeGenericType(typeof(T));

            MyEvaluator = dm.CreateDelegate(delegateType) as ExpressionEvaluator <T>;
        }
示例#9
0
        private static void EmitExplicitNumericCast(FleeILGenerator ilg, Type sourceType, Type destType, IServiceProvider services)
        {
            TypeCode          desttc   = Type.GetTypeCode(destType);
            TypeCode          sourcetc = Type.GetTypeCode(sourceType);
            bool              unsigned = IsUnsignedType(sourceType);
            ExpressionOptions options  = services.GetService(typeof(ExpressionOptions)) as ExpressionOptions;
            bool              @checked = options.Checked;
            OpCode            op       = OpCodes.Nop;

            switch (desttc)
            {
            case TypeCode.SByte:
                if (unsigned == true & @checked == true)
                {
                    op = OpCodes.Conv_Ovf_I1_Un;
                }
                else if (@checked == true)
                {
                    op = OpCodes.Conv_Ovf_I1;
                }
                else
                {
                    op = OpCodes.Conv_I1;
                }

                break;

            case TypeCode.Byte:
                if (unsigned == true & @checked == true)
                {
                    op = OpCodes.Conv_Ovf_U1_Un;
                }
                else if (@checked == true)
                {
                    op = OpCodes.Conv_Ovf_U1;
                }
                else
                {
                    op = OpCodes.Conv_U1;
                }

                break;

            case TypeCode.Int16:
                if (unsigned == true & @checked == true)
                {
                    op = OpCodes.Conv_Ovf_I2_Un;
                }
                else if (@checked == true)
                {
                    op = OpCodes.Conv_Ovf_I2;
                }
                else
                {
                    op = OpCodes.Conv_I2;
                }

                break;

            case TypeCode.UInt16:
                if (unsigned == true & @checked == true)
                {
                    op = OpCodes.Conv_Ovf_U2_Un;
                }
                else if (@checked == true)
                {
                    op = OpCodes.Conv_Ovf_U2;
                }
                else
                {
                    op = OpCodes.Conv_U2;
                }

                break;

            case TypeCode.Int32:
                if (unsigned == true & @checked == true)
                {
                    op = OpCodes.Conv_Ovf_I4_Un;
                }
                else if (@checked == true)
                {
                    op = OpCodes.Conv_Ovf_I4;
                }
                else if (sourcetc != TypeCode.UInt32)
                {
                    // Don't need to emit a convert for this case since, to the CLR, it is the same data type
                    op = OpCodes.Conv_I4;
                }

                break;

            case TypeCode.UInt32:
                if (unsigned == true & @checked == true)
                {
                    op = OpCodes.Conv_Ovf_U4_Un;
                }
                else if (@checked == true)
                {
                    op = OpCodes.Conv_Ovf_U4;
                }
                else if (sourcetc != TypeCode.Int32)
                {
                    op = OpCodes.Conv_U4;
                }

                break;

            case TypeCode.Int64:
                if (unsigned == true & @checked == true)
                {
                    op = OpCodes.Conv_Ovf_I8_Un;
                }
                else if (@checked == true)
                {
                    op = OpCodes.Conv_Ovf_I8;
                }
                else if (sourcetc != TypeCode.UInt64)
                {
                    op = OpCodes.Conv_I8;
                }

                break;

            case TypeCode.UInt64:
                if (unsigned == true & @checked == true)
                {
                    op = OpCodes.Conv_Ovf_U8_Un;
                }
                else if (@checked == true)
                {
                    op = OpCodes.Conv_Ovf_U8;
                }
                else if (sourcetc != TypeCode.Int64)
                {
                    op = OpCodes.Conv_U8;
                }

                break;

            case TypeCode.Single:
                op = OpCodes.Conv_R4;
                break;

            default:
                Debug.Assert(false, "Unknown cast dest type");
                break;
            }

            if (op.Equals(OpCodes.Nop) == false)
            {
                ilg.Emit(op);
            }
        }
示例#10
0
        // Emit an arithmetic operation with handling for unsigned and checked contexts
        private void EmitArithmeticOperation(BinaryArithmeticOperation op, FleeILGenerator ilg, IServiceProvider services)
        {
            ExpressionOptions options = services.GetService(typeof(ExpressionOptions)) as ExpressionOptions;
            bool unsigned             = IsUnsignedForArithmetic(MyLeftChild.ResultType) & IsUnsignedForArithmetic(MyRightChild.ResultType);
            bool integral             = Utility.IsIntegralType(MyLeftChild.ResultType) & Utility.IsIntegralType(MyRightChild.ResultType);
            bool emitOverflow         = integral & options.Checked;

            switch (op)
            {
            case BinaryArithmeticOperation.Add:
                if (emitOverflow == true)
                {
                    if (unsigned == true)
                    {
                        ilg.Emit(OpCodes.Add_Ovf_Un);
                    }
                    else
                    {
                        ilg.Emit(OpCodes.Add_Ovf);
                    }
                }
                else
                {
                    ilg.Emit(OpCodes.Add);
                }

                break;

            case BinaryArithmeticOperation.Subtract:
                if (emitOverflow == true)
                {
                    if (unsigned == true)
                    {
                        ilg.Emit(OpCodes.Sub_Ovf_Un);
                    }
                    else
                    {
                        ilg.Emit(OpCodes.Sub_Ovf);
                    }
                }
                else
                {
                    ilg.Emit(OpCodes.Sub);
                }

                break;

            case BinaryArithmeticOperation.Multiply:
                if (emitOverflow == true)
                {
                    if (unsigned == true)
                    {
                        ilg.Emit(OpCodes.Mul_Ovf_Un);
                    }
                    else
                    {
                        ilg.Emit(OpCodes.Mul_Ovf);
                    }
                }
                else
                {
                    ilg.Emit(OpCodes.Mul);
                }

                break;

            case BinaryArithmeticOperation.Divide:
                if (unsigned == true)
                {
                    ilg.Emit(OpCodes.Div_Un);
                }
                else
                {
                    ilg.Emit(OpCodes.Div);
                }

                break;

            case BinaryArithmeticOperation.Mod:
                if (unsigned == true)
                {
                    ilg.Emit(OpCodes.Rem_Un);
                }
                else
                {
                    ilg.Emit(OpCodes.Rem);
                }

                break;

            case BinaryArithmeticOperation.Power:
                ilg.Emit(OpCodes.Call, OurPowerMethodInfo);
                break;

            default:
                Debug.Fail("Unknown op type");
                break;
            }
        }
示例#11
0
        // Attempt to find the first type of integer that a number can fit into
        public static LiteralElement Create(string image, bool isHex, bool negated, IServiceProvider services)
        {
            StringComparison comparison = StringComparison.OrdinalIgnoreCase;

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

            // Convert to a double if option is set
            if (options.IntegersAsDoubles == true)
            {
                return(DoubleLiteralElement.Parse(image, services));
            }

            bool hasUSuffix  = image.EndsWith("u", comparison) & !image.EndsWith("lu", comparison);
            bool hasLSuffix  = image.EndsWith("l", comparison) & !image.EndsWith("ul", comparison);
            bool hasULSuffix = image.EndsWith("ul", comparison) | image.EndsWith("lu", comparison);
            bool hasSuffix   = hasUSuffix | hasLSuffix | hasULSuffix;

            LiteralElement constant  = default(LiteralElement);
            NumberStyles   numStyles = NumberStyles.Integer;

            if (isHex == true)
            {
                numStyles = NumberStyles.AllowHexSpecifier;
                image     = image.Remove(0, 2);
            }

            if (hasSuffix == false)
            {
                // If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong.
                constant = Int32LiteralElement.TryCreate(image, isHex, negated);

                if ((constant != null))
                {
                    return(constant);
                }

                constant = UInt32LiteralElement.TryCreate(image, numStyles);

                if ((constant != null))
                {
                    return(constant);
                }

                constant = Int64LiteralElement.TryCreate(image, isHex, negated);

                if ((constant != null))
                {
                    return(constant);
                }

                return(new UInt64LiteralElement(image, numStyles));
            }
            else if (hasUSuffix == true)
            {
                image = image.Remove(image.Length - 1);
                // If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong.

                constant = UInt32LiteralElement.TryCreate(image, numStyles);

                if ((constant != null))
                {
                    return(constant);
                }
                else
                {
                    return(new UInt64LiteralElement(image, numStyles));
                }
            }
            else if (hasLSuffix == true)
            {
                // If the literal is suffixed by L or l, it has the first of these types in which its value can be represented: long, ulong.
                image = image.Remove(image.Length - 1);

                constant = Int64LiteralElement.TryCreate(image, isHex, negated);

                if ((constant != null))
                {
                    return(constant);
                }
                else
                {
                    return(new UInt64LiteralElement(image, numStyles));
                }
            }
            else
            {
                // If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type ulong.
                Debug.Assert(hasULSuffix == true, "expecting ul suffix");
                image = image.Remove(image.Length - 2);
                return(new UInt64LiteralElement(image, numStyles));
            }
        }