示例#1
0
 public static Type GetBitwiseOpType(Type leftType, Type rightType)
 {
     if (IsIntegralType(leftType) == false || IsIntegralType(rightType) == false)
     {
         return(null);
     }
     else
     {
         return(ImplicitConverter.GetBinaryResultType(leftType, rightType));
     }
 }
示例#2
0
        private static int ComputeSum(ParameterInfo[] parameters, Type[] argTypes)
        {
            Debug.Assert(parameters.Length == argTypes.Length);
            int sum = 0;

            for (int i = 0; i <= parameters.Length - 1; i++)
            {
                sum += ImplicitConverter.GetImplicitConvertScore(argTypes[i], parameters[i].ParameterType);
            }

            return(sum);
        }
示例#3
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);
        }
示例#4
0
        private void SetupArrayIndexer()
        {
            MyIndexerElement = MyIndexerElements[0];

            if (MyIndexerElements.Count > 1)
            {
                base.ThrowCompileException(CompileErrorResourceKeys.MultiArrayIndexNotSupported, CompileExceptionReason.TypeMismatch);
            }
            else if (ImplicitConverter.EmitImplicitConvert(MyIndexerElement.ResultType, typeof(Int32), null) == false)
            {
                base.ThrowCompileException(CompileErrorResourceKeys.ArrayIndexersMustBeOfType, CompileExceptionReason.TypeMismatch, typeof(Int32).Name);
            }
        }
示例#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
        // Emit the arguments to a regular method call
        private void EmitRegularFunctionInternal(ParameterInfo[] parameters, ExpressionElement[] elements, FleeILGenerator ilg, IServiceProvider services)
        {
            Debug.Assert(parameters.Length == elements.Length, "argument count mismatch");

            // Emit each element and any required conversions to the actual parameter type
            for (int i = 0; i <= parameters.Length - 1; i++)
            {
                ExpressionElement element = elements[i];
                ParameterInfo     pi      = parameters[i];
                element.Emit(ilg, services);
                bool success = ImplicitConverter.EmitImplicitConvert(element.ResultType, pi.ParameterType, ilg);
                Debug.Assert(success, "conversion failed");
            }
        }
示例#7
0
        private static bool AreValidArgumentsForParameters(Type[] argTypes, ParameterInfo[] parameters)
        {
            Debug.Assert(argTypes.Length == parameters.Length);
            // Match if every given argument is implicitly convertible to the method's corresponding parameter
            for (int i = 0; i <= argTypes.Length - 1; i++)
            {
                if (ImplicitConverter.EmitImplicitConvert(argTypes[i], parameters[i].ParameterType, null) == false)
                {
                    return(false);
                }
            }

            return(true);
        }
示例#8
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);
                    }
                }
            }
        }
示例#9
0
        public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, System.Type[] types, ParameterModifier[] modifiers)
        {
            foreach (MethodInfo mi in match)
            {
                ParameterInfo[] parameters = mi.GetParameters();
                bool            leftValid  = ImplicitConverter.EmitImplicitConvert(MyLeftType, parameters[0].ParameterType, null);
                bool            rightValid = ImplicitConverter.EmitImplicitConvert(MyRightType, parameters[1].ParameterType, null);

                if (leftValid == true & rightValid == true)
                {
                    return(mi);
                }
            }
            return(null);
        }
示例#10
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);
        }
示例#11
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);
            }
        }
示例#12
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            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);
            }
        }
示例#13
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            Type resultType = this.ResultType;

            MyChild.Emit(ilg, services);
            ImplicitConverter.EmitImplicitConvert(MyChild.ResultType, resultType, ilg);

            MethodInfo mi = Utility.GetSimpleOverloadedOperator("UnaryNegation", resultType, resultType);

            if (mi == null)
            {
                ilg.Emit(OpCodes.Neg);
            }
            else
            {
                ilg.Emit(OpCodes.Call, mi);
            }
        }
示例#14
0
        private void ResolveForCollectionSearch()
        {
            // Try to find a collection type
            MyTargetCollectionType = this.GetTargetCollectionType();

            if (MyTargetCollectionType == null)
            {
                base.ThrowCompileException(CompileErrorResourceKeys.SearchArgIsNotKnownCollectionType, CompileExceptionReason.TypeMismatch, MyTargetCollectionElement.ResultType.Name);
            }

            // Validate that the operand type is compatible with the collection
            MethodInfo    mi = this.GetCollectionContainsMethod();
            ParameterInfo p1 = mi.GetParameters()[0];

            if (ImplicitConverter.EmitImplicitConvert(MyOperand.ResultType, p1.ParameterType, null) == false)
            {
                base.ThrowCompileException(CompileErrorResourceKeys.OperandNotConvertibleToCollectionType, CompileExceptionReason.TypeMismatch, MyOperand.ResultType.Name, p1.ParameterType.Name);
            }
        }
