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; } }
public void AddImport(Import import) { _methods.Add(import as IMethodNode as MethodWithGCInfo); }
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()); }
public void AddImport(Import import) { _methods.Add(import as IMethodNode); }