示例#1
0
		public LIRParameter(LIRMethod parent, LIRType tp)
		{
			this.Parent = parent;
			this.Type = tp;
			this.Index = parent.mParameters.Count;
			parent.mParameters.Add(this);
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, sA);
			var sB = pLIRMethod.RequestLocal(Sources[1].GetTypeOfLocation());
			Sources[1].LoadTo(pLIRMethod, sB);
			var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
			LIRInstructions.CompareCondition condition = LIRInstructions.CompareCondition.Equal;
			switch (CompareCondition)
			{
				case IRCompareCondition.Equal: break;
				case IRCompareCondition.GreaterThan: 
				case IRCompareCondition.GreaterThanUnsigned:
					condition = LIRInstructions.CompareCondition.GreaterThan;
					break;
				case IRCompareCondition.LessThan:
				case IRCompareCondition.LessThanUnsigned:
					condition = LIRInstructions.CompareCondition.LessThan;
					break;
				default: throw new Exception("Invalid Compare Condition");
			}
			new LIRInstructions.Compare(pLIRMethod, sA, sB, dest, sA.Type, condition);
			pLIRMethod.ReleaseLocal(sA);
			pLIRMethod.ReleaseLocal(sB);
			Destination.StoreTo(pLIRMethod, dest);
			pLIRMethod.ReleaseLocal(dest);
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var s = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, s);
			//new LIRInstructions.Throw(pLIRMethod, s, s.Type);
			pLIRMethod.ReleaseLocal(s);
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			Label[] lbls = new Label[TargetIRInstructions.Length];
			for (int i = 0; i < lbls.Length; i++)
			{
				lbls[i] = TargetIRInstructions[i].Label;
			}
			var swDatItem = new SwitchEmittableDataItem(lbls);
			pLIRMethod.CompileUnit.AddData(swDatItem);

			// Need to load and compare original value first...
			var vs = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, vs);
			var vt = pLIRMethod.RequestLocal(AppDomain.System_Boolean);
			new LIRInstructions.Compare(pLIRMethod, vs, (LIRImm)0, vt, vs.Type, LIRInstructions.CompareCondition.LessThan);
			new LIRInstructions.BranchTrue(pLIRMethod, vt, ParentMethod.Instructions[this.IRIndex + 1].Label);
			new LIRInstructions.Compare(pLIRMethod, vs, (LIRImm)lbls.Length, vt, vs.Type, LIRInstructions.CompareCondition.GreaterThan);
			new LIRInstructions.BranchTrue(pLIRMethod, vt, ParentMethod.Instructions[this.IRIndex + 1].Label);
			pLIRMethod.ReleaseLocal(vt);
			var sBase = pLIRMethod.RequestLocal(AppDomain.System_UIntPtr);
			new LIRInstructions.Move(pLIRMethod, swDatItem.Label, sBase, AppDomain.System_UIntPtr);
			new LIRInstructions.Math(pLIRMethod, vs, (LIRImm)VMConfig.PointerSizeForTarget, vs, LIRInstructions.MathOperation.Multiply, vs.Type);
			new LIRInstructions.Math(pLIRMethod, vs, sBase, sBase, LIRInstructions.MathOperation.Add, sBase.Type);
			pLIRMethod.ReleaseLocal(vs);
			new LIRInstructions.Move(pLIRMethod, new Indirect(sBase), sBase, sBase.Type);
			new LIRInstructions.BranchIndirect(pLIRMethod, sBase);
			pLIRMethod.ReleaseLocal(sBase);
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			if (Constructor.ParentType == AppDomain.System_String)
			{
#warning Finish special cases for string constructors
			}
			else
			{
				var sTypeDataPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_AllocateObject.LIRMethod.Parameters[0].Type);
				new LIRInstructions.Move(pLIRMethod, Constructor.ParentType.MetadataLabel, sTypeDataPtr, sTypeDataPtr.Type);
				var sReturnPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_AllocateObject.LIRMethod.Parameters[1].Type);
				Destination.LoadAddressTo(pLIRMethod, sReturnPtr);
				List<ISource> allocateObjectParams = new List<ISource>(2);
				allocateObjectParams.Add(sTypeDataPtr); // pointer to type data
				allocateObjectParams.Add(sReturnPtr); // pointer to destination
				new LIRInstructions.Call(pLIRMethod, AppDomain.System_GC_AllocateObject, allocateObjectParams, null);
				pLIRMethod.ReleaseLocal(sReturnPtr);
				pLIRMethod.ReleaseLocal(sTypeDataPtr);

				List<LIRLocal> constructorParams = new List<LIRLocal>(Sources.Count + 1);
				var sObj = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
				Destination.LoadTo(pLIRMethod, sObj);
				constructorParams.Add(sObj);
				foreach (IRLinearizedLocation sourceLocation in Sources)
				{
					var s = pLIRMethod.RequestLocal(sourceLocation.GetTypeOfLocation());
					constructorParams.Add(s);
					sourceLocation.LoadTo(pLIRMethod, s);
				}
				new LIRInstructions.Call(pLIRMethod, Constructor, constructorParams, null);
				constructorParams.ForEach(s => pLIRMethod.ReleaseLocal(s));
			}
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var sTypedReference = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation().GetManagedPointerType());
			Sources[0].LoadAddressTo(pLIRMethod, sTypedReference);
			new LIRInstructions.Move(pLIRMethod, new Indirect(sTypedReference), sTypedReference, sTypedReference.Type);
			Destination.StoreTo(pLIRMethod, sTypedReference);
			pLIRMethod.ReleaseLocal(sTypedReference);
		}
