예제 #1
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);
			}
		}
예제 #2
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);
			}
		}
예제 #3
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);
			}
		}
예제 #4
0
파일: Negate.cs 프로젝트: netgrim/FleeSharp
		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);
			}
		}
예제 #5
0
파일: Not.cs 프로젝트: netgrim/FleeSharp
		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);
			}
		}
예제 #6
0
파일: Xor.cs 프로젝트: netgrim/FleeSharp
		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);
		}
예제 #7
0
파일: Root.cs 프로젝트: netgrim/FleeSharp
		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);
		}
예제 #8
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));
			}
		}
예제 #9
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);
		}
예제 #10
0
파일: AndOr.cs 프로젝트: netgrim/FleeSharp
 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;
     }
 }
예제 #11
0
파일: In.cs 프로젝트: netgrim/FleeSharp
		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);
		}
예제 #12
0
파일: In.cs 프로젝트: netgrim/FleeSharp
		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);
		}
예제 #13
0
		private void EmitReferenceLoad(FleeILGenerator ilg)
		{
			ilg.Emit(OpCodes.Ldarg_1);
			MyContext.CalculationEngine.EmitLoad(MyName, ilg);
		}
예제 #14
0
파일: Double.cs 프로젝트: netgrim/FleeSharp
		public override void Emit(FleeILGenerator ilg, IServiceProvider services)
		{
			ilg.Emit(OpCodes.Ldc_R8, MyValue);
		}
예제 #15
0
파일: Member.cs 프로젝트: netgrim/FleeSharp
        // Emit a function call for a value type
		private static void EmitValueTypeMethodCall(MethodInfo mi, FleeILGenerator ilg)
		{
			if (mi.IsStatic == true) {
				ilg.Emit(OpCodes.Call, mi);
			} else if ((!object.ReferenceEquals(mi.DeclaringType, mi.ReflectedType))) {
				// Method is not defined on the value type

				if (IsGetTypeMethod(mi) == true) {
					// Special GetType method which requires a box
					ilg.Emit(OpCodes.Box, mi.ReflectedType);
					ilg.Emit(OpCodes.Call, mi);
				} else {
					// Equals, GetHashCode, and ToString methods on the base
					ilg.Emit(OpCodes.Constrained, mi.ReflectedType);
					ilg.Emit(OpCodes.Callvirt, mi);
				}
			} else {
				// Call value type's implementation
				ilg.Emit(OpCodes.Call, mi);
			}
		}
예제 #16
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);
		}
예제 #17
0
		private static bool ImplicitConvertToReferenceType(Type sourceType, Type destType, FleeILGenerator ilg)
		{
			if (destType.IsValueType == true) {
				return false;
			}

			if (object.ReferenceEquals(sourceType, typeof(Null))) {
				// Null is always convertible to a reference type
				return true;
			}

			if (destType.IsAssignableFrom(sourceType) == false) {
				return false;
			}

			if (sourceType.IsValueType == true) {
				if ((ilg != null)) {
					ilg.Emit(OpCodes.Box, sourceType);
				}
			}

			return true;
		}
예제 #18
0
		private static void EmitLdfld(System.Reflection.FieldInfo fi, bool indirect, FleeILGenerator ilg)
		{
			if (fi.IsStatic == true) {
				if (indirect == true) {
					ilg.Emit(OpCodes.Ldsflda, fi);
				} else {
					ilg.Emit(OpCodes.Ldsfld, fi);
				}
			} else {
				if (indirect == true) {
					ilg.Emit(OpCodes.Ldflda, fi);
				} else {
					ilg.Emit(OpCodes.Ldfld, fi);
				}
			}
		}
예제 #19
0
파일: Member.cs 프로젝트: netgrim/FleeSharp
		protected static void EmitLoadVariables(FleeILGenerator ilg)
		{
			ilg.Emit(OpCodes.Ldarg_2);
		}
예제 #20
0
파일: Member.cs 프로젝트: netgrim/FleeSharp
		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);
			}
		}
예제 #21
0
파일: Member.cs 프로젝트: netgrim/FleeSharp
		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));
		}
예제 #22
0
파일: Member.cs 프로젝트: netgrim/FleeSharp
		private static void EmitReferenceTypeMethodCall(MethodInfo mi, FleeILGenerator ilg)
		{
			if (mi.IsStatic == true) {
				ilg.Emit(OpCodes.Call, mi);
			} else {
				ilg.Emit(OpCodes.Callvirt, mi);
			}
		}
예제 #23
0
파일: In.cs 프로젝트: netgrim/FleeSharp
		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);
			}
		}
예제 #24
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);
			}
		}
예제 #25
0
		private static void EmitConvert(FleeILGenerator ilg, OpCode convertOpcode)
		{
			if ((ilg != null)) {
				ilg.Emit(convertOpcode);
			}
		}
예제 #26
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);
		}
예제 #27
0
		private static bool EmitOverloadedImplicitConvert(Type sourceType, Type destType, FleeILGenerator ilg)
		{
			// Look for an implicit operator on the destination type
			MethodInfo mi = Utility.GetSimpleOverloadedOperator("Implicit", sourceType, destType);

			if (mi == null) {
				// No match
				return false;
			}

			if ((ilg != null)) {
				ilg.Emit(OpCodes.Call, mi);
			}

			return true;
		}
예제 #28
0
		private void EmitVariableLoad(FleeILGenerator ilg)
		{
			var mi = VariableCollection.GetVariableLoadMethod(MyVariableType);
			ilg.Emit(OpCodes.Ldstr, MyName);
			this.EmitMethodCall(mi, ilg);
		}
예제 #29
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;
			}
		}
예제 #30
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);
		}