public void Assign(Operand target, Operand value, bool allowExplicitConversion)
		{
			if ((object)target == null)
				throw new ArgumentNullException("target");

			BeforeStatement();

			target.Assign(value, allowExplicitConversion).Emit(this);
		}
		public void AssignDivide(Operand target, Operand value)
		{
			if ((object)target == null)
				throw new ArgumentNullException("target");

			BeforeStatement();

			target.AssignDivide(value).Emit(this);
		}
Ejemplo n.º 3
0
 internal static void SetLeakedState(Operand[] operands, bool state)
 {
     if (operands != null)
     {
         for (int i = 0; i < operands.Length; i++)
         {
             OperandExtensions.SetLeakedState(operands[i], state);
         }
     }
 }
		public void EmitArgs(CodeGen g, Operand[] args)
		{
			if (args.Length != appliedSignature.Length)
				throw new InvalidOperationException();

			if (IsExpanded)
			{
				int fixedCount = methodSignature.Length - 1;
				Type expType = methodSignature[fixedCount].GetElementType();

				for (int i = 0; i < fixedCount; i++)
					EmitArg(g, i, args[i]);

				int arrayLen = args.Length - methodSignature.Length - 1;
				g.EmitI4Helper(arrayLen);
				g.IL.Emit(OpCodes.Newarr, expType);
				OpCode stelemCode = CodeGen.GetStelemOpCode(expType);
				for (int i = 0; i < arrayLen; i++)
				{
					g.IL.Emit(OpCodes.Dup);
					g.EmitI4Helper(i);
					if (stelemCode == OpCodes.Stobj)
						g.IL.Emit(OpCodes.Ldelema, expType);
					EmitArg(g, fixedCount + i, args[fixedCount + i]);
					if (stelemCode == OpCodes.Stobj)
						g.IL.Emit(OpCodes.Stobj, expType);
					else
						g.IL.Emit(stelemCode);
				}
			}
			else
			{
				for (int i = 0; i < args.Length; i++)
					EmitArg(g, i, args[i]);
			}
		}
Ejemplo n.º 5
0
		public static Conversion GetExplicit(Operand op, Type to, bool onlyStandard, ITypeMapper typeMapper)
		{
			// try implicit
			Conversion conv = GetImplicit(op, to, onlyStandard, typeMapper);
			if (conv.IsValid)
				return conv;

			Type from = Operand.GetType(op, typeMapper);

		    Type fromUnderlying = Helpers.GetNullableUnderlyingType(@from);
		    if (fromUnderlying == to)
                return new UnwrapNullable(typeMapper);


            Type toUnderlying = Helpers.GetNullableUnderlyingType(to);
            if (toUnderlying != null && fromUnderlying != null)
            {
                var c = GetExplicit(new FakeTypedOperand(fromUnderlying), toUnderlying, onlyStandard, typeMapper);
                if (c.IsValid) return new ConvertNullable(typeMapper, c);
            }


		    // section 6.3.2 - Standard explicit conversions
            if (onlyStandard)
			{
				if (from == null || !GetImplicit(to, @from, true, typeMapper).IsValid)
					return new Invalid(typeMapper);
			}

			TypeCode tcFrom = Type.GetTypeCode(from);
			TypeCode tcTo = Type.GetTypeCode(to);
			byte ct = _convTable[(int)tcFrom][(int)tcTo];

			// section 6.2.1 - Explicit numeric conversions, 6.2.2 - Explicit enumeration conversions
			if ((from.IsPrimitive || from.IsEnum || Helpers.AreTypesEqual(from, typeof(decimal), typeMapper)) && (to.IsPrimitive || to.IsEnum || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper)))
			{
				if (ct == D)
					return new Direct(typeMapper);	// this can happen for conversions involving enum-s

				if (ct <= E)
				{
				    if (Helpers.AreTypesEqual(from, typeof(decimal), typeMapper) || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper))
						// decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
						onlyStandard = false;
					else
                        return new Primitive(typeMapper);
				}
			}

			// section 6.2.5 - User-defined explicit conversions (details in section 6.4.4)
		    if (!(onlyStandard || Helpers.AreTypesEqual(from, typeof(object), typeMapper) || Helpers.AreTypesEqual(to, typeof(object), typeMapper) || from.IsInterface || to.IsInterface ||
				to.IsSubclassOf(from) || from.IsSubclassOf(to)))
			{
				List<UserDefined> candidates = null;
				FindCandidates(ref candidates, FindExplicitMethods(from, to, typeMapper), op, to, GetExplicit, typeMapper);

				if (candidates != null)
				{
					if (candidates.Count == 1)
						return candidates[0];

					return UserDefined.FindExplicit(candidates, @from, to, typeMapper);
				}
			}

			// section 6.2.3 - Explicit reference conversions, 6.2.4 - Unboxing conversions
			// TODO: not really according to spec, but mostly works
			if (!from.IsValueType && from.IsAssignableFrom(to))
			{
				if (to.IsValueType)
					return new Unboxing(typeMapper);
				else
					return new Cast(typeMapper);
			}

			return new Invalid(typeMapper);
		}