示例#7
0
		public LIRLocal(LIRMethod parent, LIRType tp)
		{
			this.Parent = parent;
			this.Type = tp;

			this.Index = parent.mLocals.Count;
			this.Parent.mLocals.Add(this);
		}
示例#8
0
		protected LIRInstruction(LIRMethod parent, LIROpCode opCode)
		{
			this.OpCode = opCode;
			if (parent != null)
			{
				this.Index = parent.mInstructions.Count;
				parent.mInstructions.Add(this);
			}
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, sA);
			var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
			new LIRInstructions.Convert(pLIRMethod, sA, sA.Type, dest, dest.Type);
			pLIRMethod.ReleaseLocal(sA);
			Destination.StoreTo(pLIRMethod, dest);
			pLIRMethod.ReleaseLocal(dest);
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var s = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, s);
			var d = pLIRMethod.RequestLocal(Type);
			new LIRInstructions.Move(pLIRMethod, Type.ToLIRType().Empty, d, Type);
			new LIRInstructions.Move(pLIRMethod, d, new Indirect(s), Type);
			pLIRMethod.ReleaseLocal(s);
			pLIRMethod.ReleaseLocal(d);
		}
示例#11
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var s = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, s);
			if (GetValue)
			{
				new LIRInstructions.Move(pLIRMethod, new Indirect(s), s, Destination.GetTypeOfLocation());
			}
			Destination.StoreTo(pLIRMethod, s);
			pLIRMethod.ReleaseLocal(s);
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var sTypedReference = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation().GetManagedPointerType());
			Sources[0].LoadAddressTo(pLIRMethod, sTypedReference);
			var sAddressPointer = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
			new LIRInstructions.Math(pLIRMethod, sTypedReference, (LIRImm)VMConfig.PointerSizeForTarget, sAddressPointer, LIRInstructions.MathOperation.Add, sAddressPointer.Type);
			new LIRInstructions.Move(pLIRMethod, new Indirect(sAddressPointer), sAddressPointer, sAddressPointer.Type);
			Destination.StoreTo(pLIRMethod, sAddressPointer);
			pLIRMethod.ReleaseLocal(sAddressPointer);
			pLIRMethod.ReleaseLocal(sTypedReference);
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, sA);
			var sB = pLIRMethod.RequestLocal(Sources[1].GetTypeOfLocation());
			Sources[1].LoadTo(pLIRMethod, sB);
			var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
			new LIRInstructions.Math(pLIRMethod, sA, sB, dest, LIRInstructions.MathOperation.Multiply, dest.Type);
			pLIRMethod.ReleaseLocal(sA);
			pLIRMethod.ReleaseLocal(sB);
			Destination.StoreTo(pLIRMethod, dest);
			pLIRMethod.ReleaseLocal(dest);
		}
示例#14
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			if (ParentMethod.ReturnType != null)
			{
				var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
				Sources[0].LoadTo(pLIRMethod, sA);
				new LIRInstructions.Return(pLIRMethod, sA, sA.Type);
				pLIRMethod.ReleaseLocal(sA);
			}
			else
			{
				new LIRInstructions.Return(pLIRMethod);
			}
		}
示例#15
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var sValuePtr = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadAddressTo(pLIRMethod, sValuePtr);
			var sTypeDataPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_BoxObject.LIRMethod.Parameters[0].Type);
			new LIRInstructions.Move(pLIRMethod, Type.MetadataLabel, sTypeDataPtr, sTypeDataPtr.Type);
			var sReturnPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_BoxObject.LIRMethod.Parameters[2].Type);
			Destination.LoadAddressTo(pLIRMethod, sReturnPtr);
			List<ISource> boxObjectParams = new List<ISource>(3);
			boxObjectParams.Add(sTypeDataPtr); // pointer to type data
			boxObjectParams.Add(sValuePtr); // pointer to value
			boxObjectParams.Add(sReturnPtr); // pointer to destination
			new LIRInstructions.Call(pLIRMethod, AppDomain.System_GC_BoxObject, boxObjectParams, null);
			pLIRMethod.ReleaseLocal(sReturnPtr);
			pLIRMethod.ReleaseLocal(sTypeDataPtr);
			pLIRMethod.ReleaseLocal(sValuePtr);
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var sElementCount = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, sElementCount);
			var sTypeDataPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_AllocateArrayOfType.LIRMethod.Parameters[0].Type);
			new LIRInstructions.Move(pLIRMethod, Destination.GetTypeOfLocation().MetadataLabel, sTypeDataPtr, sTypeDataPtr.Type);
			var sReturnPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_AllocateArrayOfType.LIRMethod.Parameters[2].Type);
			Destination.LoadAddressTo(pLIRMethod, sReturnPtr);
			List<ISource> allocateArrayOfTypeParams = new List<ISource>(3);
			allocateArrayOfTypeParams.Add(sTypeDataPtr); // pointer to type data of array
			allocateArrayOfTypeParams.Add(sElementCount); // number of elements
			allocateArrayOfTypeParams.Add(sReturnPtr); // pointer to destination
			new LIRInstructions.Call(pLIRMethod, AppDomain.System_GC_AllocateArrayOfType, allocateArrayOfTypeParams, null);
			pLIRMethod.ReleaseLocal(sReturnPtr);
			pLIRMethod.ReleaseLocal(sTypeDataPtr);
			pLIRMethod.ReleaseLocal(sElementCount);
		}
