Esempio n. 1
0
        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);
        }
Esempio n. 2
0
 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
     });
 }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
 public abstract List <byte> Assemble(LinkerResult result);