Beispiel #1
0
        public override void Emit(FleeILGenerator ilg, IServiceProvider services)
        {
            var binaryResultType = ImplicitConverter.GetBinaryResultType(MyLeftChild.ResultType, MyRightChild.ResultType);
            var 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");
            }
        }
Beispiel #2
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);
			}
		}
Beispiel #3
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);
			}
		}
Beispiel #4
0
		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);
			}
		}
Beispiel #5
0
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			var 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);
		}
Beispiel #6
0
		public static void EmitLoad(Int32 value, FleeILGenerator ilg)
		{
			if (value >= -1 & value <= 8) {
				EmitSuperShort(value, ilg);
			} else if (value >= sbyte.MinValue & value <= sbyte.MaxValue) {
				ilg.Emit(OpCodes.Ldc_I4_S, Convert.ToSByte(value));
			} else {
				ilg.Emit(OpCodes.Ldc_I4, value);
			}
		}
Beispiel #7
0
		protected static void EmitLoad(Int64 value, FleeILGenerator ilg)
		{
			if (value >= Int32.MinValue & value <= Int32.MaxValue) {
				EmitLoad((int)value, ilg);
				ilg.Emit(OpCodes.Conv_I8);
			} else if (value >= 0 & value <= UInt32.MaxValue) {
				EmitLoad((int)value, ilg);
				ilg.Emit(OpCodes.Conv_U8);
			} else {
				ilg.Emit(OpCodes.Ldc_I8, value);
			}
		}
Beispiel #8
0
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			MyChild.Emit(ilg, services);
			ImplicitConverter.EmitImplicitConvert(MyChild.ResultType, MyResultType, ilg);

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

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

			ilg.Emit(OpCodes.Ret);
		}
Beispiel #9
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);
			}
		}
Beispiel #10
0
		public override void Emit(FleeILGenerator ilg, System.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);
		}
Beispiel #11
0
 private static void EmitBitwiseOperation(FleeILGenerator ilg, AndOrOperation op)
 {
     switch (op)
     {
         case AndOrOperation.And:
         	ilg.Emit(OpCodes.And);
             break;
         case AndOrOperation.Or:
             ilg.Emit(OpCodes.Or);
             break;
         default:
             Debug.Fail("Unknown op type");
             break;
     }
 }
Beispiel #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);
        }
    }
Beispiel #13
0
		private void EmitConditional(FleeILGenerator ilg, IServiceProvider services, BranchManager bm)
		{
			var falseLabel = bm.FindLabel("falseLabel");
			var 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);
		}
Beispiel #14
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);
		}
Beispiel #15
0
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			int index = ilg.GetTempLocalIndex(typeof(decimal));
			Utility.EmitLoadLocalAddress(ilg, index);

			int[] bits = decimal.GetBits(MyValue);
			EmitLoad(bits[0], ilg);
			EmitLoad(bits[1], ilg);
			EmitLoad(bits[2], ilg);

			int flags = bits[3];

			EmitLoad((flags >> 31) == -1, ilg);

			EmitLoad(flags >> 16, ilg);

			ilg.Emit(OpCodes.Call, OurConstructorInfo);

			Utility.EmitLoadLocal(ilg, index);
		}
Beispiel #16
0
		public static void EmitStoreLocal(FleeILGenerator ilg, int index)
		{
			if (index >= 0 & index <= 3) {
				switch (index) {
					case 0:
						ilg.Emit(OpCodes.Stloc_0);
						break;
					case 1:
						ilg.Emit(OpCodes.Stloc_1);
						break;
					case 2:
						ilg.Emit(OpCodes.Stloc_2);
						break;
					case 3:
						ilg.Emit(OpCodes.Stloc_3);
						break;
				}
			} else {
				Debug.Assert(index < 256, "local index too large");
				ilg.Emit(OpCodes.Stloc_S, Convert.ToByte(index));
			}
		}
Beispiel #17
0
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			var 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;
			}

			var 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);
		}
Beispiel #18
0
		protected static void EmitValueTypeLoadAddress(FleeILGenerator ilg, Type targetType)
		{
			int index = ilg.GetTempLocalIndex(targetType);
			Utility.EmitStoreLocal(ilg, index);
			ilg.Emit(OpCodes.Ldloca_S, Convert.ToByte(index));
		}
Beispiel #19
0
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			MyTail.Emit(ilg, services);
		}
Beispiel #20
0
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			if ((MyPrevious != null)) {
				MyPrevious.Emit(ilg, services);
			}
		}
Beispiel #21
0
		protected void EmitLoadOwner(FleeILGenerator ilg)
		{
			ilg.Emit(OpCodes.Ldarg_0);

			Type ownerType = MyOptions.OwnerType;

			if (ownerType.IsValueType == false) {
				return;
			}

			ilg.Emit(OpCodes.Unbox, ownerType);
			ilg.Emit(OpCodes.Ldobj, ownerType);

			// Emit usual stuff for value types but use the owner type as the target
			if (this.RequiresAddress == true) {
				EmitValueTypeLoadAddress(ilg, ownerType);
			}
		}
