{
methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODTABLE;
}
-
methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE;
Get_CORINFO_SIG_INFO(method, &methodInfo->args);
Get_CORINFO_SIG_INFO(methodIL.GetLocals(), &methodInfo->locals);
CorInfoType corInfoRetType = asCorInfoType(signature.ReturnType, &sig->retTypeClass);
sig->_retType = (byte)corInfoRetType;
- sig->retTypeSigClass = sig->retTypeClass; // The difference between the two is not relevant for ILCompiler
+ sig->retTypeSigClass = ObjectToHandle(signature.ReturnType);
sig->flags = 0; // used by IL stubs code
return CorInfoInitClassResult.CORINFO_INITCLASS_USE_HELPER;
}
- private void classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_STRUCT_* cls)
- {
- }
-
private CORINFO_CLASS_STRUCT_* getBuiltinClass(CorInfoClassId classId)
{
switch (classId)
// Nothing to do
}
- private void setEHcount(uint cEH)
- {
- _ehClauses = new CORINFO_EH_CLAUSE[cEH];
- }
-
- private void setEHinfo(uint EHnumber, ref CORINFO_EH_CLAUSE clause)
- {
- _ehClauses[EHnumber] = clause;
- }
-
private bool logMsg(uint level, byte* fmt, IntPtr args)
{
// Console.WriteLine(Marshal.PtrToStringAnsi((IntPtr)fmt));
private OffsetMapping[] _debugLocInfos;
private NativeVarInfo[] _debugVarInfos;
private DebugEHClauseInfo[] _debugEHClauseInfos;
+ private List<ISymbolNode> _fixups;
public MethodWithGCInfo(MethodDesc methodDesc, SignatureContext signatureContext)
{
GCInfoNode = new MethodGCInfoNode(this);
+ _fixups = new List<ISymbolNode>();
_method = methodDesc;
SignatureContext = signatureContext;
}
public MethodDesc Method => _method;
+ public List<ISymbolNode> Fixups => _fixups;
+
public bool IsEmpty => _methodCode.Data.Length == 0;
public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
}
}
+ 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;
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
{
- return new DependencyList(new DependencyListEntry[] { new DependencyListEntry(GCInfoNode, "Unwind & GC info") });
+ DependencyList dependencyList = new DependencyList(new DependencyListEntry[] { new DependencyListEntry(GCInfoNode, "Unwind & GC info") });
+
+ foreach (ISymbolNode node in _fixups)
+ {
+ dependencyList.Add(node, "classMustBeLoadedBeforeCodeIsRun");
+ }
+
+ return dependencyList;
}
public override bool StaticDependenciesAreComputed => _methodCode != null;
return attribs;
}
+ private void classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_STRUCT_* cls)
+ {
+ TypeDesc type = HandleToObject(cls);
+ classMustBeLoadedBeforeCodeIsRun(type);
+ }
+
+ private void classMustBeLoadedBeforeCodeIsRun(TypeDesc type)
+ {
+ ISymbolNode node = _compilation.SymbolNodeFactory.CreateReadyToRunHelper(ReadyToRunHelperId.TypeHandle, type, GetSignatureContext());
+ ((MethodWithGCInfo)_methodCodeNode).Fixups.Add(node);
+ }
+
private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, CORINFO_CALLINFO_FLAGS flags, CORINFO_CALL_INFO* pResult)
{
MethodDesc methodToCall;
}
private int SizeOfPInvokeTransitionFrame => ReadyToRunRuntimeConstants.READYTORUN_PInvokeTransitionFrameSizeInPointerUnits * _compilation.NodeFactory.Target.PointerSize;
+
+ private void setEHcount(uint cEH)
+ {
+ _ehClauses = new CORINFO_EH_CLAUSE[cEH];
+ }
+
+ private void setEHinfo(uint EHnumber, ref CORINFO_EH_CLAUSE clause)
+ {
+ // Filters don't have class token in the clause.ClassTokenOrOffset
+ if ((clause.Flags & CORINFO_EH_CLAUSE_FLAGS.CORINFO_EH_CLAUSE_FILTER) == 0)
+ {
+ if (clause.ClassTokenOrOffset != 0)
+ {
+ MethodIL methodIL = _compilation.GetMethodIL(MethodBeingCompiled);
+ mdToken classToken = (mdToken)clause.ClassTokenOrOffset;
+ TypeDesc clauseType = (TypeDesc)ResolveTokenInScope(methodIL, MethodBeingCompiled, classToken);
+
+ CORJIT_FLAGS flags = default(CORJIT_FLAGS);
+ getJitFlags(ref flags, 0);
+
+ if (flags.IsSet(CorJitFlag.CORJIT_FLAG_IL_STUB))
+ {
+ // IL stub tokens are 'private' and do not resolve correctly in their parent module's metadata.
+
+ // Currently, the only place we are using a token here is for a COM-to-CLR exception-to-HRESULT
+ // mapping catch clause. We want this catch clause to catch all exceptions, so we override the
+ // token to be mdTypeRefNil, which used by the EH system to mean catch(...)
+ Debug.Assert(clauseType.IsObject);
+ clause.ClassTokenOrOffset = 0;
+ }
+ else
+ {
+ // For all clause types add fixup to ensure the types are loaded before the code of the method
+ // containing the catch blocks is executed. This ensures that a failure to load the types would
+ // not happen when the exception handling is in progress and it is looking for a catch handler.
+ // At that point, we could only fail fast.
+ classMustBeLoadedBeforeCodeIsRun(clauseType);
+ }
+ }
+ }
+
+ _ehClauses[EHnumber] = clause;
+ }
}
}