示例#17
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, sA);
			var sB = pLIRMethod.RequestLocal(Sources[1].GetTypeOfLocation());
			Sources[1].LoadTo(pLIRMethod, sB);
			var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
			LIRInstructions.MathOperation shiftOp = LIRInstructions.MathOperation.ShiftLeft;
			switch (ShiftType)
			{
				case IRShiftType.Left: shiftOp = LIRInstructions.MathOperation.ShiftLeft; break;
				case IRShiftType.Right: shiftOp = LIRInstructions.MathOperation.ShiftRight; break;
				case IRShiftType.RightSignExtended: shiftOp = LIRInstructions.MathOperation.ShiftRightSignExtended; break;
				default: throw new Exception();
			}
			new LIRInstructions.Math(pLIRMethod, sA, sB, dest, shiftOp, dest.Type);
			pLIRMethod.ReleaseLocal(sA);
			pLIRMethod.ReleaseLocal(sB);
			Destination.StoreTo(pLIRMethod, dest);
			pLIRMethod.ReleaseLocal(dest);
		}
示例#18
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			var src = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
			Sources[0].LoadTo(pLIRMethod, src);
			var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
			var canCastResult = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Boolean);
			var getTypeByGlobalTypeIDResult = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Type);

			// Call to Proton.Runtime.RuntimeHelpers.GetTypeByGlobalTypeID method, which returns the runtime System.Type
			new LIRInstructions.Call(pLIRMethod, ParentMethod.Assembly.AppDomain.Proton_Runtime_RuntimeHelpers_GetTypeByGlobalTypeID.LIRMethod, new List<ISource>(1) { (LIRImm)Type.GlobalTypeID }, getTypeByGlobalTypeIDResult);

			// Call to Proton.Runtime.RuntimeHelpers.CanCast method, which determines if an object can be cast to a type
			// TODO: can src be a value type? if so then we may need to box it first to pass it into this call as an object
			// TODO: this method should throw an exception if the Type is null, so we can skip testing castType before the call
			new LIRInstructions.Call(pLIRMethod, ParentMethod.Assembly.AppDomain.Proton_Runtime_RuntimeHelpers_CanCast.LIRMethod, new List<ISource>(2) { src, getTypeByGlobalTypeIDResult }, canCastResult);

			// Don't need getTypeByGlobalTypeIDResult anymore, we have canCastResult
			pLIRMethod.ReleaseLocal(getTypeByGlobalTypeIDResult);

			// Branch if we can cast, fall through if we cannot
			LIRInstructions.BranchTrue canCastBranchTrue = new LIRInstructions.BranchTrue(pLIRMethod, canCastResult);

			// Getting here means CanCast returned false, so the emitted code depends on ThrowExceptionOnFailure
			if (!ThrowExceptionOnFailure)
			{
				// If we don't throw an exception, then we are expected to set the destination to it's default value (null, 0, etc)
				new LIRInstructions.Move(pLIRMethod, dest.Type.Empty, dest, dest.Type);
			}
			// Now we jump past the previous BranchTrue logic below
			LIRInstructions.Branch cannotCastBranchOut = new LIRInstructions.Branch(pLIRMethod);
			// Getting here means CanCast returned true, so we need to set the BranchTrue target label
			canCastBranchTrue.SetTarget(new Label());
			// And now copy src to dest, based on the destination casted type
			// TODO: Is it safe to use src here, after it was passed as a source to the Call above?
			new LIRInstructions.Move(pLIRMethod, src, dest, dest.Type);

			cannotCastBranchOut.SetTarget(new Label());

			// We're done with src now, clean that up
			pLIRMethod.ReleaseLocal(src);

			if (!ThrowExceptionOnFailure)
			{
				// If we don't throw an exception, then we end up moving null to destination
				// so we can just do a normal cleanup and store here
				pLIRMethod.ReleaseLocal(canCastResult);
				Destination.StoreTo(pLIRMethod, dest);
				pLIRMethod.ReleaseLocal(dest);
			}
			else
			{
				// Branch if we can cast, fall through if we cannot
				canCastBranchTrue = new LIRInstructions.BranchTrue(pLIRMethod, canCastResult);
				// Getting here means we were not able to cast, so we need to cleanup before we throw an
				// exception, but we do not store anything to the destination
				pLIRMethod.ReleaseLocal(canCastResult);
				pLIRMethod.ReleaseLocal(dest);

				// TODO: Throw exception here, Branch is here to loop infinite, but this is not valid
				// it is here only as a placeholder, we need to prepare the object being thrown in a
				// way that the reference is held until an exception handler has the reference
				Label loopLabel = new Label();
				new LIRInstructions.Comment(pLIRMethod, "TODO: Replace this infinite loop with Throw logic");
				new LIRInstructions.Branch(pLIRMethod, loopLabel);

				// Getting here means we were able to cast, just do a normal cleanup
				canCastBranchTrue.SetTarget(new Label());
				pLIRMethod.ReleaseLocal(canCastResult);
				Destination.StoreTo(pLIRMethod, dest);
				pLIRMethod.ReleaseLocal(dest);
			}
			// Fall through to next IR instruction if we had a successful cast, or failed without
			// throwing an exception
		}
