private void embedGenericHandle(IntPtr _this, ref CORINFO_RESOLVED_TOKEN pResolvedToken, [MarshalAs(UnmanagedType.Bool)]bool fEmbedParent, ref CORINFO_GENERICHANDLE_RESULT pResult) { #if DEBUG // In debug, write some bogus data to the struct to ensure we have filled everything // properly. fixed (CORINFO_GENERICHANDLE_RESULT* tmp = &pResult) MemoryHelper.FillMemory((byte*)tmp, 0xcc, Marshal.SizeOf<CORINFO_GENERICHANDLE_RESULT>()); #endif if (!fEmbedParent && pResolvedToken.hMethod != null) { throw new NotImplementedException("embedGenericHandle"); } else if (!fEmbedParent && pResolvedToken.hField != null) { pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_FIELD; pResult.compileTimeHandle = (CORINFO_GENERIC_STRUCT_*)pResolvedToken.hField; // fRuntimeLookup = th.IsSharedByGenericInstantiations() && pFD->IsStatic(); } else { TypeDesc td = HandleToObject(pResolvedToken.hClass); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_CLASS; pResult.compileTimeHandle = (CORINFO_GENERIC_STRUCT_*)pResolvedToken.hClass; // TODO? If we're embedding a method handle for a method that points to a sub-class of the actual // class, we might need to embed the actual declaring type in compileTimeHandle. // IsSharedByGenericInstantiations would not work here. The runtime lookup is required // even for standalone generic variables that show up as __Canon here. //fRuntimeLookup = th.IsCanonicalSubtype(); } Debug.Assert(pResult.compileTimeHandle != null); // TODO: shared generics //if (...) //{ // ... //} // else { // If the target is not shared then we've already got our result and // can simply do a static look up pResult.lookup.lookupKind.needsRuntimeLookup = false; pResult.lookup.constLookup.handle = (CORINFO_GENERIC_STRUCT_*)pResult.compileTimeHandle; pResult.lookup.constLookup.accessType = InfoAccessType.IAT_VALUE; } }
public virtual void embedGenericHandle_wrapper(IntPtr _this, out IntPtr exception, ref CORINFO_RESOLVED_TOKEN pResolvedToken, [MarshalAs(UnmanagedType.Bool)]bool fEmbedParent, ref CORINFO_GENERICHANDLE_RESULT pResult) { exception = IntPtr.Zero; try { embedGenericHandle(ref pResolvedToken, fEmbedParent, ref pResult); return; } catch (Exception ex) { exception = AllocException(ex); } }
private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, [MarshalAs(UnmanagedType.Bool)]bool fEmbedParent, ref CORINFO_GENERICHANDLE_RESULT pResult) { #if DEBUG // In debug, write some bogus data to the struct to ensure we have filled everything // properly. fixed (CORINFO_GENERICHANDLE_RESULT* tmp = &pResult) MemoryHelper.FillMemory((byte*)tmp, 0xcc, Marshal.SizeOf<CORINFO_GENERICHANDLE_RESULT>()); #endif bool runtimeLookup; if (!fEmbedParent && pResolvedToken.hMethod != null) { MethodDesc md = HandleToObject(pResolvedToken.hMethod); TypeDesc td = HandleToObject(pResolvedToken.hClass); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_METHOD; Debug.Assert(md.OwningType == td); runtimeLookup = md.IsSharedByGenericInstantiations; pResult.compileTimeHandle = (CORINFO_GENERIC_STRUCT_*)ObjectToHandle(md); if (!runtimeLookup) { // TODO: LDTOKEN <method>? } else { pResult.lookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunFixupKind.MethodHandle; } } else if (!fEmbedParent && pResolvedToken.hField != null) { FieldDesc fd = HandleToObject(pResolvedToken.hField); TypeDesc td = HandleToObject(pResolvedToken.hClass); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_FIELD; pResult.compileTimeHandle = (CORINFO_GENERIC_STRUCT_*)pResolvedToken.hField; runtimeLookup = fd.IsStatic && td.IsCanonicalSubtype(CanonicalFormKind.Any); if (!runtimeLookup) { // TODO: Handle should actually point to a dependency node (we don't have one yet) pResult.lookup.constLookup.handle = (CORINFO_GENERIC_STRUCT_*)pResult.compileTimeHandle; } else { pResult.lookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunFixupKind.FieldHandle; } } else { TypeDesc td = HandleToObject(pResolvedToken.hClass); pResult.handleType = CorInfoGenericHandleType.CORINFO_HANDLETYPE_CLASS; pResult.compileTimeHandle = (CORINFO_GENERIC_STRUCT_*)pResolvedToken.hClass; runtimeLookup = td.IsCanonicalSubtype(CanonicalFormKind.Any); if (!runtimeLookup) { if (pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_NewObj) pResult.lookup.constLookup.handle = (CORINFO_GENERIC_STRUCT_*)ObjectToHandle(_compilation.NodeFactory.ConstructedTypeSymbol(td)); else pResult.lookup.constLookup.handle = (CORINFO_GENERIC_STRUCT_*)ObjectToHandle(_compilation.NodeFactory.NecessaryTypeSymbol(td)); } else { pResult.lookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunFixupKind.TypeHandle; } } Debug.Assert(pResult.compileTimeHandle != null); if (runtimeLookup) { pResult.lookup.lookupKind.needsRuntimeLookup = true; pResult.lookup.runtimeLookup.signature = null; pResult.lookup.runtimeLookup.indirections = CORINFO.USEHELPER; MethodDesc contextMethod = methodFromContext(pResolvedToken.tokenContext); // Do not bother computing the runtime lookup if we are inlining. The JIT is going // to abort the inlining attempt anyway. if (contextMethod != MethodBeingCompiled) return; pResult.lookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(contextMethod); } else { // If the target is not shared then we've already got our result and // can simply do a static look up pResult.lookup.lookupKind.needsRuntimeLookup = false; pResult.lookup.constLookup.accessType = InfoAccessType.IAT_VALUE; } }
static void _embedGenericHandle(IntPtr thisHandle, IntPtr* ppException, ref CORINFO_RESOLVED_TOKEN pResolvedToken, [MarshalAs(UnmanagedType.Bool)]bool fEmbedParent, ref CORINFO_GENERICHANDLE_RESULT pResult) { var _this = GetThis(thisHandle); try { _this.embedGenericHandle(ref pResolvedToken, fEmbedParent, ref pResult); } catch (Exception ex) { *ppException = _this.AllocException(ex); } }