Example #1
0
        public ImportThunk(ReadyToRunHelper helperId, ReadyToRunCodegenNodeFactory factory, Import instanceCell, bool useVirtualCall)
        {
            _helperCell   = factory.GetReadyToRunHelperCell(helperId);
            _instanceCell = instanceCell;
            _moduleImport = factory.ModuleImport;

            if (useVirtualCall)
            {
                _thunkKind = Kind.VirtualStubDispatch;
            }
            else if (helperId == ReadyToRunHelper.GetString)
            {
                _thunkKind = Kind.Lazy;
            }
            else if (helperId == ReadyToRunHelper.DelayLoad_MethodCall ||
                     helperId == ReadyToRunHelper.DelayLoad_Helper ||
                     helperId == ReadyToRunHelper.DelayLoad_Helper_Obj ||
                     helperId == ReadyToRunHelper.DelayLoad_Helper_ObjObj)
            {
                _thunkKind = Kind.DelayLoadHelper;
            }
            else
            {
                _thunkKind = Kind.Eager;
            }
        }
Example #2
0
 public void AddImport(Import import)
 {
     _methods.Add(import as IMethodNode as MethodWithGCInfo);
 }
Example #3
0
        public byte[] GetFixupBlob(NodeFactory factory)
        {
            Relocation[] relocations = GetData(factory, relocsOnly: true).Relocs;

            if (relocations == null)
            {
                return(null);
            }

            List <FixupCell> fixupCells = null;

            foreach (Relocation reloc in relocations)
            {
                if (reloc.Target is Import fixupCell && fixupCell.EmitPrecode)
                {
                    if (fixupCells == null)
                    {
                        fixupCells = new List <FixupCell>();
                    }
                    fixupCells.Add(new FixupCell(fixupCell.Table.IndexFromBeginningOfArray, fixupCell.OffsetFromBeginningOfArray));
                }
            }

            foreach (ISymbolNode node in _fixups)
            {
                if (fixupCells == null)
                {
                    fixupCells = new List <FixupCell>();
                }

                Import fixupCell = (Import)node;
                fixupCells.Add(new FixupCell(fixupCell.Table.IndexFromBeginningOfArray, fixupCell.OffsetFromBeginningOfArray));
            }

            if (fixupCells == null)
            {
                return(null);
            }

            fixupCells.Sort(FixupCell.Comparer);

            // Deduplicate fixupCells
            int j = 0;

            for (int i = 1; i < fixupCells.Count; i++)
            {
                if (FixupCell.Comparer.Compare(fixupCells[j], fixupCells[i]) != 0)
                {
                    j++;
                    if (i != j)
                    {
                        fixupCells[j] = fixupCells[i];
                    }
                }
            }

            // Move j to point after the last valid fixupCell in the array
            j++;

            if (j < fixupCells.Count)
            {
                fixupCells.RemoveRange(j, fixupCells.Count - j);
            }

            NibbleWriter writer = new NibbleWriter();

            int curTableIndex = -1;
            int curOffset     = 0;

            foreach (FixupCell cell in fixupCells)
            {
                Debug.Assert(cell.ImportOffset % factory.Target.PointerSize == 0);
                int offset = cell.ImportOffset / factory.Target.PointerSize;

                if (cell.TableIndex != curTableIndex)
                {
                    // Write delta relative to the previous table index
                    Debug.Assert(cell.TableIndex > curTableIndex);
                    if (curTableIndex != -1)
                    {
                        writer.WriteUInt(0);                                       // table separator, so add except for the first entry
                        writer.WriteUInt((uint)(cell.TableIndex - curTableIndex)); // add table index delta
                    }
                    else
                    {
                        writer.WriteUInt((uint)cell.TableIndex);
                    }
                    curTableIndex = cell.TableIndex;

                    // This is the first fixup in the current table.
                    // We will write it out completely (without delta-encoding)
                    writer.WriteUInt((uint)offset);
                }
                else if (offset != curOffset) // ignore duplicate fixup cells
                {
                    // This is not the first entry in the current table.
                    // We will write out the delta relative to the previous fixup value
                    int delta = offset - curOffset;
                    Debug.Assert(delta > 0);
                    writer.WriteUInt((uint)delta);
                }

                // future entries for this table would be relative to this rva
                curOffset = offset;
            }

            writer.WriteUInt(0); // table separator
            writer.WriteUInt(0); // fixup list ends

            return(writer.ToArray());
        }
Example #4
0
 public void AddImport(Import import)
 {
     _methods.Add(import as IMethodNode);
 }