Beispiel #22
0
		private static void EmitBranchToTrueTerminal(FleeILGenerator ilg, Label trueTerminal, BranchManager bm)
		{
			if (ilg.IsTemp == true) {
				bm.AddBranch(ilg, trueTerminal);
				ilg.Emit(OpCodes.Brtrue_S, trueTerminal);
			} else if (bm.IsLongBranch(ilg, trueTerminal) == false) {
				ilg.Emit(OpCodes.Brtrue_S, trueTerminal);
			} else {
				ilg.Emit(OpCodes.Brtrue, trueTerminal);
			}
		}
Beispiel #23
0
		protected static void EmitLoadVariables(FleeILGenerator ilg)
		{
			ilg.Emit(OpCodes.Ldarg_2);
		}
Beispiel #24
0
		private void EmitCollectionIn(FleeILGenerator ilg, IServiceProvider services)
		{
			// Get the contains method
			var mi = this.GetCollectionContainsMethod();
			var 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);
		}
Beispiel #25
0
		private void EmitListIn(FleeILGenerator ilg, IServiceProvider services, BranchManager bm)
		{
			var ce = new CompareElement();
			var endLabel = bm.FindLabel("endLabel");
			var trueTerminal = bm.FindLabel("trueTerminal");

			// Cache the operand since we will be comparing against it a lot
			var lb = ilg.DeclareLocal(MyOperand.ResultType);
			int targetIndex = lb.LocalIndex;

			MyOperand.Emit(ilg, services);
			Utility.EmitStoreLocal(ilg, targetIndex);

			// Wrap our operand in a local shim
			var targetShim = new LocalBasedElement(MyOperand, targetIndex);

			// Emit the compares
			foreach (var argumentElement in MyArguments) {
				ce.Initialize(targetShim, argumentElement, LogicalCompareOperation.Equal);
				ce.Emit(ilg, services);

				EmitBranchToTrueTerminal(ilg, trueTerminal, bm);
			}

			ilg.Emit(OpCodes.Ldc_I4_0);
			ilg.Emit(OpCodes.Br_S, endLabel);

			bm.MarkLabel(ilg, trueTerminal);
			ilg.MarkLabel(trueTerminal);

			ilg.Emit(OpCodes.Ldc_I4_1);

			bm.MarkLabel(ilg, endLabel);
			ilg.MarkLabel(endLabel);
		}
Beispiel #26
0
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			if ((MyTargetCollectionType != null)) {
				this.EmitCollectionIn(ilg, services);

			} else {
				var bm = new BranchManager();
				bm.GetLabel("endLabel", ilg);
				bm.GetLabel("trueTerminal", ilg);

				// Do a fake emit to get branch positions
				var ilgTemp = this.CreateTempFleeILGenerator(ilg);
				Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp);

				this.EmitListIn(ilgTemp, services, bm);

				bm.ComputeBranches();

				// Do the real emit
				this.EmitListIn(ilg, services, bm);
			}
		}
Beispiel #27
0
		public static void EmitArrayStore(FleeILGenerator ilg, Type elementType)
		{
			TypeCode tc = Type.GetTypeCode(elementType);

			switch (tc) {
				case TypeCode.Byte:
				case TypeCode.SByte:
				case TypeCode.Boolean:
					ilg.Emit(OpCodes.Stelem_I1);
					break;
				case TypeCode.Int16:
				case TypeCode.UInt16:
					ilg.Emit(OpCodes.Stelem_I2);
					break;
				case TypeCode.Int32:
				case TypeCode.UInt32:
					ilg.Emit(OpCodes.Stelem_I4);
					break;
				case TypeCode.Int64:
				case TypeCode.UInt64:
					ilg.Emit(OpCodes.Stelem_I8);
					break;
				case TypeCode.Single:
					ilg.Emit(OpCodes.Stelem_R4);
					break;
				case TypeCode.Double:
					ilg.Emit(OpCodes.Stelem_R8);
					break;
				case TypeCode.Object:
				case TypeCode.String:
					ilg.Emit(OpCodes.Stelem_Ref);
					break;
				default:
					// Must be a non-primitive value type
					ilg.Emit(OpCodes.Stelem, elementType);
					break;
			}
		}
Beispiel #28
0
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			ilg.Emit(OpCodes.Ldc_R8, MyValue);
		}
Beispiel #29
0
		public static void SyncFleeILGeneratorLabels(FleeILGenerator source, FleeILGenerator target)
		{
			while (source.LabelCount != target.LabelCount) {
				target.DefineLabel();
			}
		}
Beispiel #30
0
		public static void EmitLoadLocalAddress(FleeILGenerator ilg, int index)
		{
			Debug.Assert(index >= 0, "Invalid index");

			if (index <= byte.MaxValue) {
				ilg.Emit(OpCodes.Ldloca_S, Convert.ToByte(index));
			} else {
				ilg.Emit(OpCodes.Ldloca, index);
			}
		}