示例#1
0
		private void GenerateIMTHelpers(Class _class) {
			if (!_class.IsClass)
				return;

			if ((_class.ClassDefinition as TypeDefinition).Interfaces.Count > 0) {
				for (int i = 0; i < Method.IMTSize; ++i) {
					List<Method> entries = _class.GetInterfaceEntries (i);
					if (entries != null && entries.Count > 1)
						GenerateConflictStub (_class, i);
				}
			}
		}
示例#2
0
文件: IR.cs 项目: sharpos/SharpOS
		/// <summary>
		/// Common implementations which pop a value from the IL evaluation stack and save it in another means
		/// of storage (such as stloc, stind, starg).
		/// </summary>
		private void Save (Class _class, InternalType destinationType, Memory memory, IR.Operands.Register value)
		{
			switch (destinationType) {
			case InternalType.I1:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new ByteMemory (memory), R8.AL);

				break;

			case InternalType.U1:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new ByteMemory (memory), R8.AL);

				break;

			case InternalType.I2:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new WordMemory (memory), R16.AX);

				break;

			case InternalType.U2:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new WordMemory (memory), R16.AX);

				break;

			case InternalType.I4:
			case InternalType.U4:
			case InternalType.I:
			case InternalType.U:
			case InternalType.O:
			case InternalType.SZArray:
			case InternalType.Array:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new DWordMemory (memory), R32.EAX);

				break;

			case InternalType.I8:
			case InternalType.U8:
				Memory source = this.GetAddress (value);
				source.DisplacementDelta = 4;

				DWordMemory destination = new DWordMemory (memory);
				destination.DisplacementDelta = 4;

				this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));
				this.assembly.MOV (new DWordMemory (memory), R32.EAX);

				this.assembly.MOV (R32.EAX, new DWordMemory (source));
				this.assembly.MOV (new DWordMemory (destination), R32.EAX);
				break;

			case InternalType.ValueType:
				uint size = (uint) this.method.Engine.GetTypeSize (_class.TypeFullName, 4);

				if (size == 4) {
					if (value.IsRegisterSet)
						this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));
					else
						this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					this.assembly.MOV (new DWordMemory (memory), R32.EAX);

				} else {
					this.assembly.PUSH (R32.ECX);
					this.assembly.PUSH (R32.ESI);
					this.assembly.PUSH (R32.EDI);

					if (value.IsRegisterSet)
						this.assembly.MOV (R32.ESI, Assembly.GetRegister (value.Register));
					else
						this.assembly.LEA (R32.ESI, new DWordMemory (this.GetAddress (value)));

					this.assembly.LEA (R32.EDI, new DWordMemory (memory));

					this.assembly.MOV (R32.ECX, size);

					this.assembly.CLD ();
					this.assembly.REP ();
					this.assembly.MOVSB ();

					this.assembly.POP (R32.EDI);
					this.assembly.POP (R32.ESI);
					this.assembly.POP (R32.ECX);
				}
				break;

			case InternalType.R4:
			case InternalType.R8:
			case InternalType.F:
			case InternalType.M:
			case InternalType.TypedReference:
			default:
				throw new NotImplementedEngineException ("Save not supported for InternalType." + destinationType);
			}
		}
示例#3
0
		private void GenerateConflictStubPart (Class _class, int key, List<Method> methods, int rangeStart, int rangeEnd)
		{
			// only one element - just jump to that method
			if (rangeStart == rangeEnd) {
				this.JMP (methods[rangeStart].AssemblyLabel);
			} else { // many elements - divide and generate stub parts
				int divide = (rangeEnd - rangeStart)/2 + rangeStart;
				string greaterBranchLabel = GetITableStubPartLabel(_class, key, divide+1, rangeEnd);

				this.CMP (R32.ECX, (uint)methods[divide].InterfaceMethodNumber);
				this.JG (greaterBranchLabel);
				// needed interface number is lower than middle element
				GenerateConflictStubPart (_class, key, methods, rangeStart, divide);
				this.LABEL (greaterBranchLabel);
				// needed interface number is higher than middle element
				GenerateConflictStubPart (_class, key, methods, divide + 1, rangeEnd);
			}
		}
示例#4
0
		private void GenerateConflictStub (Class _class, int key)
		{
			List<Method> entries = _class.GetInterfaceEntries (key);
			entries.Sort (delegate (Method a, Method b) {
				return Comparer<int>.Default.Compare (a.InterfaceMethodNumber, b.InterfaceMethodNumber);
			});

			string fullname = GetITableStubLabel(_class, key);
			this.ALIGN (Assembly.ALIGNMENT);

			this.AddSymbol (new COFF.Function (fullname));

			this.LABEL (fullname);
			GenerateConflictStubPart (_class, key, entries, 0, entries.Count-1);
		}
