/// <summary> /// Assemble, that is measure, arrange, and write elements in the given BinaryWriter /// </summary> /// <param name="element">Element to assemble</param> /// <param name="baseMemoryAddress">Memory address at which the program will be loaded</param> /// <param name="pointerSize">Size of a memory address</param> /// <param name="writer">Writer to write the result to</param> public void Assemble(Element element, ulong baseMemoryAddress, PointerSize pointerSize, BinaryWriter writer) { Dictionary <Element, Tag> tagMap = new Dictionary <Element, Tag>(); List <Tag> tagList = new List <Tag>(); AssemblingContext context = new AssemblingContext(tagMap, baseMemoryAddress, pointerSize); CreateTags(tagMap, tagList, context, element, null); foreach (Tag tag in tagList) { tag.RegisterDependencies(); } uint fileAddress = 0; uint relativeMemoryAddress = 0; for (int i = 0; i < tagList.Count; i++) { Tag tag = tagList[i]; if (tag.SetAddresses(fileAddress, relativeMemoryAddress) && tag.Observers != null) { int index = int.MaxValue; foreach (ElementTag observer in tag.Observers) { observer.InvalidateMeasure(); if (observer.Index < i && observer.Measure()) { index = Math.Min(index, observer.Index); } } if (index < i) { i = index; tag = tagList[i]; fileAddress = tag.FileAddress; relativeMemoryAddress = tag.RelativeMemoryAddress; } } tag.Measure(); fileAddress += tag.RealFileSize; relativeMemoryAddress += tag.RealMemorySize; } long baseStreamPosition = writer.BaseStream.Position; foreach (Tag tag in tagList) { tag.WriteTo(writer); baseStreamPosition += tag.RealFileSize; if (baseStreamPosition != writer.BaseStream.Position) { throw new Exception(); } } writer.Flush(); }
public AssemblingContext(Dictionary <Element, Tag> tagMap, ulong baseMemoryAddress, PointerSize pointerSize) { m_tagMap = tagMap; m_baseMemoryAddress = baseMemoryAddress; m_pointerSize = pointerSize; }