Ejemplo n.º 6
0
 void DoInvoke(Operand invocation)
 {
     Eval(invocation);
 }
		// the sections mentioned in comments of this method are from C# specification v1.2
		public static Conversion GetImplicit(Operand op, Type to, bool onlyStandard)
		{
			Type from = Operand.GetType(op);

			if (to.Equals(from))
				return Direct.Instance;

			// required for arrays created from TypeBuilder-s
			if (from != null && to.IsArray && from.IsArray)
			{
				if (to.GetArrayRank() == from.GetArrayRank())
				{
					if (to.GetElementType().Equals(from.GetElementType()))
						return Direct.Instance;
				}
			}

			TypeCode tcFrom = Type.GetTypeCode(from);
			TypeCode tcTo = Type.GetTypeCode(to);
			byte ct = convTable[(int)tcFrom][(int)tcTo];

			// section 6.1.2 - Implicit numeric conversions
			if ((from != null && (from.IsPrimitive || from == typeof(decimal))) && (to.IsPrimitive || to == typeof(decimal)))
			{
				if (ct <= I)
				{
					if (from == typeof(decimal) || to == typeof(decimal))
						// decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
						onlyStandard = false;
					else
						return Primitive.Instance;
				}
			}

			IntLiteral intLit = op as IntLiteral;

			// section 6.1.3 - Implicit enumeration conversions
			if (!onlyStandard && to.IsEnum && (object)intLit != null && intLit.Value == 0)
				return Primitive.Instance;

			// section 6.1.4 - Implicit reference conversions
			if ((from == null || !from.IsValueType) && !to.IsValueType)
			{
				if (from == null) // from the null type to any reference type
					return Direct.Instance;

				if (to.IsAssignableFrom(from))	// the rest
					return Direct.Instance;
			}

			if (from == null)	// no other conversion from null type is possible
				return Invalid.Instance;

			// section 6.1.5 - Boxing conversions
			if (from.IsValueType)
			{
				if (to.IsAssignableFrom(from))
					return Boxing.Instance;
			}

			// section 6.1.6 - Implicit constant expression conversions
			if ((object)intLit != null && from == typeof(int) && to.IsPrimitive)
			{
				int val = intLit.Value;

				switch (tcTo)
				{
					case TypeCode.SByte:
						if (val >= sbyte.MinValue && val <= sbyte.MaxValue)
							return Direct.Instance;
						break;
					case TypeCode.Byte:
						if (val >= byte.MinValue && val <= byte.MaxValue)
							return Direct.Instance;
						break;
					case TypeCode.Int16:
						if (val >= short.MinValue && val <= short.MaxValue)
							return Direct.Instance;
						break;
					case TypeCode.UInt16:
						if (val >= ushort.MinValue && val <= ushort.MaxValue)
							return Direct.Instance;
						break;
					case TypeCode.UInt32:
						if (val >= 0)
							return Direct.Instance;
						break;
					case TypeCode.UInt64:
						if (val >= 0)
							return Primitive.Instance;
						break;
				}
			}
			if (from == typeof(long))
			{
				LongLiteral longLit = op as LongLiteral;
				if ((object)longLit != null && longLit.Value > 0)
					return Direct.Instance;
			}

			// section 6.1.7 - User-defined implicit conversions (details in section 6.4.3)
			if (onlyStandard || from == typeof(object) || to == typeof(object) || from.IsInterface || to.IsInterface ||
				to.IsSubclassOf(from) || from.IsSubclassOf(to))
				return Invalid.Instance;	// skip not-permitted conversion attempts (section 6.4.1)

			List<UserDefined> candidates = null;
			FindCandidates(ref candidates, FindImplicitMethods(from, to), op, to, GetImplicit);

			if (candidates == null)
				return Invalid.Instance;

			if (candidates.Count == 1)
				return candidates[0];

			return UserDefined.FindImplicit(candidates, from, to);
		}
