Beispiel #1
0
 /// <summary>
 /// Creates a LocalVariableTable from a SerLocalVariableTable.
 /// </summary>
 /// <param name="serTable">Deserialized data.</param>
 /// <param name="contentVersion">Serialization version.</param>
 /// <param name="report">Error report object.</param>
 /// <param name="outLvt">Created LocalVariableTable</param>
 /// <returns>True on success.</returns>
 private static bool CreateLocalVariableTable(SerLocalVariableTable serTable,
                                              int contentVersion, FileLoadReport report, out LocalVariableTable outLvt)
 {
     outLvt = new LocalVariableTable();
     outLvt.ClearPrevious = serTable.ClearPrevious;
     foreach (SerDefSymbol serDef in serTable.Variables)
     {
         // Force the "has width" field to true for local variables, because it's
         // non-optional there.  This is really only needed for loading projects
         // created in v1.3, which didn't have the "has width" property.
         serDef.HasWidth = true;
         if (!CreateDefSymbol(serDef, contentVersion, report, out DefSymbol defSym))
         {
             return(false);
         }
         if (!defSym.IsVariable)
         {
             // not expected to happen; skip it
             Debug.WriteLine("Found local variable with bad source: " +
                             defSym.SymbolSource);
             string str = string.Format(Res.Strings.ERR_BAD_LOCAL_VARIABLE_FMT,
                                        defSym);
             report.Add(FileLoadItem.Type.Warning, str);
             continue;
         }
         outLvt.AddOrReplace(defSym);
     }
     return(true);
 }
