public static tMD_MethodDef *GetMethodDefFromSpec(tMD_MethodSpec *pMethodSpec, tMD_TypeDef **ppCallingClassTypeArgs, tMD_TypeDef **ppCallingMethodTypeArgs) { tMD_MethodDef *pCoreMethod; tMD_MethodDef *pMethod; /*SIG*/ byte * sig; uint argCount, i; tMD_TypeDef ** ppTypeArgs; Mem.heapcheck(); pCoreMethod = MetaData.GetMethodDefFromDefRefOrSpec(pMethodSpec->pMetaData, pMethodSpec->method, null, null);//ppCallingClassTypeArgs, ppCallingMethodTypeArgs); //ppClassTypeArgs = pCoreMethod->pParentType->ppClassTypeArgs; sig = MetaData.GetBlob(pMethodSpec->instantiation, null); MetaData.DecodeSigEntry(&sig); // always 0x0a argCount = MetaData.DecodeSigEntry(&sig); ppTypeArgs = (tMD_TypeDef **)Mem.malloc((SIZE_T)(argCount * sizeof(tMD_TypeDef *))); for (i = 0; i < argCount; i++) { tMD_TypeDef *pArgType; pArgType = Type.GetTypeFromSig(pMethodSpec->pMetaData, &sig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs, null); ppTypeArgs[i] = pArgType; } pMethod = Generics.GetMethodDefFromCoreMethod(pCoreMethod, pCoreMethod->pParentType, argCount, ppTypeArgs); Mem.free(ppTypeArgs); Mem.heapcheck(); return(pMethod); }
public static tMD_TypeDef *GetGenericTypeFromSig(tMetaData *pMetaData, /*SIG*/ byte **pSig, tMD_TypeDef **ppCallingClassTypeArgs, tMD_TypeDef **ppCallingMethodTypeArgs) { tMD_TypeDef * pCoreType; tMD_TypeDef * pRet; uint numTypeArgs, i; tMD_TypeDef **ppTypeArgs; Mem.heapcheck(); pCoreType = Type.GetTypeFromSig(pMetaData, pSig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs, null); MetaData.Fill_TypeDef(pCoreType, ppCallingClassTypeArgs, ppCallingMethodTypeArgs, Type.TYPE_FILL_PARENTS); //null, null); numTypeArgs = MetaData.DecodeSigEntry(pSig); ppTypeArgs = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))); for (i = 0; i < numTypeArgs; i++) { ppTypeArgs[i] = Type.GetTypeFromSig(pMetaData, pSig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs); if (ppTypeArgs[i] != null) { MetaData.Fill_TypeDef(ppTypeArgs[i], null, null, Type.TYPE_FILL_PARENTS); } } pRet = GetGenericTypeFromCoreType(pCoreType, numTypeArgs, ppTypeArgs); Mem.free(ppTypeArgs); Mem.heapcheck(); return(pRet); }
public static byte *strdup(byte *s) { Mem.heapcheck(); int len = strlen(s) + 1; byte *p = (byte *)Mem.malloc((SIZE_T)len); strncpy(p, s, len); return(p); }
public static tMD_MethodDef *GetMethodDefFromCoreMethod(tMD_MethodDef *pCoreMethod, tMD_TypeDef *pParentType, uint numTypeArgs, tMD_TypeDef **ppTypeArgs, HashSet <PTR> resolveTypes = null) { tGenericMethodInstance *pInst; tMD_MethodDef * pMethod; int i; Mem.heapcheck(); // See if we already have an instance with the given type args pInst = pCoreMethod->pGenericMethodInstances; while (pInst != null) { if (pInst->numTypeArgs == numTypeArgs && Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0) { return(pInst->pInstanceMethodDef); } pInst = pInst->pNext; } // We don't have an instance so create one now. pInst = (tGenericMethodInstance *)Mem.mallocForever((SIZE_T)(sizeof(tGenericMethodInstance))); pInst->pNext = pCoreMethod->pGenericMethodInstances; pCoreMethod->pGenericMethodInstances = pInst; pInst->numTypeArgs = numTypeArgs; pInst->ppTypeArgs = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))); Mem.memcpy(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))); pInst->pInstanceMethodDef = pMethod = ((tMD_MethodDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_MethodDef))); Mem.memset(pMethod, 0, (SIZE_T)sizeof(tMD_MethodDef)); pMethod->pMethodDef = pMethod; pMethod->pMetaData = pCoreMethod->pMetaData; pMethod->pCIL = pCoreMethod->pCIL; pMethod->implFlags = pCoreMethod->implFlags; pMethod->flags = pCoreMethod->flags; pMethod->name = pCoreMethod->name; pMethod->signature = pCoreMethod->signature; pMethod->vTableOfs = pCoreMethod->vTableOfs; pMethod->ppMethodTypeArgs = pInst->ppTypeArgs; MetaData.Fill_MethodDef(pParentType, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs); Mem.heapcheck(); return(pMethod); }
public static int Execute() { Mem.heapcheck(); int returnCode = 0; for (;;) { uint status = Thread.Update(maxInstrPerThread, &returnCode); if (status == THREADSTATE_STOPPED) { break; } } Mem.heapcheck(); return(returnCode); }
public static DnaObject CreateInstance(tMD_TypeDef *pTypeDef, object monoBaseObject = null) { Mem.heapcheck(); byte *pPtr = null; if (monoBaseObject != null) { pPtr = Heap.AllocMonoObject(pTypeDef, monoBaseObject); } else { pPtr = Heap.AllocType(pTypeDef); } Mem.heapcheck(); return(WrapObject(pPtr)); }
public static tMethodState *Direct(tThread *pThread, tMD_MethodDef *pMethod, tMethodState *pCaller, uint isInternalNewObjCall) { tMethodState *pThis; Mem.heapcheck(); if (pMethod->isFilled == 0) { tMD_TypeDef *pTypeDef; pTypeDef = MetaData.GetTypeDefFromMethodDef(pMethod); MetaData.Fill_TypeDef(pTypeDef, null, null); } pThis = (tMethodState *)Thread.StackAlloc(pThread, (uint)sizeof(tMethodState)); pThis->finalizerThis = null; pThis->pCaller = pCaller; pThis->pMetaData = pMethod->pMetaData; pThis->pMethod = pMethod; if (pMethod->pJITted == null) { // If method has not already been JITted JIT.Prepare(pMethod, 0); } pThis->pJIT = pMethod->pJITted; pThis->ipOffset = 0; pThis->pEvalStack = (byte *)Thread.StackAlloc(pThread, pThis->pMethod->pJITted->maxStack); pThis->stackOfs = 0; pThis->isInternalNewObjCall = isInternalNewObjCall; pThis->pNextDelegate = null; pThis->pDelegateParams = null; pThis->pParamsLocals = (byte *)Thread.StackAlloc(pThread, pMethod->parameterStackSize + pMethod->pJITted->localsStackSize); Mem.memset(pThis->pParamsLocals, 0, pMethod->parameterStackSize + pMethod->pJITted->localsStackSize); #if DIAG_METHOD_CALLS // Keep track of the number of times this method is called pMethod->callCount++; pThis->startTime = microTime(); #endif Mem.heapcheck(); return(pThis); }
public static byte *strncat(byte *a, string b, int size) { Mem.heapcheck(); if (a == null || b == null) { throw new System.NullReferenceException(); } byte *dst = a; int len = strlen(a); if (len + 1 >= size) { throw new System.IndexOutOfRangeException(); } strncpy(a + len, b, size - len); Mem.heapcheck(); return(dst); }
public static byte *strncpy(byte *a, byte *b, int size) { Mem.heapcheck(); if (a == null || b == null) { throw new System.NullReferenceException(); } byte *dst = a; byte *end = a + (size - 1); while (*b != 0) { if (a >= end) { throw new System.IndexOutOfRangeException(); } *a++ = *b++; } *a = 0; Mem.heapcheck(); return(dst); }
public static byte *strncpy(byte *a, string b, int size) { Mem.heapcheck(); if (a == null || b == null) { throw new System.NullReferenceException(); } byte *dst = a; byte *end = a + (size - 1); int len = b.Length; for (int i = 0; i < len; i++) { if (a >= end) { throw new System.IndexOutOfRangeException(); } *a++ = (byte)b[i]; } *a = 0; Mem.heapcheck(); return(dst); }
public static byte *scatprintf(byte *bfr, byte *end, string fmt, params object[] args) { if (bfr == null || fmt == null) { throw new System.NullReferenceException(); } Mem.heapcheck(); int curarg = 0; int i = 0; int fmtLen = fmt.Length; byte *b = bfr; byte *e = end; while (i < fmtLen) { char ch = fmt[i]; if (ch == '%' && i + 1 < fmtLen) { i++; ch = fmt[i]; if (ch == 's') { object sarg = args[curarg]; curarg++; if (sarg == null) { if (b + 4 > e) { throw new System.IndexOutOfRangeException(); } *b++ = (byte)'n'; *b++ = (byte)'u'; *b++ = (byte)'l'; *b++ = (byte)'l'; } else if (sarg is string) { string str = (string)sarg; for (int j = 0; j < str.Length; j++) { if (b >= e) { throw new System.IndexOutOfRangeException(); } *b++ = (byte)str[j]; } } else if (sarg is PTR) { byte *s = (byte *)((PTR)sarg); if (s == null) { if (b + 4 >= e) { throw new System.IndexOutOfRangeException(); } *b++ = (byte)'n'; *b++ = (byte)'u'; *b++ = (byte)'l'; *b++ = (byte)'l'; } else { while (*s != 0) { if (b >= e) { throw new System.IndexOutOfRangeException(); } *b++ = *s++; } } } else { throw new System.ArgumentException(); } } else if (ch == 'x' || ch == 'X' || ch == 'd') { int v; object arg = args[curarg]; if (arg is int) { v = (int)arg; } else if (arg is uint) { v = (int)(uint)arg; } else if (arg is long) { v = (int)(long)arg; } else if (arg is ulong) { v = (int)(ulong)arg; } else { v = System.Convert.ToInt32(arg); } curarg++; string vs = (ch == 'x' || ch == 'X' ? v.ToString("X") : v.ToString()); for (int j = 0; j < vs.Length; j++) { if (b >= e) { throw new System.IndexOutOfRangeException(); } *b++ = (byte)vs[j]; } } else if (ch == 'l' && i + 2 < fmtLen && fmt[i + 1] == 'l' && (fmt[i + 2] == 'x' || fmt[i + 2] == 'X' || fmt[i + 2] == 'd')) { i += 2; ch = fmt[i]; long lv = System.Convert.ToInt64(args[curarg]); curarg++; string lvs = (ch == 'x' || ch == 'X' ? lv.ToString("X") : lv.ToString()); for (int j = 0; j < lvs.Length; j++) { if (b >= e) { throw new System.IndexOutOfRangeException(); } *b++ = (byte)lvs[j]; } } else if (ch == '0' && i + 2 < fmtLen && (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') && (fmt[i + 2] == 'x' || fmt[i + 2] == 'X' || fmt[i + 2] == 'd')) { char l0 = fmt[i + 1]; i += 2; ch = fmt[i]; int v0; object arg = args[curarg]; if (arg is int) { v0 = (int)arg; } else if (arg is uint) { v0 = (int)(uint)arg; } else if (arg is long) { v0 = (int)(long)arg; } else if (arg is ulong) { v0 = (int)(ulong)arg; } else { v0 = System.Convert.ToInt32(arg); } curarg++; string vs0 = (ch == 'x' || ch == 'X' ? v0.ToString("X" + l0) : v0.ToString("D" + l0)); for (int j = 0; j < vs0.Length; j++) { if (b >= e) { throw new System.IndexOutOfRangeException(); } *b++ = (byte)vs0[j]; } } else { if (b >= e) { throw new System.IndexOutOfRangeException(); } *b++ = (byte)ch; } } else { if (b >= e) { throw new System.IndexOutOfRangeException(); } *b++ = (byte)ch; } i++; } // Null terminator *b = 0; Mem.heapcheck(); return(b); }
public static tMD_TypeDef *GetGenericTypeFromCoreType(tMD_TypeDef *pCoreType, uint numTypeArgs, tMD_TypeDef **ppTypeArgs) { tGenericInstance *pInst; tMD_TypeDef * pTypeDef; uint i; byte * name = stackalloc byte[NAME_BUF_SIZE]; byte * namePos, nameEnd; tMetaData *pMetaData; Mem.heapcheck(); pMetaData = pCoreType->pMetaData; MetaData.Fill_TypeDef(pCoreType, null, null, Type.TYPE_FILL_PARENTS); // See if we have already built an instantiation of this type with the given type args. pInst = pCoreType->pGenericInstances; while (pInst != null) { if (pInst->numTypeArgs == numTypeArgs && Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0) { return(pInst->pInstanceTypeDef); } pInst = pInst->pNext; } // This has not already been instantiated, so instantiate it now. pInst = (tGenericInstance *)Mem.mallocForever((SIZE_T)sizeof(tGenericInstance)); // Insert this into the chain of instantiations. pInst->pNext = pCoreType->pGenericInstances; pCoreType->pGenericInstances = pInst; // Copy the type args into the instantiation. pInst->numTypeArgs = numTypeArgs; pInst->ppTypeArgs = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))); Mem.memcpy(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))); Mem.heapcheck(); // Create the new instantiated type pInst->pInstanceTypeDef = pTypeDef = ((tMD_TypeDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_TypeDef))); Mem.memset(pTypeDef, 0, (SIZE_T)sizeof(tMD_TypeDef)); // Make the name of the instantiation. namePos = name; nameEnd = namePos + NAME_BUF_SIZE - 1; namePos = S.scatprintf(namePos, nameEnd, "%s", (PTR)pCoreType->name); namePos = S.scatprintf(namePos, nameEnd, "["); for (i = 0; i < numTypeArgs; i++) { if (i > 0) { namePos = S.scatprintf(namePos, nameEnd, ","); } if (ppTypeArgs[i] != null) { namePos = S.scatprintf(namePos, nameEnd, "%s.%s", (PTR)ppTypeArgs[i]->nameSpace, (PTR)ppTypeArgs[i]->name); } else { tMD_GenericParam *pGenericParam = FindGenericParam(pCoreType, i); if (pGenericParam != null) { namePos = S.scatprintf(namePos, nameEnd, "%s", (PTR)pGenericParam->name); } else { namePos = S.scatprintf(namePos, nameEnd, "???"); } } } namePos = S.scatprintf(namePos, nameEnd, "]"); // Fill in the basic bits of the new type def. pTypeDef->pTypeDef = pTypeDef; pTypeDef->pMetaData = pMetaData; pTypeDef->flags = pCoreType->flags; pTypeDef->pGenericDefinition = pCoreType; for (i = 0; i < numTypeArgs; i++) { if (ppTypeArgs[i] == null) { pTypeDef->isGenericDefinition = 1; break; } } pTypeDef->nameSpace = pCoreType->nameSpace; int nameLen = S.strlen(name) + 1; pTypeDef->name = (/*STRING*/ byte *)Mem.mallocForever((SIZE_T)nameLen); S.strncpy(pTypeDef->name, name, nameLen); pTypeDef->ppClassTypeArgs = pInst->ppTypeArgs; pTypeDef->extends = pCoreType->extends; pTypeDef->tableIndex = pCoreType->tableIndex; pTypeDef->fieldList = pCoreType->fieldList; pTypeDef->methodList = pCoreType->methodList; pTypeDef->numFields = pCoreType->numFields; pTypeDef->numMethods = pCoreType->numMethods; pTypeDef->numVirtualMethods = pCoreType->numVirtualMethods; pTypeDef->pNestedIn = pCoreType->pNestedIn; pTypeDef->isPrimed = 1; MetaData.Fill_TypeDef(pTypeDef, pInst->ppTypeArgs, null, Type.TYPE_FILL_PARENTS); Mem.heapcheck(); return(pTypeDef); }
public static void GarbageCollect() { #if NO tHeapRoots heapRoots; tHeapEntry * pNode; tHeapEntry **pUp = stackalloc tHeapEntry *[MAX_TREE_DEPTH * 2]; int top; tHeapEntry * pToDelete = null; SIZE_T orgHeapSize = trackHeapSize; uint orgNumNodes = numNodes; #if DIAG_GC ulong startTime; #endif Mem.heapcheck(); numCollections++; #if DIAG_GC startTime = microTime(); #endif heapRoots.capacity = 64; heapRoots.num = 0; heapRoots.pHeapEntries = (tHeapRootEntry *)Mem.malloc(heapRoots.capacity * (SIZE_T)sizeof(tHeapRootEntry)); Thread.GetHeapRoots(&heapRoots); CLIFile.GetHeapRoots(&heapRoots); // Mark phase while (heapRoots.num > 0) { tHeapRootEntry *pRootsEntry; uint i; uint moreRootsAdded = 0; uint rootsEntryNumPointers; void ** pRootsEntryMem; // Get a piece of memory off the list of heap memory roots. pRootsEntry = &heapRoots.pHeapEntries[heapRoots.num - 1]; rootsEntryNumPointers = pRootsEntry->numPointers; pRootsEntryMem = pRootsEntry->pMem; // Mark this entry as done pRootsEntry->numPointers = 0; pRootsEntry->pMem = null; // Iterate through all pointers in it for (i = 0; i < rootsEntryNumPointers; i++) { void *pMemRef = pRootsEntryMem[i]; // Quick escape for known non-memory if (pMemRef == null) { continue; } // Find this piece of heap memory in the tracking tree. // Note that the 2nd memory address comparison MUST be >, not >= as might be expected, // to allow for a zero-sized memory to be detected (and not garbage collected) properly. // E.g. The object class has zero memory. pNode = pHeapTreeRoot; while (pNode != nil) { if (pMemRef < (void *)pNode) { pNode = (tHeapEntry *)pNode->pLink[0]; } else if ((byte *)pMemRef > ((byte *)pNode) + GetSize(pNode) + sizeof(tHeapEntry)) { pNode = (tHeapEntry *)pNode->pLink[1]; } else { // Found memory. See if it's already been marked. // If it's already marked, then don't do anything. // It it's not marked, then add all of its memory to the roots, and mark it. if (pNode->marked == 0) { tMD_TypeDef *pType = pNode->pTypeDef; // Not yet marked, so mark it, and add it to heap roots. pNode->marked = 1; // Don't look at the contents of strings, arrays of primitive Type.types, or WeakReferences if (pType->stackType == EvalStack.EVALSTACK_O || pType->stackType == EvalStack.EVALSTACK_VALUETYPE || pType->stackType == EvalStack.EVALSTACK_PTR) { if (pType != Type.types[Type.TYPE_SYSTEM_STRING] && (!MetaData.TYPE_ISARRAY(pType) || pType->pArrayElementType->stackType == EvalStack.EVALSTACK_O || pType->pArrayElementType->stackType == EvalStack.EVALSTACK_VALUETYPE || pType->pArrayElementType->stackType == EvalStack.EVALSTACK_PTR)) { if (pType != Type.types[Type.TYPE_SYSTEM_WEAKREFERENCE]) { Heap.SetRoots(&heapRoots, ((byte *)&pNode->pSync + sizeof(PTR)), GetSize(pNode)); moreRootsAdded = 1; } } } } break; } } } if (moreRootsAdded == 0) { heapRoots.num--; } } Mem.free(heapRoots.pHeapEntries); // Sweep phase // Traverse nodes pUp[0] = pHeapTreeRoot; top = 1; while (top != 0) { // Get this node pNode = pUp[--top]; // Act on this node if (pNode->marked != 0) { if (pNode->marked != 0xff) { // Still in use (but not marked undeletable), so unmark pNode->marked = 0; } } else { // Not in use any more, so put in deletion queue if it does not need Finalizing // If it does need Finalizing, then don't garbage collect, and put in Finalization queue. if (pNode->needToFinalize != 0) { if (pNode->needToFinalize == 1) { Finalizer.AddFinalizer((/*HEAP_PTR*/ byte *)pNode + sizeof(tHeapEntry)); // Mark it has having been placed in the finalization queue. // When it has been finalized, then this will be set to 0 pNode->needToFinalize = 2; // If this object is being targetted by weak-ref(s), handle it if (pNode->pSync != null) { RemoveWeakRefTarget(pNode, 0); Mem.free(pNode->pSync); } } } else { // If this object is being targetted by weak-ref(s), handle it if (pNode->pSync != null) { RemoveWeakRefTarget(pNode, 1); Mem.free(pNode->pSync); } // Use pSync to point to next entry in this linked-list. pNode->pSync = (tSync *)pToDelete; pToDelete = pNode; } } // Get next node(s) if (pNode->pLink[1] != (PTR)nil) { pUp[top++] = (tHeapEntry *)pNode->pLink[1]; } if (pNode->pLink[0] != (PTR)nil) { pUp[top++] = (tHeapEntry *)pNode->pLink[0]; } } // Delete all unused memory nodes. while (pToDelete != null) { tHeapEntry *pThis = pToDelete; pToDelete = (tHeapEntry *)(pToDelete->pSync); pHeapTreeRoot = TreeRemove(pHeapTreeRoot, pThis); if (pThis->monoHandle == 1) { void *hptr = *(void **)((byte *)pThis + sizeof(tHeapEntry)); if (hptr != null) { H.Free(hptr); } } numNodes--; trackHeapSize -= GetSize(pThis) + (uint)sizeof(tHeapEntry); Mem.free(pThis); } Mem.heapcheck(); #if DIAG_GC gcTotalTime += microTime() - startTime; #endif Sys.log_f(1, "--- GARBAGE --- [Size: %d -> %d] [Nodes: %d -> %d]\n", orgHeapSize, trackHeapSize, orgNumNodes, numNodes); #if DIAG_GC Sys.log_f(1, "GC time = %d ms\n", gcTotalTime / 1000); #endif #endif }
public static tMD_MethodDef *GetMethodDefFromCoreMethod(tMD_MethodDef *pCoreMethod, tMD_TypeDef *pParentType, uint numTypeArgs, tMD_TypeDef **ppTypeArgs, HashSet <PTR> resolveTypes = null) { tGenericMethodInstance *pInst; tMD_MethodDef * pMethod; Mem.heapcheck(); // See if we already have an instance with the given type args pInst = pCoreMethod->pGenericMethodInstances; while (pInst != null) { if (pInst->numTypeArgs == numTypeArgs && Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0) { return(pInst->pInstanceMethodDef); } pInst = pInst->pNext; } // We don't have an instance so create one now. pInst = (tGenericMethodInstance *)Mem.mallocForever((SIZE_T)(sizeof(tGenericMethodInstance))); pInst->pNext = pCoreMethod->pGenericMethodInstances; pCoreMethod->pGenericMethodInstances = pInst; pInst->numTypeArgs = numTypeArgs; pInst->ppTypeArgs = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))); Mem.memcpy(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))); pInst->pInstanceMethodDef = pMethod = ((tMD_MethodDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_MethodDef))); Mem.memset(pMethod, 0, (SIZE_T)sizeof(tMD_MethodDef)); pMethod->pMethodDef = pMethod; pMethod->pMetaData = pCoreMethod->pMetaData; pMethod->pCIL = pCoreMethod->pCIL; pMethod->implFlags = pCoreMethod->implFlags; pMethod->flags = pCoreMethod->flags; pMethod->name = pCoreMethod->name; pMethod->signature = pCoreMethod->signature; pMethod->vTableOfs = pCoreMethod->vTableOfs; pMethod->ppMethodTypeArgs = pInst->ppTypeArgs; if (pCoreMethod->monoMethodInfo != null) { System.Reflection.MethodInfo methodInfo = H.ToObj(pCoreMethod->monoMethodInfo) as System.Reflection.MethodInfo; System.Type[] typeArgs = new System.Type[(int)numTypeArgs]; for (uint i = 0; i < numTypeArgs; i++) { typeArgs[i] = MonoType.GetMonoTypeForType(ppTypeArgs[i]); if (typeArgs[i] == null) { Sys.Crash("Unable to find mono type for type arg %s.%s in for generic method %s", (PTR)ppTypeArgs[i]->nameSpace, (PTR)ppTypeArgs[i]->name, (PTR)pCoreMethod->name); } } System.Reflection.MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(typeArgs); MonoType.Fill_MethodDef(pParentType, genericMethodInfo, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs); } else { MetaData.Fill_MethodDef(pParentType, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs); } Mem.heapcheck(); return(pMethod); }