示例#5
0
		private string AddTypeInfoFields (Class _class)
		{
			this.ALIGN (OBJECT_ALIGNMENT);

			// Writing the Type Info instances
			string typeInfoLabel = this.GetTypeInfoLabel (_class.TypeFullName);
			this.AddSymbol (new COFF.Label (typeInfoLabel));
			this.LABEL (typeInfoLabel);

			// Type Info Object Header
			this.AddObjectFields (this.engine.TypeInfoClass.TypeFullName);

			// Type Info Name
			this.ADDRESSOF (this.AddString (_class.TypeFullName));

			// Type Info Base Instance
			if (_class.Base == null)
				// NULL
				this.DATA ((uint) 0);
			else
				this.ADDRESSOF (this.GetTypeInfoLabel (_class.Base.TypeFullName));

			if (this.engine.Options.NoMetadata) {
				this.DATA (0U);
				this.DATA (0U);
			} else {
				// Type Info AssemblyMetadata
				this.ADDRESSOF (_class.ClassDefinition.Module.Assembly.Name + " MetadataRoot");

				/*if (_class.ClassDefinition.Name == "TestD")
					Console.WriteLine ("TestD ******: {0}",
						_class.ClassDefinition.MetadataToken.ToUInt ().ToString ("x"));*/

				// Type Info Metadata token
				this.DATA (_class.ClassDefinition.MetadataToken.ToUInt ());
			}

			return typeInfoLabel;
		}
示例#6
0
		private void AddITableFields (Class _class)
		{
			this.ALIGN (OBJECT_ALIGNMENT);

			// Writing the Runtime ITable instances
			string label = this.GetITableLabel (_class.TypeFullName);
			this.AddSymbol (new COFF.Label (label));
			this.LABEL (label);

			// Type Info Object Header
			this.AddObjectFields (this.engine.ITableClass.TypeFullName);

			// count entries - don't write unused fields
			int lastEntry=0;
			for (int key = 0; key < Method.IMTSize; ++key) {
				if (_class.GetInterfaceEntries(key) != null)
					lastEntry = key;
			}

			for (int key = 0; key <= lastEntry; ++key) {
				List<Method> m = _class.GetInterfaceEntries(key);
				if (m == null) {
					this.DATA((uint) 0);
				} else if (m.Count == 1) {
					this.ADDRESSOF (m[0].AssemblyLabel);
				} else {
					this.ADDRESSOF (GetITableStubLabel(_class, key));
				}
			}
		}
示例#7
0
		private void AddVTableFields (Class _class, string typeInfoLabel)
		{
			this.ALIGN (OBJECT_ALIGNMENT);

			// Writing the Runtime VTable instances
			string label = this.GetVTableLabel (_class.TypeFullName);
			this.AddSymbol (new COFF.Label (label));
			this.LABEL (label);

			this.AddObjectFields (this.engine.VTableClass.TypeFullName);

			/*if (_class.ClassDefinition.Name == "TestD") {
				Console.WriteLine ("vtable.type -> {0}", typeInfoLabel);
			}*/

			// Type Info Field
			this.ADDRESSOF (typeInfoLabel);

			// VTable Size Field
			this.DATA ((uint) _class.ObjectSize);

			// ITable pointer
			if (_class.ImplementsInterfaces)
				this.ADDRESSOF (this.GetITableLabel(_class.TypeFullName));
			else
				this.DATA ((uint) 0);

			// Virtual Methods
			foreach (Method method in _class.VirtualMethods) {
				// add only non-interface methods to vtable
				if (method.InterfaceMethodNumber == -1) {
					this.ADDRESSOF (method.AssemblyLabel);
				}
			}
		}
示例#8
0
		/// <summary>
		/// Gets the I table stub part label.
		/// </summary>
		/// <param name="_class">The _class.</param>
		/// <param name="key">The key.</param>
		/// <param name="fromMethod">From method.</param>
		/// <param name="toMethod">To method.</param>
		/// <returns></returns>
		public string GetITableStubPartLabel (Class _class, int key, int fromMethod, int toMethod)
		{
			return string.Format (IMT_RANGE_LABEL, _class, key, fromMethod, toMethod);
		}
示例#9
0
		/// <summary>
		/// Gets the I table stub label.
		/// </summary>
		/// <param name="_class">The _class.</param>
		/// <param name="key">The key.</param>
		/// <returns></returns>
		public string GetITableStubLabel (Class _class, int key)
		{
			return string.Format (IMT_LABEL, _class, key);
		}