private LinkerResult ProcessOrdered( LinkerTarget root, Dictionary <FileReference, LinkerTarget> mapping, bool enableHide) { Stack <FileReference> todo = new Stack <FileReference>(mapping.Keys.Where(x => x.File != root.FileCompilation.Reference.File)); LinkerResult result = new LinkerResult( mapping.Values.ToArray(), new Dictionary <string, AddressItem>(), new Dictionary <string, AddressItem>(), new Dictionary <string, AddressItem>(), new List <AToken[]>(), new uint[0] ); PerformLinking(result, new List <LinkerTarget> { root }, enableHide); while (todo.Count != 0) { FileReference nextFile = todo.Pop(); LinkerTarget fileTarget = mapping[nextFile]; PerformLinking(result, new List <LinkerTarget> { fileTarget }, enableHide); } return(result); }
public static LinkerInfo CreateFromResult(LinkerResult result) { return(new LinkerInfo { Constants = result.Constants.Filter(kvp => !kvp.Value.Internal && !kvp.Value.Hide), DataSectionHeader = result.DataSectionHeader.Filter(kvp => !kvp.Value.Internal && !kvp.Value.Hide), Labels = result.Labels.Filter(kvp => !kvp.Value.Internal && !kvp.Value.Hide), Source = result.LinkedBinary.FirstOrDefault()?.FirstOrDefault()?.OriginalText }); }
public void Compile(string file) { FileCompilation fc = new FileCompilation(new FileReference(file)); LinkerTarget linkTarget = new LinkerTarget(fc, fc.Reference.LinkerArguments); LinkerResult linkResult = m_Linker.Link(linkTarget, this); LinkerResult = linkResult; ByteCode = m_AssemblyGenerator.Assemble(linkResult); LinkerInfo = CreateFromResult(linkResult); }
private void PerformLinking(LinkerResult result, List <LinkerTarget> references, bool enableHide) { //Join the Targets foreach (LinkerTarget linkerTarget in references) { JoinDefinitions(result.Constants, linkerTarget.FileCompilation.Constants, enableHide); JoinDefinitions( result.DataSectionHeader, linkerTarget.FileCompilation.DataSectionHeader.ApplyOffset( ( uint )result.DataSection.Count ), enableHide ); (int, int)k = (result.LinkedBinary.Count, linkerTarget.FileCompilation.Tokens.Count); result.HiddenDataSectionItems[k] = SelectHidden(linkerTarget.FileCompilation.DataSectionHeader.ToArray()). ApplyOffset(( uint )result.DataSection.Count). ToDictionary(x => x.Key, x => x.Value); result.HiddenLabelItems[k] = SelectHidden(linkerTarget.FileCompilation.Labels.ToArray()). ApplyOffset( ( uint )result.LinkedBinary.Count * CpuSettings.InstructionSize ). ToDictionary(x => x.Key, x => x.Value); result.HiddenConstantItems[k] = SelectHidden(linkerTarget.FileCompilation.Constants.ToArray()); result.DataSection.AddRange(linkerTarget.FileCompilation.DataSection); JoinDefinitions( result.Labels, linkerTarget.FileCompilation.Labels.ApplyOffset( ( uint )result.LinkedBinary.Count * CpuSettings.InstructionSize ), enableHide ); result.LinkedBinary.AddRange(linkerTarget.FileCompilation.Tokens); } }
private uint GetTotalVarCount(LinkerResult result) { uint size = 0; foreach (KeyValuePair <string, AddressItem> keyValuePair in result.DataSectionHeader) { size++; } foreach (KeyValuePair <(int, int), Dictionary <string, AddressItem> > section in result.HiddenDataSectionItems) { foreach (KeyValuePair <string, AddressItem> keyValuePair in section.Value) { size++; } } return(size); }
public override LinkerResult Link(LinkerTarget target, Compilation compilation) { if (target.FileCompilation.FileReferences.Count != 0) { EventManager <ErrorEvent> .SendEvent(new FileReferencesUnsupportedEvent()); } LinkerResult ret = new LinkerResult( new[] { target }, target.FileCompilation.Constants, target.FileCompilation.Labels, target.FileCompilation.DataSectionHeader, target.FileCompilation.Tokens.ToList(), target.FileCompilation.DataSection.ToArray() ); return(ret); }
private uint GetTotalEmptyVarSize(LinkerResult result) { uint size = 0; foreach (KeyValuePair <string, AddressItem> keyValuePair in result.DataSectionHeader) { if (keyValuePair.Value.IsEmpty) { size += keyValuePair.Value.Size; } } foreach (KeyValuePair <(int, int), Dictionary <string, AddressItem> > section in result.HiddenDataSectionItems) { foreach (KeyValuePair <string, AddressItem> keyValuePair in section.Value) { if (keyValuePair.Value.IsEmpty) { size += keyValuePair.Value.Size; } } } return(size); }
private List <(Dictionary <string, AddressItem>, string, AddressItem)> CleanEmptyItems(LinkerResult result) { List <(Dictionary <string, AddressItem>, string, AddressItem)> ret = new List <(Dictionary <string, AddressItem>, string, AddressItem)>(); foreach (string name in result.DataSectionHeader.Keys.ToList()) { AddressItem item = result.DataSectionHeader[name]; if (item.IsEmpty) { ret.Add((result.DataSectionHeader, name, item)); result.DataSectionHeader.Remove(name); } } foreach (KeyValuePair <(int, int), Dictionary <string, AddressItem> > section in result.HiddenDataSectionItems) { foreach (string name in section.Value.Keys.ToList()) { AddressItem item = section.Value[name]; if (item.IsEmpty) { ret.Add((section.Value, name, item)); section.Value.Remove(name); } } } return(ret); }
public override List <byte> Assemble(LinkerResult result) { List <byte> instrBytes = new List <byte>(); AssemblyGeneratorSettings settings = SettingsManager.GetSettings <AssemblyGeneratorSettings>(); Log("Using format: {0}", settings.Format); uint emptyVarSize = GetTotalEmptyVarSize(result); if (settings.Format.Contains("-ovars")) { float savedSpace = emptyVarSize / (float)GetTotalVarCount(result); Log("Saved Space: {0}%", Math.Round(savedSpace, 2) * 100); } if (settings.Format.StartsWith("v2")) { if (settings.Format.Contains("-ovars")) { instrBytes.AddRange(BitConverter.GetBytes(emptyVarSize)); } else { instrBytes.AddRange(BitConverter.GetBytes(0u)); } instrBytes.AddRange(BitConverter.GetBytes(( uint )1)); instrBytes.AddRange(BitConverter.GetBytes(settings.GlobalOffset)); instrBytes.AddRange(BitConverter.GetBytes(( uint )0)); } Dictionary <string, AddressItem> consts = result.Constants.ApplyOffset(settings.GlobalOffset).ToDictionary(x => x.Key, x => x.Value); Dictionary <string, AddressItem> labels = result.Labels.ApplyOffset(settings.GlobalOffset).ToDictionary(x => x.Key, x => x.Value); FileCompilation.ApplyToAllTokens( result.LinkedBinary, consts, new List <uint>() ); //Apply global constants List <uint> indexList = new List <uint>(); FileCompilation.ApplyToAllTokens(result.LinkedBinary, labels, indexList); FixEmptyVars(( uint )result.DataSection.Count, CleanEmptyItems(result)); Dictionary <string, AddressItem> ds = result.DataSectionHeader. ApplyOffset( settings.GlobalOffset + ( uint )result.LinkedBinary.Count * CpuSettings.InstructionSize ). ToDictionary(x => x.Key, x => x.Value); result.ApplyDataOffset( ( int )(settings.GlobalOffset + result.LinkedBinary.Count * CpuSettings.InstructionSize) ); FileCompilation.ApplyToAllTokens(result.LinkedBinary, ds, indexList); foreach (KeyValuePair <(int, int), Dictionary <string, AddressItem> > resultHiddenAddressItem in result. HiddenConstantItems) { FileCompilation.ApplyToTokens( result.LinkedBinary, resultHiddenAddressItem.Value, new List <uint>(), resultHiddenAddressItem.Key.Item1, resultHiddenAddressItem.Key.Item2 ); //Apply global constants } foreach (KeyValuePair <(int, int), Dictionary <string, AddressItem> > resultHiddenAddressItem in result. HiddenLabelItems) { Dictionary <string, AddressItem> hiddenLabels = resultHiddenAddressItem.Value.ApplyOffset(settings.GlobalOffset). ToDictionary(x => x.Key, x => x.Value); FileCompilation.ApplyToTokens( result.LinkedBinary, hiddenLabels, indexList, resultHiddenAddressItem.Key.Item1, resultHiddenAddressItem.Key.Item2 ); //Apply global constants } foreach (KeyValuePair <(int, int), Dictionary <string, AddressItem> > resultHiddenAddressItem in result. HiddenDataSectionItems) { Dictionary <string, AddressItem> hds = resultHiddenAddressItem.Value.ApplyOffset( settings.GlobalOffset + ( uint )result.LinkedBinary.Count * CpuSettings.InstructionSize ). ToDictionary( x => x.Key, x => x.Value ); FileCompilation.ApplyToTokens( result.LinkedBinary, hds, indexList, resultHiddenAddressItem.Key.Item1, resultHiddenAddressItem.Key.Item2 ); //Apply global constants } for (int i = 0; i < result.LinkedBinary.Count; i++) { List <byte> bytes = new List <byte>(); AToken instr = result.LinkedBinary[i][0]; IEnumerable <AToken> args = result.LinkedBinary[i].Skip(1); uint opCode = CpuSettings.InstructionSet.GetInstruction( CpuSettings.InstructionSet.GetInstruction( instr.GetValue(), result.LinkedBinary[i].Length - 1 ) ); bytes.AddRange(BitConverter.GetBytes(opCode)); foreach (AToken aToken in args) { if (aToken is ValueToken vToken) { bytes.AddRange(BitConverter.GetBytes(vToken.Value)); } else { EventManager <ErrorEvent> .SendEvent(new TokenRecognitionFailureEvent( aToken.GetValue())); } } if (bytes.Count > CpuSettings.ByteSize) { EventManager <ErrorEvent> .SendEvent(new InvalidArgumentCountEvent( i )); } bytes.AddRange(Enumerable.Repeat(( byte )0, ( int )CpuSettings.ByteSize - bytes.Count)); instrBytes.AddRange(bytes); } List <byte> v = result.DataSection.SelectMany(BitConverter.GetBytes).ToList(); instrBytes.AddRange(v); if (settings.Format.StartsWith("v3")) { instrBytes.InsertRange(0, indexList.SelectMany(BitConverter.GetBytes)); instrBytes.InsertRange(0, BitConverter.GetBytes(0u)); instrBytes.InsertRange(0, BitConverter.GetBytes(( uint )indexList.Count)); instrBytes.InsertRange(0, BitConverter.GetBytes(2u)); if (settings.Format.Contains("-ovars")) { instrBytes.InsertRange(0, BitConverter.GetBytes(emptyVarSize)); } else { instrBytes.InsertRange(0, BitConverter.GetBytes(0u)); } if (settings.Format.StartsWith("v3-pic")) { List <uint> symbolTable = new List <uint>(); symbolTable.Add(( uint )result.Labels.Count); foreach (KeyValuePair <string, AddressItem> keyValuePair in result.Labels) { uint[] bs = keyValuePair.Key.ToCharArray(). Select(x => ( uint )x). ToArray(); symbolTable.Add(( uint )keyValuePair.Key.Length); symbolTable.Add(keyValuePair.Value.Address); symbolTable.AddRange(bs); } instrBytes.InsertRange(0, symbolTable.SelectMany(BitConverter.GetBytes)); } } return(instrBytes); }
public abstract List <byte> Assemble(LinkerResult result);