Ejemplo n.º 8
0
        // the sections mentioned in comments of this method are from C# specification v1.2
		public static Conversion GetImplicit(Operand op, Type to, bool onlyStandard, ITypeMapper typeMapper)
		{
			Type from = Operand.GetType(op, typeMapper);

            Type toUnderlying = Helpers.GetNullableUnderlyingType(to);
		    if (to.Equals(from))
		        return new Direct(typeMapper);

            Type fromUnderlying = Helpers.GetNullableUnderlyingType(@from);
		    if (toUnderlying != null)
		    {
		        if (fromUnderlying != null)
		        {
		            Conversion c = GetImplicit(new FakeTypedOperand(fromUnderlying), toUnderlying, onlyStandard, typeMapper);
		            if (c.IsValid) return new ConvertNullable(typeMapper, c);
		        }
		        else
		        {
                    Conversion c = GetImplicit(op, toUnderlying, onlyStandard, typeMapper);
                    if (c.IsValid) return new WrapNullable(typeMapper, c);
                }
		    }
            
		    // required for arrays created from TypeBuilder-s
			if (from != null && to.IsArray && from.IsArray)
			{
				if (to.GetArrayRank() == from.GetArrayRank())
				{
					if (to.GetElementType().Equals(from.GetElementType()))
						return new Direct(typeMapper);
				}
			}

			TypeCode tcFrom = Type.GetTypeCode(from);
			TypeCode tcTo = Type.GetTypeCode(to);
			byte ct = _convTable[(int)tcFrom][(int)tcTo];

			// section 6.1.2 - Implicit numeric conversions
			if (from != null && (from.IsPrimitive || Helpers.AreTypesEqual(from, typeof(decimal), typeMapper)) && (to.IsPrimitive || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper)))
			{
				if (ct <= I)
				{
				    if (Helpers.AreTypesEqual(from, typeof(decimal), typeMapper) || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper))
						// decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
						onlyStandard = false;
					else
						return new Primitive(typeMapper);
				}
			}

			IntLiteral intLit = op as IntLiteral;

			// section 6.1.3 - Implicit enumeration conversions
			if (!onlyStandard && to.IsEnum && (object)intLit != null && intLit.Value == 0)
				return new Primitive(typeMapper);

			// section 6.1.4 - Implicit reference conversions
			if ((from == null || !from.IsValueType) && !to.IsValueType)
			{
				if (from == null) // from the null type to any reference type
					return new Direct(typeMapper);

				if (to.IsAssignableFrom(from))	// the rest
					return new Direct(typeMapper);
			}

			if (from == null)	// no other conversion from null type is possible
				return new Invalid(typeMapper);

			// section 6.1.5 - Boxing conversions
			if (from.IsValueType)
			{
				if (to.IsAssignableFrom(from))
					return new Boxing(typeMapper);
			}

			// section 6.1.6 - Implicit constant expression conversions
			if ((object)intLit != null && Helpers.AreTypesEqual(from, typeof(int), typeMapper) && to.IsPrimitive)
			{
				int val = intLit.Value;

				switch (tcTo)
				{
					case TypeCode.SByte:
						if (val >= sbyte.MinValue && val <= sbyte.MaxValue)
							return new Direct(typeMapper);
						break;
					case TypeCode.Byte:
						if (val >= byte.MinValue && val <= byte.MaxValue)
                            return new Direct(typeMapper);
                        break;
					case TypeCode.Int16:
						if (val >= short.MinValue && val <= short.MaxValue)
                            return new Direct(typeMapper);
                        break;
					case TypeCode.UInt16:
						if (val >= ushort.MinValue && val <= ushort.MaxValue)
                            return new Direct(typeMapper);
                        break;
					case TypeCode.UInt32:
						if (val >= 0)
                            return new Direct(typeMapper);
                        break;
					case TypeCode.UInt64:
						if (val >= 0)
                            return new Direct(typeMapper);
                        break;
				}
			}

			// section 6.1.7 - User-defined implicit conversions (details in section 6.4.3)
			if (onlyStandard || Helpers.AreTypesEqual(from, typeof(object), typeMapper) || Helpers.AreTypesEqual(to, typeof(object), typeMapper) || from.IsInterface || to.IsInterface ||
				to.IsSubclassOf(from) || from.IsSubclassOf(to))
                return new Invalid(typeMapper);  // skip not-permitted conversion attempts (section 6.4.1)

            List<UserDefined> candidates = null;
			FindCandidates(ref candidates, FindImplicitMethods(from, to, typeMapper), op, to, GetImplicit, typeMapper);

			if (candidates == null)
                return new Invalid(typeMapper);

            if (candidates.Count == 1)
				return candidates[0];

			return UserDefined.FindImplicit(candidates, @from, to, typeMapper);
		}