示例#19
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
		}
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			throw new NotSupportedException();
		}
示例#21
0
		public void CreateLIRMethod()
		{
			if (
				this.Name == ".cctor" &&
				(
					(
						this.Instructions.Count == 1 &&
						this.Instructions[0].Opcode == IROpcode.Return
					) ||
					(
						this.Instructions.Count == 2 &&
						this.Instructions[0].Opcode == IROpcode.Nop &&
						this.Instructions[1].Opcode == IROpcode.Return
					)
				)
			)
			{
				Assembly.AppDomain.Methods.QueueForRemoval(this);
				return;
			}
			LIRMethod = new LIRMethod(Name, ReturnType ?? (LIRType)null);
			mParameters.ForEach(p => new LIRParameter(LIRMethod, p.Type));
			mLocals.ForEach(l => new LIRLocal(LIRMethod, l.Type));
		}
示例#22
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			switch (BranchCondition)
			{
				case IRBranchCondition.Always:
					new LIRInstructions.Branch(pLIRMethod, TargetIRInstruction.Label);
					break;
				case IRBranchCondition.True:
				{
					var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
					Sources[0].LoadTo(pLIRMethod, sA);
					new LIRInstructions.BranchTrue(pLIRMethod, sA, TargetIRInstruction.Label);
					pLIRMethod.ReleaseLocal(sA);
					break;
				}
				case IRBranchCondition.False:
				{
					var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
					Sources[0].LoadTo(pLIRMethod, sA);
					var sB = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Int32);
					new IRLinearizedLocation(this, IRLinearizedLocationType.ConstantI4)
					{
						ConstantI4 = new IRLinearizedLocation.ConstantI4LocationData()
						{
							Value = 0
						}
					}.LoadTo(pLIRMethod, sB);
					var dest = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Int32);
					new LIRInstructions.Compare(pLIRMethod, sA, sB, dest, sA.Type, BranchCondition == IRBranchCondition.True ? LIRInstructions.CompareCondition.NotEqual : LIRInstructions.CompareCondition.Equal);
					pLIRMethod.ReleaseLocal(sA);
					pLIRMethod.ReleaseLocal(sB);
					new LIRInstructions.BranchTrue(pLIRMethod, dest, TargetIRInstruction.Label);
					pLIRMethod.ReleaseLocal(dest);
					break;
				}
				case IRBranchCondition.GreaterOrEqual:
				case IRBranchCondition.GreaterOrEqualUnsigned:
				case IRBranchCondition.Greater:
				case IRBranchCondition.GreaterUnsigned:
				case IRBranchCondition.LessOrEqual:
				case IRBranchCondition.LessOrEqualUnsigned:
				case IRBranchCondition.Less:
				case IRBranchCondition.LessUnsigned:
				case IRBranchCondition.NotEqualUnsigned:
				case IRBranchCondition.Equal:
				{
					var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
					Sources[0].LoadTo(pLIRMethod, sA);
					var sB = pLIRMethod.RequestLocal(Sources[1].GetTypeOfLocation());
					Sources[1].LoadTo(pLIRMethod, sB);
					var dest = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Int32);
					LIRInstructions.CompareCondition condition = LIRInstructions.CompareCondition.Equal;
					switch (BranchCondition)
					{
						case IRBranchCondition.GreaterOrEqual:
						case IRBranchCondition.GreaterOrEqualUnsigned:
							condition = LIRInstructions.CompareCondition.GreaterThanOrEqual;
							break;
						case IRBranchCondition.Greater:
						case IRBranchCondition.GreaterUnsigned:
							condition = LIRInstructions.CompareCondition.GreaterThan;
							break;
						case IRBranchCondition.LessOrEqual:
						case IRBranchCondition.LessOrEqualUnsigned:
							condition = LIRInstructions.CompareCondition.LessThanOrEqual;
							break;
						case IRBranchCondition.Less:
						case IRBranchCondition.LessUnsigned:
							condition = LIRInstructions.CompareCondition.LessThan;
							break;
						case IRBranchCondition.NotEqualUnsigned:
							condition = LIRInstructions.CompareCondition.NotEqual;
							break;
						case IRBranchCondition.Equal:
							condition = LIRInstructions.CompareCondition.Equal;
							break;
						default: throw new Exception("Something is rong here, we just were one of these....");
					}
					new LIRInstructions.Compare(pLIRMethod, sA, sB, dest, sA.Type, condition);
					pLIRMethod.ReleaseLocal(sA);
					pLIRMethod.ReleaseLocal(sB);
					new LIRInstructions.BranchTrue(pLIRMethod, dest, TargetIRInstruction.Label);
					pLIRMethod.ReleaseLocal(dest);
					break;
				}
				default:
					throw new Exception("Unknown IRBranchCondition!");
			}
		}
