public static Type GetBitwiseOpType(Type leftType, Type rightType) { if (IsIntegralType(leftType) == false || IsIntegralType(rightType) == false) { return(null); } else { return(ImplicitConverter.GetBinaryResultType(leftType, rightType)); } }
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); }
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); }
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); } }
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); }
// 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"); } }
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); }
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); } } } }
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); }
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); }
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); } }
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); } }
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); } }
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); } }
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"); } }
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); } }
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); }
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); } }
// 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); }