Ejemplo n.º 9
0
        protected internal static Type GetType(Operand op, ITypeMapper typeMapper)
		{
			if ((object)op == null)
				return null;

			return op.GetReturnType(typeMapper);
		}
Ejemplo n.º 10
0
        protected internal virtual void EmitSet(CodeGen g, Operand value, bool allowExplicitConversion)
		{
			throw new InvalidOperationException(string.Format(null, Properties.Messages.ErrOperandNotWritable, GetType()));
		}
Ejemplo n.º 11
0
		public Operand LogicalAnd(Operand other)
		{
            return OperandExtensions.SetLeakedState(Conditional(other, false), true);
		}
Ejemplo n.º 12
0
	    protected void EmitGetHelper(CodeGen g, Operand op, Type desiredType, bool allowExplicitConversion)
	    {
            g.EmitGetHelper(op, desiredType,allowExplicitConversion);
	    }
Ejemplo n.º 13
0
		public Operand Multiply(Operand value)
		{
			return OperandExtensions.SetLeakedState(new OverloadableOperation(Operator.Multiply, this, value), true);
		}
Ejemplo n.º 14
0
		public Operand Xor(Operand value)
		{
			return OperandExtensions.SetLeakedState(new OverloadableOperation(Operator.Xor, this, value), true);
		}
Ejemplo n.º 15
0
 public void Invoke(Operand target, MethodInfo method, params Operand[] args)
 {
     DoInvoke(target.Invoke(method, TypeMapper, args));
 }
Ejemplo n.º 16
0
 public void Invoke(Operand target, string method)
 {
     Invoke(target, method, Operand.EmptyArray);
 }
Ejemplo n.º 17
0
 public void DebugAssert(Operand condition, Operand message)
 {
     Invoke(TypeMapper.MapType(typeof(System.Diagnostics.Debug)), "Assert", condition, message);
 }
Ejemplo n.º 18
0
 public void DebugWriteLine(Operand message)
 {
     Invoke(TypeMapper.MapType(typeof(System.Diagnostics.Debug)), "WriteLine", message);
 }
Ejemplo n.º 19
0
 public void InvokeDelegate(Operand targetDelegate)
 {
     InvokeDelegate(targetDelegate, Operand.EmptyArray);
 }
Ejemplo n.º 20
0
		public Operand BitwiseAnd(Operand value)
		{
			return OperandExtensions.SetLeakedState(new OverloadableOperation(Operator.And, this, value), true);
		}
Ejemplo n.º 21
0
		public IStatement AssignXor(Operand value)
		{
			return Assign(Xor(value));
		}
Ejemplo n.º 22
0
		public Operand RightShift(Operand value)
		{
			return OperandExtensions.SetLeakedState(new OverloadableOperation(Operator.RightShift, this, value), true);
		}
Ejemplo n.º 23
0
		public IStatement AssignLeftShift(Operand value)
		{
			return Assign(LeftShift(value));
		}
Ejemplo n.º 24
0
		public Operand LogicalOr(Operand other)
		{
			return OperandExtensions.SetLeakedState(Conditional(true, other), true);
		}
Ejemplo n.º 25
0
		public IStatement AssignRightShift(Operand value)
		{
			return Assign(RightShift(value));
		}
Ejemplo n.º 26
0
		public Operand Conditional(Operand ifTrue, Operand ifFalse)
		{
			return OperandExtensions.SetLeakedState(new Conditional(this, ifTrue, ifFalse), true);
		}
Ejemplo n.º 27
0
	    public ContextualOperand InvokeEquals(Operand right, ITypeMapper typeMapper)
	    {
            Operand left = this;
            var args = new Operand[] { left, right };
            return OperandExtensions.SetLeakedState(new ContextualOperand(new Invocation(typeMapper.TypeInfo.FindMethod(typeMapper.MapType(typeof(object)), "Equals", args, true), null, args), typeMapper), true);
        }
Ejemplo n.º 28
0
        protected internal static Type[] GetTypes(Operand[] ops, ITypeMapper typeMapper)
		{
			if (ops == null)
				return null;

			Type[] types = new Type[ops.Length];
			for (int i = 0; i < ops.Length; i++)
				types[i] = (object)ops[i] == null ? null : ops[i].GetReturnType(typeMapper);

			return types;
		}
Ejemplo n.º 29
0
		public Operand Ne(Operand value)
		{
			return new OverloadableOperation(Operator.Inequality, this, value);
		}