示例#23
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			if (Virtual)
			{
				if (Target.VirtualMethodIndex < 0) throw new Exception();
				List<LIRLocal> paramSources = new List<LIRLocal>(Target.Parameters.Count);
				foreach (var v in Sources)
				{
					var s = pLIRMethod.RequestLocal(v.GetTypeOfLocation());
					v.LoadTo(pLIRMethod, s);
					paramSources.Add(s);
				}
				ISource methodPointerSource = null;
				if (!Target.ParentType.IsInterface)
				{
					var s = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation());
					Sources[0].LoadTo(pLIRMethod, s); // Gets Object Pointer
					new LIRInstructions.Math(pLIRMethod, s, (LIRImm)VMConfig.PointerSizeForTarget, s, LIRInstructions.MathOperation.Subtract, s.Type); // Subtract sizeof pointer to get address of TypeData pointer
					new LIRInstructions.Move(pLIRMethod, new Indirect(s), s, s.Type); // Get TypeData Pointer
					new LIRInstructions.Move(pLIRMethod, new Indirect(s), s, s.Type); // Get VirtualMethodTree Pointer Array
					new LIRInstructions.Math(pLIRMethod, s, (LIRImm)(VMConfig.PointerSizeForTarget * Target.VirtualMethodIndex), s, LIRInstructions.MathOperation.Add, s.Type); // Get VirtualMethod Pointer Address
					new LIRInstructions.Move(pLIRMethod, new Indirect(s), s, s.Type); // Get VirtualMethod Pointer
					methodPointerSource = s;
				}
				else
				{
#warning Interface Calls Not Yet Implemented.
					return;
				}
				if (Target.ReturnType != null)
				{
					var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
					new LIRInstructions.CallIndirect(pLIRMethod, methodPointerSource, paramSources, dest);
					Destination.StoreTo(pLIRMethod, dest);
					pLIRMethod.ReleaseLocal(dest);
				}
				else
				{
					new LIRInstructions.CallIndirect(pLIRMethod, methodPointerSource, paramSources);
				}
				paramSources.ForEach(s => pLIRMethod.ReleaseLocal(s));
			}
			else
			{
				List<LIRLocal> paramSources = new List<LIRLocal>(Target.Parameters.Count);
				foreach (var v in Sources)
				{
					var s = pLIRMethod.RequestLocal(v.GetTypeOfLocation());
					v.LoadTo(pLIRMethod, s);
					paramSources.Add(s);
				}
				if (Target.ReturnType != null)
				{
					var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation());
					new LIRInstructions.Call(pLIRMethod, Target.LIRMethod, paramSources, dest);
					Destination.StoreTo(pLIRMethod, dest);
					pLIRMethod.ReleaseLocal(dest);
				}
				else
				{
					new LIRInstructions.Call(pLIRMethod, Target.LIRMethod, paramSources);
				}
				paramSources.ForEach(s => pLIRMethod.ReleaseLocal(s));
			}
		}
示例#24
0
		public override void ConvertToLIR(LIRMethod pLIRMethod)
		{
			if (ForceEmit)
				new LIRInstructions.Nop(pLIRMethod);
		}
示例#25
0
		private static void FinalMethodCleanup(LIRMethod m)
		{
			for (int i = 0; i < m.mInstructions.Count; i++)
			{
				if (m.mInstructions[i].OpCode == LIROpCode.Comment)
					m.mInstructions[i] = new Instructions.Dead(i);
			}
			KnownOptimizationPasses[KnownOptimizationPasses.Length - 1].Run(m);
		}