Beispiel #2
0
        /// <summary>
        /// Updates internal state to reflect the state of the world at the specified offset.
        /// </summary>
        /// <remarks>
        /// When the offset is greater than or equal to its value on a previous call, we can
        /// do an incremental update.  If the offset moves backward, we have to reset and walk
        /// forward again.
        /// </remarks>
        /// <param name="targetOffset">Target offset.</param>
        private void AdvanceToOffset(int targetOffset)
        {
            if (mNextLvtIndex < 0)
            {
                return;
            }
            if (targetOffset < mRecentOffset)
            {
                // We went backwards.
                Reset();
            }
            while (mNextLvtOffset <= targetOffset)
            {
                if (!mProject.GetAnattrib(mNextLvtOffset).IsStart)
                {
                    // Hidden table, ignore it.
                    Debug.WriteLine("Ignoring LvTable at +" + mNextLvtOffset.ToString("x6"));
                }
                else
                {
                    // Process this table.
                    LocalVariableTable lvt = mLvTables.Values[mNextLvtIndex];
                    if (lvt.ClearPrevious)
                    {
                        mCurrentTable.Clear();
                    }

                    // Create a list for GetVariablesDefinedAtOffset
                    mRecentSymbols = new List <DefSymbol>();
                    mRecentOffset  = mNextLvtOffset;

                    // Merge the new entries into the work table.  This automatically
                    // discards entries that clash by name or value.
                    for (int i = 0; i < lvt.Count; i++)
                    {
                        DefSymbol defSym = lvt[i];

                        // Look for non-variable symbols with the same label.  Ordinarily the
                        // editor prevents this from happening, but there are ways to trick
                        // the system (e.g. add a symbol while the LvTable is hidden).  We
                        // deal with it here.
                        if (mSymbolTable.TryGetNonVariableValue(defSym.Label, out Symbol unused))
                        {
                            Debug.WriteLine("Detected duplicate non-var label " + defSym.Label +
                                            " at +" + mNextLvtOffset.ToString("x6"));
                            string newLabel = DeDupLabel(defSym.Label);
                            mDupRemap[defSym.Label] = newLabel;
                            defSym = new DefSymbol(defSym, newLabel);
                        }

                        if (mDoUniquify)
                        {
                            if (mUniqueLabels.TryGetValue(defSym.Label, out UniqueLabel ulab))
                            {
                                // We've seen this label before; generate a unique version by
                                // increasing the appended number.
                                ulab.MakeUnique(mSymbolTable);
                                defSym = new DefSymbol(defSym, ulab.Label);
                            }
                            else
                            {
                                // Haven't seen this before.  Add it to the unique-labels table.
                                mUniqueLabels.Add(defSym.Label, new UniqueLabel(defSym.Label));
                            }
                        }
                        mCurrentTable.AddOrReplace(defSym);

                        mRecentSymbols.Add(defSym);
                    }

                    //mCurrentTable.DebugDump(mNextLvtOffset);
                }

                // Update state to look for next table.
                mNextLvtIndex++;
                if (mNextLvtIndex < mLvTables.Keys.Count)
                {
                    mNextLvtOffset = mLvTables.Keys[mNextLvtIndex];
                }
                else
                {
                    mNextLvtOffset = mProject.FileDataLength;   // never reached
                }
            }
        }
        /// <summary>
        /// Updates internal state to reflect the state of the world at the specified offset.
        /// </summary>
        /// <remarks>
        /// When the offset is greater than or equal to its value on a previous call, we can
        /// do an incremental update.  If the offset moves backward, we have to reset and walk
        /// forward again.
        /// </remarks>
        /// <param name="targetOffset">Target offset.</param>
        private void AdvanceToOffset(int targetOffset)
        {
            if (mNextLvtIndex < 0)
            {
                return;
            }
            if (targetOffset < mRecentOffset)
            {
                // We went backwards.
                Reset(false);
            }
            while (mNextLvtOffset <= targetOffset)
            {
                if (!mProject.GetAnattrib(mNextLvtOffset).IsStart)
                {
                    // Hidden table, ignore it.
                    Debug.WriteLine("Ignoring LvTable at +" + mNextLvtOffset.ToString("x6"));
                }
                else
                {
                    // Process this table.
                    LocalVariableTable lvt = mLvTables.Values[mNextLvtIndex];
                    if (lvt.ClearPrevious)
                    {
                        mCurrentTable.Clear();
                    }

                    // Create a list for GetVariablesDefinedAtOffset
                    mRecentSymbols = new List <DefSymbol>();
                    mRecentOffset  = mNextLvtOffset;

                    // Merge the new entries into the work table.  This automatically
                    // discards entries that clash by name or value.
                    for (int i = 0; i < lvt.Count; i++)
                    {
                        DefSymbol defSym   = lvt[i];
                        string    newLabel = defSym.Label;

                        if (mMaskLeadingUnderscores && newLabel[0] == '_')
                        {
                            newLabel = AsmGen.LabelLocalizer.NO_UNDER_PFX + newLabel;
                        }

                        // Look for non-variable symbols with the same label.  Ordinarily the
                        // editor prevents this from happening, but there are ways to trick
                        // the system (e.g. add a symbol while the LvTable is hidden, or have
                        // a non-unique local promoted to global).  We deal with it here.
                        //
                        // TODO(someday): this is not necessary for assemblers like Merlin 32
                        // that put variables in a separate namespace.
                        if (mAllNvSymbols.TryGetValue(newLabel, out Symbol unused))
                        {
                            Debug.WriteLine("Detected duplicate non-var label " + newLabel +
                                            " at +" + mNextLvtOffset.ToString("x6"));
                            newLabel = GenerateDeDupLabel(newLabel);
                        }

                        if (newLabel != defSym.Label)
                        {
                            mDupRemap[defSym.Label] = newLabel;
                            defSym = new DefSymbol(defSym, newLabel);
                        }

                        if (mDoUniquify)
                        {
                            if (mUniqueLabels.TryGetValue(defSym.Label, out UniqueLabel ulab))
                            {
                                // We've seen this label before; generate a unique version by
                                // increasing the appended number.
                                ulab.MakeUnique(mAllNvSymbols);
                                defSym = new DefSymbol(defSym, ulab.Label);
                            }
                            else
                            {
                                // Haven't seen this before.  Add it to the unique-labels table.
                                mUniqueLabels.Add(defSym.Label, new UniqueLabel(defSym.Label));
                            }
                        }
                        mCurrentTable.AddOrReplace(defSym);

                        mRecentSymbols.Add(defSym);
                    }

                    //mCurrentTable.DebugDump(mNextLvtOffset);
                }

                // Update state to look for next table.
                mNextLvtIndex++;
                if (mNextLvtIndex < mLvTables.Keys.Count)
                {
                    mNextLvtOffset = mLvTables.Keys[mNextLvtIndex];
                }
                else
                {
                    mNextLvtOffset = mProject.FileDataLength;   // never reached
                }
            }
        }