Ejemplo n.º 30
0
            public Reference(Operand op)
		    {
		        _op = op;
		    }
Ejemplo n.º 31
0
		public Operand Ge(Operand value)
		{
			return new OverloadableOperation(Operator.GreaterThanOrEqual, this, value);
		}
		public static Conversion GetExplicit(Operand op, Type to, bool onlyStandard)
		{
			// try implicit
			Conversion conv = GetImplicit(op, to, onlyStandard);
			if (conv.IsValid)
				return conv;

			Type from = Operand.GetType(op);

			// section 6.3.2 - Standard explicit conversions
			if (onlyStandard)
			{
				if (from == null || !GetImplicit(to, from, true).IsValid)
					return Invalid.Instance;
			}

			TypeCode tcFrom = Type.GetTypeCode(from);
			TypeCode tcTo = Type.GetTypeCode(to);
			byte ct = convTable[(int)tcFrom][(int)tcTo];

			// section 6.2.1 - Explicit numeric conversions, 6.2.2 - Explicit enumeration conversions
			if ((from.IsPrimitive || from.IsEnum || from == typeof(decimal)) && (to.IsPrimitive || to.IsEnum || to == typeof(decimal)))
			{
				if (ct == D)
					return Direct.Instance;	// this can happen for conversions involving enum-s

				if (ct <= E)
				{
					if (from == typeof(decimal) || to == typeof(decimal))
						// decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
						onlyStandard = false;
					else
						return Primitive.Instance;
				}
			}

			// section 6.2.5 - User-defined explicit conversions (details in section 6.4.4)
			if (!(onlyStandard || from == typeof(object) || to == typeof(object) || from.IsInterface || to.IsInterface ||
				to.IsSubclassOf(from) || from.IsSubclassOf(to)))
			{
				List<UserDefined> candidates = null;
				FindCandidates(ref candidates, FindExplicitMethods(from, to), op, to, GetExplicit);

				if (candidates != null)
				{
					if (candidates.Count == 1)
						return candidates[0];

					return UserDefined.FindExplicit(candidates, from, to);
				}
			}

			// section 6.2.3 - Explicit reference conversions, 6.2.4 - Unboxing conversions
			// TODO: not really according to spec, but mostly works
			if (!from.IsValueType && from.IsAssignableFrom(to))
			{
				if (to.IsValueType)
					return Unboxing.Instance;
				else
					return Cast.Instance;
			}

			return Invalid.Instance;
		}
Ejemplo n.º 33
0
		public Operand Le(Operand value)
		{
			return new OverloadableOperation(Operator.LessThanOrEqual, this, value);
		}
Ejemplo n.º 34
0
		static void FindCandidates(ref List<UserDefined> candidates, IEnumerable<IMemberInfo> methods, Operand from, Type to, ConversionProvider extraConv, ITypeMapper typeMapper)
		{
			foreach (IMemberInfo mi in methods)
			{
				Conversion before = extraConv(from, mi.ParameterTypes[0], true, typeMapper);
				if (!before.IsValid)
					continue;

				Conversion after = extraConv(new FakeTypedOperand(mi.ReturnType), to, true, typeMapper);
				if (!after.IsValid)
					continue;

				if (candidates == null)
					candidates = new List<UserDefined>();

				candidates.Add(new UserDefined(before, mi, after, typeMapper));
			}
		}
Ejemplo n.º 35
0
		public Operand Subtract(Operand value)
		{
			return OperandExtensions.SetLeakedState(new OverloadableOperation(Operator.Subtract, this, value), true);
		}
		internal AttributeGen(AttributeTargets target, AttributeType attributeType, object[] args)
		{
			if (args != null)
			{
				foreach (object arg in args)
				{
					CheckValue(arg);
				}
			}

			// TODO: target validation

			this.attributeType = attributeType;

			Operand[] argOperands;
			if (args == null || args.Length == 0)
			{
				this.args = EmptyArray<object>.Instance;
				argOperands = Operand.EmptyArray;
			}
			else
			{
				this.args = args;
				argOperands = new Operand[args.Length];
				for (int i = 0; i < args.Length; i++)
				{
					argOperands[i] = GetOperand(args[i]);
				}
			}

			this.ctor = TypeInfo.FindConstructor(attributeType, argOperands);
		}
Ejemplo n.º 37
0
 public ForeachBlock(Type elementType, Operand collection, ITypeMapper typeMapper)
 {
     _elementType = elementType;
     _collection  = collection;
     _typeMapper  = typeMapper;
 }