示例#26
0
		public void AddMethod(LIRMethod m)
		{
			mMethods.Add(m);
			m.CompileUnit = this;
		}
		public void StoreTo(LIRMethod pParent, ISource pSource)
		{
			switch (Type)
			{
				case IRLinearizedLocationType.Local:
					new LIRInstructions.Move(pParent, pSource, pParent.Locals[Local.LocalIndex], pParent.Locals[Local.LocalIndex].Type);
					break;
				case IRLinearizedLocationType.Parameter:
					new LIRInstructions.Move(pParent, pSource, pParent.Parameters[Parameter.ParameterIndex], pParent.Parameters[Parameter.ParameterIndex].Type);
					break;
				case IRLinearizedLocationType.Field:
				{
					var obj = pParent.RequestLocal(Field.FieldLocation.GetTypeOfLocation());
					Field.FieldLocation.LoadTo(pParent, obj);
					var foff = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, obj, (LIRImm)Field.Field.Offset, foff, LIRInstructions.MathOperation.Add, ParentInstruction.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(obj);
					new LIRInstructions.Move(pParent, pSource, new Indirect(foff), Field.Field.Type);
					pParent.ReleaseLocal(foff);
					break;
				}
				case IRLinearizedLocationType.Indirect:
				{
					var obj = pParent.RequestLocal(Indirect.AddressLocation.GetTypeOfLocation());
					Indirect.AddressLocation.LoadTo(pParent, obj);
					new LIRInstructions.Move(pParent, pSource, new Indirect(obj), Indirect.Type);
					pParent.ReleaseLocal(obj);
					break;
				}
				case IRLinearizedLocationType.ArrayElement:
				{
					var arr = pParent.RequestLocal(ArrayElement.ArrayLocation.GetTypeOfLocation());
					var idx = pParent.RequestLocal(ArrayElement.IndexLocation.GetTypeOfLocation());
					ArrayElement.ArrayLocation.LoadTo(pParent, arr);
					ArrayElement.IndexLocation.LoadTo(pParent, idx);
					var off = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, idx, (LIRImm)ArrayElement.ElementType.StackSize, off, LIRInstructions.MathOperation.Multiply, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(idx);
					new LIRInstructions.Math(pParent, off, (LIRImm)0x04, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, off, arr, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(arr);
					new LIRInstructions.Move(pParent, pSource, new Indirect(off), ArrayElement.ElementType);
					pParent.ReleaseLocal(off);
					break;
				}
				case IRLinearizedLocationType.StaticField:
				{
					EmitStaticConstructorCheck(pParent, StaticField.Field.ParentType, ParentInstruction.ParentMethod.ParentType);
					new LIRInstructions.Move(pParent, pSource, new Indirect(StaticField.Field.Label), StaticField.Field.Type);
					break;
				}


				case IRLinearizedLocationType.Null:
				case IRLinearizedLocationType.LocalAddress:
				case IRLinearizedLocationType.ParameterAddress:
				case IRLinearizedLocationType.ConstantI4:
				case IRLinearizedLocationType.ConstantI8:
				case IRLinearizedLocationType.ConstantR4:
				case IRLinearizedLocationType.ConstantR8:
				case IRLinearizedLocationType.FieldAddress:
				case IRLinearizedLocationType.StaticFieldAddress:
				case IRLinearizedLocationType.ArrayElementAddress:
				case IRLinearizedLocationType.ArrayLength:
				case IRLinearizedLocationType.FunctionAddress:
				case IRLinearizedLocationType.RuntimeHandle:
				case IRLinearizedLocationType.String:
				case IRLinearizedLocationType.SizeOf:
					throw new Exception("It's not possible to store to these!");
				case IRLinearizedLocationType.Phi:
					throw new Exception("All phi's should have been eliminated by this point!");
				default:
					throw new Exception("Unknown IRLinearizedLocationType!");
			}
		}
		public void LoadTo(LIRMethod pParent, IDestination pDestination)
		{
			switch (Type)
			{
				case IRLinearizedLocationType.Null:
					new LIRInstructions.Move(pParent, (LIRImm)0, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					break;
				case IRLinearizedLocationType.Local:
					new LIRInstructions.Move(pParent, pParent.Locals[Local.LocalIndex], pDestination, pParent.Locals[Local.LocalIndex].Type);
					break;
				case IRLinearizedLocationType.Parameter:
					new LIRInstructions.Move(pParent, pParent.Parameters[Parameter.ParameterIndex], pDestination, pParent.Parameters[Parameter.ParameterIndex].Type);
					break;
				case IRLinearizedLocationType.ConstantI4:
					new LIRInstructions.Move(pParent, (LIRImm)ConstantI4.Value, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Int32);
					break;
				case IRLinearizedLocationType.ConstantI8:
					new LIRInstructions.Move(pParent, (LIRImm)ConstantI8.Value, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Int64);
					break;
				case IRLinearizedLocationType.ConstantR4:
					new LIRInstructions.Move(pParent, (LIRImm)ConstantR4.Value, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Single);
					break;
				case IRLinearizedLocationType.ConstantR8:
					new LIRInstructions.Move(pParent, (LIRImm)ConstantR8.Value, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Double);
					break;
				case IRLinearizedLocationType.SizeOf:
					new LIRInstructions.Move(pParent, (LIRImm)SizeOf.Type.StackSize, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Int32);
					break;
				case IRLinearizedLocationType.Field:
				{
					var obj = pParent.RequestLocal(Field.FieldLocation.GetTypeOfLocation());
					Field.FieldLocation.LoadTo(pParent, obj);
					var foff = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, obj, (LIRImm)Field.Field.Offset, foff, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(obj);
					new LIRInstructions.Move(pParent, new Indirect(foff), pDestination, Field.Field.Type);
					pParent.ReleaseLocal(foff);
					break;
				}
				case IRLinearizedLocationType.FieldAddress:
				{
					var obj = pParent.RequestLocal(FieldAddress.FieldLocation.GetTypeOfLocation());
					FieldAddress.FieldLocation.LoadTo(pParent, obj);
					var foff = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, obj, (LIRImm)FieldAddress.Field.Offset, foff, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(obj);
					new LIRInstructions.Move(pParent, foff, pDestination, FieldAddress.Field.Type.GetManagedPointerType());
					pParent.ReleaseLocal(foff);
					break;
				}
				case IRLinearizedLocationType.Indirect:
				{
					var obj = pParent.RequestLocal(Indirect.AddressLocation.GetTypeOfLocation());
					Indirect.AddressLocation.LoadTo(pParent, obj);
					new LIRInstructions.Move(pParent, new Indirect(obj), pDestination, Indirect.Type);
					pParent.ReleaseLocal(obj);
					break;
				}
				case IRLinearizedLocationType.ArrayElement:
				{
					var arr = pParent.RequestLocal(ArrayElement.ArrayLocation.GetTypeOfLocation());
					var idx = pParent.RequestLocal(ArrayElement.IndexLocation.GetTypeOfLocation());
					ArrayElement.ArrayLocation.LoadTo(pParent, arr);
					ArrayElement.IndexLocation.LoadTo(pParent, idx);
					var off = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, idx, (LIRImm)ArrayElement.ElementType.StackSize, off, LIRInstructions.MathOperation.Multiply, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(idx);
					new LIRInstructions.Math(pParent, off, (LIRImm)0x04, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, off, arr, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(arr);
					new LIRInstructions.Move(pParent, new Indirect(off), pDestination, ArrayElement.ElementType);
					pParent.ReleaseLocal(off);
					break;
				}
				case IRLinearizedLocationType.ArrayElementAddress:
				{
					var arr = pParent.RequestLocal(ArrayElementAddress.ArrayLocation.GetTypeOfLocation());
					var idx = pParent.RequestLocal(ArrayElementAddress.IndexLocation.GetTypeOfLocation());
					ArrayElementAddress.ArrayLocation.LoadTo(pParent, arr);
					ArrayElementAddress.IndexLocation.LoadTo(pParent, idx);
					var off = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, idx, (LIRImm)ArrayElementAddress.ElementType.StackSize, off, LIRInstructions.MathOperation.Multiply, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(idx);
					new LIRInstructions.Math(pParent, off, (LIRImm)0x04, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					new LIRInstructions.Math(pParent, off, arr, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr);
					pParent.ReleaseLocal(arr);
					new LIRInstructions.Move(pParent, off, pDestination, ArrayElementAddress.ElementType.GetManagedPointerType());
					pParent.ReleaseLocal(off);
					break;
				}
				case IRLinearizedLocationType.ArrayLength:
				{
					var arr = pParent.RequestLocal(ArrayLength.ArrayLocation.GetTypeOfLocation());
					ArrayLength.ArrayLocation.LoadTo(pParent, arr);
					new LIRInstructions.Move(pParent, new Indirect(arr), pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Int32);
					pParent.ReleaseLocal(arr);
					break;
				}
				case IRLinearizedLocationType.LocalAddress:
					new LIRInstructions.Move(pParent, pParent.Locals[Local.LocalIndex].AddressOf(), pDestination, pParent.Locals[Local.LocalIndex].Type);
					break;
				case IRLinearizedLocationType.ParameterAddress:
					new LIRInstructions.Move(pParent, pParent.Parameters[Parameter.ParameterIndex].AddressOf(), pDestination, pParent.Parameters[Parameter.ParameterIndex].Type);
					break;
				case IRLinearizedLocationType.String:
				{
					var dest = pParent.RequestLocal(ParentInstruction.AppDomain.System_String.GetManagedPointerType());
					new LIRInstructions.Move(pParent, dest.AddressOf(), dest, dest.Type);
					var str = GetStringLiteral(pParent.CompileUnit, String.Value);
					var strLb = pParent.RequestLocal(ParentInstruction.AppDomain.System_UIntPtr);
					new LIRInstructions.Move(pParent, str.Label, strLb, strLb.Type);
					new LIRInstructions.Call(pParent, ParentInstruction.AppDomain.System_GC_AllocateStringFromUTF16, new List<ISource>() { strLb, dest }, null);
					pParent.ReleaseLocal(strLb);
					new LIRInstructions.Move(pParent, dest, pDestination, dest.Type);
					pParent.ReleaseLocal(dest);
					break;
				}
				case IRLinearizedLocationType.StaticField:
				{
					EmitStaticConstructorCheck(pParent, StaticField.Field.ParentType, ParentInstruction.ParentMethod.ParentType);
					new LIRInstructions.Move(pParent, new Indirect(StaticField.Field.Label), pDestination, StaticField.Field.Type);
					break;
				}
				case IRLinearizedLocationType.StaticFieldAddress:
				{
					EmitStaticConstructorCheck(pParent, StaticFieldAddress.Field.ParentType, ParentInstruction.ParentMethod.ParentType);
					new LIRInstructions.Move(pParent, StaticFieldAddress.Field.Label, pDestination, StaticField.Field.Type);
					break;
				}
				case IRLinearizedLocationType.FunctionAddress:
				{
					if (FunctionAddress.Virtual)
					{
						if (FunctionAddress.Method.VirtualMethodIndex < 0)
							throw new Exception("The requested method never got laid out in a virtual method tree!");
						if (FunctionAddress.Method.ParentType.IsInterface)
						{
#warning Loading the virtual function address of a method on an interface isn't supported yet!
						}
						else
						{
							var s = pParent.RequestLocal(Indirect.AddressLocation.GetTypeOfLocation());
							Indirect.AddressLocation.LoadTo(pParent, s); // Gets Object Pointer
							new LIRInstructions.Math(pParent, s, (LIRImm)VMConfig.PointerSizeForTarget, s, LIRInstructions.MathOperation.Subtract, s.Type); // Subtract sizeof pointer to get address of TypeData pointer
							new LIRInstructions.Move(pParent, new Indirect(s), s, s.Type); // Get TypeData Pointer
							new LIRInstructions.Move(pParent, new Indirect(s), s, s.Type); // Get VirtualMethodTree Pointer Array
							new LIRInstructions.Math(pParent, s, (LIRImm)(VMConfig.PointerSizeForTarget * FunctionAddress.Method.VirtualMethodIndex), s, LIRInstructions.MathOperation.Add, s.Type); // Get VirtualMethod Pointer Address
							new LIRInstructions.Move(pParent, new Indirect(s), pDestination, s.Type); // Get VirtualMethod Pointer
							pParent.ReleaseLocal(s);
						}
					}
					else
					{
						new LIRInstructions.Move(pParent, FunctionAddress.Method.LIRMethod.Label, pDestination, ParentInstruction.AppDomain.System_UIntPtr);
					}
					break;
				}
				case IRLinearizedLocationType.RuntimeHandle:
				{
					if (RuntimeHandle.HandleType == ParentInstruction.AppDomain.System_RuntimeTypeHandle)
					{
						new LIRInstructions.Move(pParent, RuntimeHandle.TargetType.MetadataLabel, pDestination, RuntimeHandle.HandleType);
					}
					else if (RuntimeHandle.HandleType == ParentInstruction.AppDomain.System_RuntimeMethodHandle)
					{
						new LIRInstructions.Move(pParent, RuntimeHandle.TargetMethod.MetadataLabel, pDestination, RuntimeHandle.HandleType);
					}
					else if (RuntimeHandle.HandleType == ParentInstruction.AppDomain.System_RuntimeFieldHandle)
					{
						new LIRInstructions.Move(pParent, RuntimeHandle.TargetField.MetadataLabel, pDestination, RuntimeHandle.HandleType);
					}
					else
					{
						throw new Exception("Unknown RuntimeHandle HandleType!");
					}
					break;
				}

				case IRLinearizedLocationType.Phi:
					throw new Exception("All phi's should have been eliminated by this point!");
				default:
					throw new Exception("Unknown IRLinearizedLocationType!");
			}
		}
		public static void EmitStaticConstructorCheck(LIRMethod m, IRType targetType, IRType curType, bool forceEmit = false)
		{
			if (targetType.HasStaticConstructor && (forceEmit || targetType != curType))
			{
				var con = targetType.StaticConstructor;
				if (
					(
						con.Instructions.Count == 1 &&
						con.Instructions[0].Opcode == IROpcode.Return
					) ||
					(
						con.Instructions.Count == 2 &&
						con.Instructions[0].Opcode == IROpcode.Nop &&
						con.Instructions[1].Opcode == IROpcode.Return
					)
				)
				{
					// We don't need a static constructor call
				}
				else
				{
					StaticConstructorCalledEmittableDataItem d = null;
					if (!KnownStaticConstructors.TryGetValue(targetType, out d))
					{
						d = new StaticConstructorCalledEmittableDataItem(targetType);
						m.CompileUnit.AddData(d);
						KnownStaticConstructors.Add(targetType, d);
					}
					new LIRInstructions.Comment(m, "Static Constructor Check");
					var c = m.RequestLocal(targetType.Assembly.AppDomain.System_Boolean);
					new LIRInstructions.Move(m, new Indirect(d.Label), c, targetType.Assembly.AppDomain.System_Boolean);
					Label called = new Label();
					new LIRInstructions.BranchTrue(m, c, called);
					m.ReleaseLocal(c);
					new LIRInstructions.Move(m, (LIRImm)1, new Indirect(d.Label), targetType.Assembly.AppDomain.System_Boolean);
					new LIRInstructions.Call(m, con);
					m.MarkLabel(called);
				}
			}
		}
示例#30
0
		public abstract void ConvertToLIR(LIRMethod pLIRMethod);