示例#15
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            Type       binaryResultType   = ImplicitConverter.GetBinaryResultType(MyLeftChild.ResultType, MyRightChild.ResultType);
            MethodInfo overloadedOperator = this.GetOverloadedCompareOperator();

            if (this.AreBothChildrenOfType(typeof(string)))
            {
                // String equality
                MyLeftChild.Emit(ilg, services);
                MyRightChild.Emit(ilg, services);
                EmitStringEquality(ilg, MyOperation, services);
            }
            else if ((overloadedOperator != null))
            {
                base.EmitOverloadedOperatorCall(overloadedOperator, ilg, services);
            }
            else if ((binaryResultType != null))
            {
                // Emit a compare of numeric operands
                EmitChildWithConvert(MyLeftChild, binaryResultType, ilg, services);
                EmitChildWithConvert(MyRightChild, binaryResultType, ilg, services);
                EmitCompareOperation(ilg, MyOperation);
            }
            else if (this.AreBothChildrenOfType(typeof(bool)))
            {
                // Boolean equality
                this.EmitRegular(ilg, services);
            }
            else if (this.AreBothChildrenReferenceTypes() == true)
            {
                // Reference equality
                this.EmitRegular(ilg, services);
            }
            else if (MyLeftChild.ResultType.IsEnum == true & MyRightChild.ResultType.IsEnum == true)
            {
                this.EmitRegular(ilg, services);
            }
            else
            {
                Debug.Fail("unknown operand types");
            }
        }
示例#16
0
        protected override System.Type GetResultType(System.Type leftType, System.Type rightType)
        {
            Type       binaryResultType   = ImplicitConverter.GetBinaryResultType(leftType, rightType);
            MethodInfo overloadedOperator = this.GetOverloadedCompareOperator();
            bool       isEqualityOp       = IsOpTypeEqualOrNotEqual(MyOperation);

            // Use our string equality instead of overloaded operator
            if (object.ReferenceEquals(leftType, typeof(string)) & object.ReferenceEquals(rightType, typeof(string)) & isEqualityOp == true)
            {
                // String equality
                return(typeof(bool));
            }
            else if ((overloadedOperator != null))
            {
                return(overloadedOperator.ReturnType);
            }
            else if ((binaryResultType != null))
            {
                // Comparison of numeric operands
                return(typeof(bool));
            }
            else if (object.ReferenceEquals(leftType, typeof(bool)) & object.ReferenceEquals(rightType, typeof(bool)) & isEqualityOp == true)
            {
                // Boolean equality
                return(typeof(bool));
            }
            else if (this.AreBothChildrenReferenceTypes() == true & isEqualityOp == true)
            {
                // Comparison of reference types
                return(typeof(bool));
            }
            else if (this.AreBothChildrenSameEnum() == true)
            {
                return(typeof(bool));
            }
            else
            {
                // Invalid operands
                return(null);
            }
        }
示例#17
0
        private bool IsParamArrayMatch(Type[] argTypes, ParameterInfo[] parameters, ParameterInfo paramArrayParameter)
        {
            // Get the count of arguments before the paramArray parameter
            int fixedParameterCount = paramArrayParameter.Position;

            Type[]          fixedArgTypes   = new Type[fixedParameterCount];
            ParameterInfo[] fixedParameters = new ParameterInfo[fixedParameterCount];

            // Get the argument types and parameters before the paramArray
            System.Array.Copy(argTypes, fixedArgTypes, fixedParameterCount);
            System.Array.Copy(parameters, fixedParameters, fixedParameterCount);

            // If the fixed arguments don't match, we are not a match
            if (AreValidArgumentsForParameters(fixedArgTypes, fixedParameters) == false)
            {
                return(false);
            }

            // Get the type of the paramArray
            ParamArrayElementType = paramArrayParameter.ParameterType.GetElementType();

            // Get the types of the arguments passed to the paramArray
            Type[] paramArrayArgTypes = new Type[argTypes.Length - fixedParameterCount];
            System.Array.Copy(argTypes, fixedParameterCount, paramArrayArgTypes, 0, paramArrayArgTypes.Length);

            // Check each argument
            foreach (Type argType in paramArrayArgTypes)
            {
                if (ImplicitConverter.EmitImplicitConvert(argType, ParamArrayElementType, null) == false)
                {
                    return(false);
                }
            }

            MyFixedArgTypes      = fixedArgTypes;
            MyParamArrayArgTypes = paramArrayArgTypes;

            // They all match, so we are a match
            return(true);
        }
示例#18
0
        protected override System.Type GetResultType(System.Type leftType, System.Type rightType)
        {
            // Right argument (shift count) must be convertible to int32
            if (ImplicitConverter.EmitImplicitNumericConvert(rightType, typeof(Int32), null) == false)
            {
                return(null);
            }

            // Left argument must be an integer type
            if (Utility.IsIntegralType(leftType) == false)
            {
                return(null);
            }

            TypeCode tc = Type.GetTypeCode(leftType);

            switch (tc)
            {
            case TypeCode.Byte:
            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
                return(typeof(Int32));

            case TypeCode.UInt32:
                return(typeof(UInt32));

            case TypeCode.Int64:
                return(typeof(Int64));

            case TypeCode.UInt64:
                return(typeof(UInt64));

            default:
                Debug.Assert(false, "unknown left shift operand");
                return(null);
            }
        }
示例#19
0
        // Load a PropertyDescriptor based property
        private void EmitVirtualPropertyLoad(FleeILGenerator ilg)
        {
            // The previous value is already on the top of the stack but we need it at the bottom

            // Get a temporary local index
            int index = ilg.GetTempLocalIndex(MyPrevious.ResultType);

            // Store the previous value there
            Utility.EmitStoreLocal(ilg, index);

            // Load the variable collection
            EmitLoadVariables(ilg);
            // Load the property name
            ilg.Emit(OpCodes.Ldstr, MyName);

            // Load the previous value and convert it to object
            Utility.EmitLoadLocal(ilg, index);
            ImplicitConverter.EmitImplicitConvert(MyPrevious.ResultType, typeof(object), ilg);

            // Call the method to get the actual value
            MethodInfo mi = VariableCollection.GetVirtualPropertyLoadMethod(this.ResultType);

            this.EmitMethodCall(mi, ilg);
        }