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 tMetaData *New() { tMetaData *pRet = ((tMetaData *)Mem.malloc((SIZE_T)sizeof(tMetaData))); Mem.memset(pRet, 0, (SIZE_T)sizeof(tMetaData)); return(pRet); }
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 tRVA *New() { tRVA *pRet; pRet = ((tRVA *)Mem.malloc((SIZE_T)sizeof(tRVA))); return(pRet); }
public static tRVA_Item *Create(tRVA *pThis, void *pFile, void *pSectionHeader) { tRVA_Item *pRet; uint rawOfs; uint rawSize; pRet = ((tRVA_Item *)Mem.malloc((SIZE_T)sizeof(tRVA_Item))); pRet->baseAddress = *(uint *)&((byte *)pSectionHeader)[12]; pRet->size = *(uint *)&((byte *)pSectionHeader)[8]; pRet->pData = Mem.malloc(pRet->size); Mem.memset(pRet->pData, 0, pRet->size); pRet->pNext = pThis->pFirstRVA; pThis->pFirstRVA = pRet; rawOfs = *(uint *)&((byte *)pSectionHeader)[20]; rawSize = *(uint *)&((byte *)pSectionHeader)[16]; if (rawOfs > 0) { if (rawSize > pRet->size) { rawSize = pRet->size; } Mem.memcpy(pRet->pData, ((byte *)pFile) + rawOfs, rawSize); } return(pRet); }
public static void WrapMonoAssembly(tMetaData *pMetaData, System.Reflection.Assembly assembly) { System.Type[] types = assembly.GetTypes(); pMetaData->tables.numRows[MetaDataTable.MD_TABLE_TYPEDEF] = (uint)types.Length; tMD_TypeDef *pTypeDefs = (tMD_TypeDef *)Mem.malloc((SIZE_T)(sizeof(tMD_TypeDef) * types.Length)); Mem.memset(pTypeDefs, 0, (SIZE_T)(sizeof(tMD_TypeDef) * types.Length)); for (int i = 0; i < types.Length; i++) { tMD_TypeDef *pTypeDef = &pTypeDefs[i]; System.Type monoType = types[i]; pTypeDef->pMetaData = pMetaData; pTypeDef->name = new S(monoType.Name); pTypeDef->nameSpace = new S(monoType.Namespace); pTypeDef->monoType = new H(monoType); pTypeDef->flags = (monoType.IsInterface ? TYPEATTRIBUTES_INTERFACE : 0); pTypeDef->isValueType = (byte)(monoType.IsValueType ? 1 : 0); pTypeDef->isGenericDefinition = (byte)(types[i].IsGenericTypeDefinition ? 1 : 0); MonoType.monoTypes[monoType] = (PTR)pTypeDef; } pMetaData->tables.data[MetaDataTable.MD_TABLE_TYPEDEF] = (PTR)pTypeDefs; }
public static tAsyncCall *Sleep(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue) { tAsyncCall *pAsync = ((tAsyncCall *)Mem.malloc((SIZE_T)sizeof(tAsyncCall))); pAsync->sleepTime = ((int *)pParams)[0]; return(pAsync); }
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); }
static tSync *EnsureSync(tHeapEntry *pHeapEntry) { if (pHeapEntry->pSync == null) { tSync *pSync = ((tSync *)Mem.malloc((SIZE_T)sizeof(tSync))); Mem.memset(pSync, 0, (SIZE_T)sizeof(tSync)); pHeapEntry->pSync = pSync; } return(pHeapEntry->pSync); }
// static uint nextKeybC = 0xFFFFFFFF; public static tAsyncCall *Internal_ReadKey(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue) { tAsyncCall *pAsync = (tAsyncCall *)Mem.malloc((SIZE_T)sizeof(tAsyncCall)); pAsync->sleepTime = -1; pAsync->checkFn = new H(Internal_ReadKey_Check); pAsync->state = null; return(pAsync); }
public static byte *PTypes(byte a, byte b = 255, byte c = 255, byte d = 255, byte e = 255, byte f = 255) { int count; if (b == 255) { count = 1; } else if (c == 255) { count = 2; } else if (d == 255) { count = 3; } else if (e == 255) { count = 4; } else if (f == 255) { count = 5; } else { count = 6; } byte *types = (byte *)Mem.malloc((SIZE_T)(sizeof(byte *) * count)); types[0] = a; if (count > 1) { types[1] = b; } if (count > 2) { types[2] = c; } if (count > 3) { types[3] = d; } if (count > 4) { types[4] = e; } if (count > 5) { types[5] = f; } return(types); }
public static byte **buildArray(params string[] args) { byte **arry = null; if (args != null && args.Length > 0) { arry = (byte **)Mem.malloc((SIZE_T)(sizeof(byte *) * args.Length)); for (int i = 0; i < args.Length; i++) { arry[i] = new S(args[i]); } } return(arry); }
public static tCLIFile *WrapMonoAssembly(/*char**/ byte *pAssemblyName) { tCLIFile * pRet; tFilesLoaded *pNewFile; tMetaData * pMetaData; System.Reflection.Assembly assembly = null; string assemblyName = Marshal.PtrToStringAnsi((System.IntPtr)pAssemblyName); System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { System.Reflection.Assembly assem = assemblies[i]; if (assem.GetName().Name == assemblyName) { assembly = assem; break; } } if (assembly == null) { Sys.Crash("Unable to load assembly file %s", (PTR)pAssemblyName); } pRet = ((tCLIFile *)Mem.malloc((SIZE_T)sizeof(tCLIFile))); Mem.memset(pRet, 0, (SIZE_T)sizeof(tCLIFile)); pRet->pMetaData = pMetaData = MetaData.New(); MetaData.WrapMonoAssembly(pMetaData, assembly); string codeBase = assembly.CodeBase; System.UriBuilder uri = new System.UriBuilder(codeBase); string path = System.Uri.UnescapeDataString(uri.Path); string assmName = System.IO.Path.GetFileNameWithoutExtension(path); pRet->assemblyName = new S(assmName); // Record that we've loaded this file pNewFile = ((tFilesLoaded *)Mem.mallocForever((SIZE_T)sizeof(tFilesLoaded))); pNewFile->pCLIFile = pRet; pNewFile->pNext = pFilesLoaded; pFilesLoaded = pNewFile; return(pRet); }
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 tAsyncCall *Internal_TryEnter(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue) { uint ok = Internal_TryEntry_Check(pCallNative, pThis_, pParams, pReturnValue, null); tAsyncCall *pAsync; if (ok != 0) { // Got lock already, so don't block thread return(null); } pAsync = ((tAsyncCall *)Mem.malloc((SIZE_T)(sizeof(tAsyncCall)))); pAsync->sleepTime = -1; pAsync->checkFn = new H(Internal_TryEntry_Check); pAsync->state = null; return(pAsync); }
public S(string s) { if (s != null) { byte *p = _s = (byte *)Mem.malloc((SIZE_T)s.Length + 1); for (int i = 0; i < s.Length; i++) { *p = (byte)s[i]; p++; } *p = 0; } else { _s = null; } }
public static /*HEAP_PTR*/ byte *Alloc(tMD_TypeDef *pTypeDef, uint size) { tHeapEntry *pHeapEntry; uint totalSize; byte * pMem; if (pTypeDef == null) { Sys.Crash("Invalid heap type!"); } totalSize = (uint)sizeof(tHeapEntry) + size; // Trigger garbage collection if required. if (trackHeapSize >= heapSizeMax) { GarbageCollect(); heapSizeMax = (trackHeapSize + totalSize) << 1; if (heapSizeMax < trackHeapSize + totalSize + MIN_HEAP_SIZE) { // Make sure there is always MIN_HEAP_SIZE available to allocate on the heap heapSizeMax = trackHeapSize + totalSize + MIN_HEAP_SIZE; } if (heapSizeMax > trackHeapSize + totalSize + MAX_HEAP_EXCESS) { // Make sure there is never more that MAX_HEAP_EXCESS space on the heap heapSizeMax = trackHeapSize + totalSize + MAX_HEAP_EXCESS; } } pHeapEntry = (tHeapEntry *)Mem.malloc(totalSize); pHeapEntry->pTypeDef = pTypeDef; pHeapEntry->signature = VALID_HEAP_OBJ_SIG; pHeapEntry->pSync = null; pHeapEntry->needToFinalize = (byte)((pTypeDef->pFinalizer != null) ? 1 : 0); pMem = (byte *)pHeapEntry + sizeof(tHeapEntry); Mem.memset(pMem, 0, size); trackHeapSize += totalSize; pHeapTreeRoot = TreeInsert(pHeapTreeRoot, pHeapEntry); numNodes++; return(pMem); }
static void Reset(tThread *pThis) { pThis->pCurrentMethodState = null; pThis->threadExitValue = 0; pThis->nextFinallyUnwindStack = 0; pThis->pAsync = null; pThis->hasParam = 0; pThis->startDelegate = null; pThis->param = null; pThis->state = THREADSTATE_UNSTARTED; // Allocate the first chunk of thread-local stack if (pThis->pThreadStack == null) { pThis->pThreadStack = ((tThreadStack *)Mem.malloc((SIZE_T)sizeof(tThreadStack))); pThis->pThreadStack->pNext = null; } pThis->pThreadStack->ofs = 0; }
public S(ref byte *sc, string s) { if (s != null) { if (sc != null) { _s = sc; } else { byte *p = sc = _s = (byte *)Mem.malloc((SIZE_T)s.Length + 1); for (int i = 0; i < s.Length; i++) { *p++ = (byte)s[i]; } *p = 0; } } else { _s = null; } }
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); }
public static void Init() { methodNameBuf = (byte *)Mem.malloc((SIZE_T)METHOD_NAME_BUF_SIZE); }
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 void Fill_MethodDef(tMD_TypeDef *pParentType, MethodBase methodBase, tMD_MethodDef *pMethodDef, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { uint i, totalSize, start; if (pMethodDef->isFilled == 1) { return; } pMethodDef->pParentType = pParentType; pMethodDef->pMethodDef = pMethodDef; pMethodDef->isFilled = 1; pMethodDef->isGenericDefinition = (byte)(methodBase.IsGenericMethodDefinition ? 1 : 0); if (methodBase.IsGenericMethodDefinition) { // Generic definition method, so can't do any more. //Sys.log_f("Method<>: %s.%s.%s()\n", pParentType->nameSpace, pParentType->name, pMethodDef->name); return; } ParameterInfo[] paramInfos = methodBase.GetParameters(); pMethodDef->numberOfParameters = (ushort)(paramInfos.Length + (methodBase.IsStatic ? 0 : 1)); if (methodBase is MethodInfo) { pMethodDef->pReturnType = GetTypeForMonoType(((MethodInfo)methodBase).ReturnType, ppClassTypeArgs, ppMethodTypeArgs); } else { pMethodDef->pReturnType = null; } if (pMethodDef->pReturnType == Type.types[Type.TYPE_SYSTEM_VOID]) { pMethodDef->pReturnType = null; } if (pMethodDef->pReturnType != null && pMethodDef->pReturnType->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pMethodDef->pReturnType, null, null); } pMethodDef->pParams = (tParameter *)Mem.malloc((SIZE_T)(pMethodDef->numberOfParameters * sizeof(tParameter))); totalSize = 0; start = 0; if (!methodBase.IsStatic) { // Fill in parameter info for the 'this' pointer pMethodDef->pParams->offset = 0; if (pParentType->isValueType != 0) { // If this is a value-type then the 'this' pointer is actually an IntPtr to the value-type's location pMethodDef->pParams->size = sizeof(PTR); pMethodDef->pParams->pStackTypeDef = Type.types[Type.TYPE_SYSTEM_INTPTR]; } else { pMethodDef->pParams->size = sizeof(PTR); pMethodDef->pParams->pStackTypeDef = pParentType; } totalSize = sizeof(PTR); start = 1; } for (i = start; i < pMethodDef->numberOfParameters; i++) { tMD_TypeDef *pStackTypeDef; tMD_TypeDef *pByRefTypeDef; uint size; // NOTE: Byref values are treated as intptr's in DNA System.Type paramType = paramInfos[i - start].ParameterType; if (paramType.IsByRef) { pStackTypeDef = Type.types[Type.TYPE_SYSTEM_INTPTR]; pByRefTypeDef = GetTypeForMonoType(paramType.GetElementType(), ppClassTypeArgs, ppMethodTypeArgs); } else { pStackTypeDef = GetTypeForMonoType(paramType, ppClassTypeArgs, ppMethodTypeArgs); pByRefTypeDef = null; } if (pStackTypeDef != null) { if (pStackTypeDef->fillState < Type.TYPE_FILL_LAYOUT) { MetaData.Fill_TypeDef(pStackTypeDef, null, null, Type.TYPE_FILL_LAYOUT); } else if (pStackTypeDef->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pStackTypeDef, null, null); } size = pStackTypeDef->stackSize; } else { size = 0; } if (pByRefTypeDef != null) { if (pByRefTypeDef->fillState < Type.TYPE_FILL_LAYOUT) { MetaData.Fill_TypeDef(pByRefTypeDef, null, null, Type.TYPE_FILL_LAYOUT); } else if (pByRefTypeDef->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pByRefTypeDef, null, null); } } pMethodDef->pParams[i].pStackTypeDef = pStackTypeDef; pMethodDef->pParams[i].pByRefTypeDef = pByRefTypeDef; pMethodDef->pParams[i].offset = totalSize; pMethodDef->pParams[i].size = size; totalSize += size; } pMethodDef->parameterStackSize = totalSize; if (pMethodDef->monoMethodInfo == null) { pMethodDef->monoMethodInfo = new H(methodBase); } if (pMethodDef->monoMethodCall == null) { pMethodDef->monoMethodCall = new H(CallMethodTrampoline); } }
public static tMetaData *GetMetaDataForAssembly(byte *pAssemblyName) { tFilesLoaded *pFiles; int monoAssembly = 0; tCLIFile * pCLIFile = null; tMD_Assembly *pThisAssembly = null; tMetaData ** ppChildMetaData = null; int i, j, childCount; // Check corlib assemblies i = 0; while (dnaCorlibAssemblies[i] != null) { if (S.strcmp(pAssemblyName, dnaCorlibAssemblies[i]) == 0) { pAssemblyName = scCorLib; break; } i++; } // Look in already-loaded files first pFiles = pFilesLoaded; while (pFiles != null) { pCLIFile = pFiles->pCLIFile; if (S.strcmp(pAssemblyName, pCLIFile->assemblyName) == 0) { // Found the correct assembly, so return its meta-data return(pCLIFile->pMetaData); } pFiles = pFiles->pNext; } // Mono/Unity assemblies only load metadata, no code if (monoAssemblies != null) { i = 0; while (monoAssemblies[i] != null) { if (S.strcmp(pAssemblyName, monoAssemblies[i]) == 0) { if (i == 0) { // Handle "UnityEngine" assemblies j = 0; childCount = 0; while (unityModuleAssemblies[j] != null) { childCount++; j++; } ppChildMetaData = (tMetaData **)Mem.malloc((SIZE_T)((childCount + 1) * sizeof(tMetaData *))); Mem.memset(ppChildMetaData, 0, (SIZE_T)((childCount + 1) * sizeof(tMetaData *))); j = 0; while (unityModuleAssemblies[j] != null) { ppChildMetaData[j] = GetMetaDataForAssembly(unityModuleAssemblies[j]); j++; } } monoAssembly = 1; break; } i++; } } // Assembly not loaded, so load it if possible if (monoAssembly != 0) { pCLIFile = CLIFile.WrapMonoAssembly(pAssemblyName); if (pCLIFile == null) { Sys.Crash("Cannot load required mono assembly file: %s.dll", (PTR)pAssemblyName); } } else { byte *fileName = stackalloc byte[256]; S.snprintf(fileName, 256, "%s.dll", (PTR)pAssemblyName); pCLIFile = CLIFile.LoadAssembly(fileName); if (pCLIFile == null) { Sys.Crash("Cannot load required assembly file: %s.dll", (PTR)pAssemblyName); } } pCLIFile->pMetaData->ppChildMetaData = ppChildMetaData; return(pCLIFile->pMetaData); }
private static tCLIFile *LoadPEFile(byte[] image) { tCLIFile *pRet = ((tCLIFile *)Mem.malloc((SIZE_T)sizeof(tCLIFile))); System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(image, GCHandleType.Pinned); byte *pData = (byte *)handle.AddrOfPinnedObject(); byte *pMSDOSHeader = (byte *)&(((byte *)pData)[0]); byte *pPEHeader; byte *pPEOptionalHeader; byte *pPESectionHeaders; byte *pCLIHeader; byte *pRawMetaData; int i; uint lfanew; ushort machine; int numSections; //uint imageBase; //int fileAlignment; uint cliHeaderRVA; //uint cliHeaderSize; uint metaDataRVA; //uint metaDataSize; tMetaData *pMetaData; pRet->pRVA = RVA.New(); pRet->gcHandle = (PTR)(System.IntPtr)handle; pRet->pMetaData = pMetaData = MetaData.New(); lfanew = *(uint *)&(pMSDOSHeader[0x3c]); pPEHeader = pMSDOSHeader + lfanew + 4; pPEOptionalHeader = pPEHeader + 20; pPESectionHeaders = pPEOptionalHeader + 224; machine = *(ushort *)&(pPEHeader[0]); if (machine != DOT_NET_MACHINE) { return(null); } numSections = *(ushort *)&(pPEHeader[2]); //imageBase = *(uint*)&(pPEOptionalHeader[28]); //fileAlignment = *(int*)&(pPEOptionalHeader[36]); for (i = 0; i < numSections; i++) { byte *pSection = pPESectionHeaders + i * 40; RVA.Create(pRet->pRVA, pData, pSection); } cliHeaderRVA = *(uint *)&(pPEOptionalHeader[208]); //cliHeaderSize = *(uint*)&(pPEOptionalHeader[212]); pCLIHeader = (byte *)RVA.FindData(pRet->pRVA, cliHeaderRVA); metaDataRVA = *(uint *)&(pCLIHeader[8]); //metaDataSize = *(uint*)&(pCLIHeader[12]); pRet->entryPoint = *(uint *)&(pCLIHeader[20]); pRawMetaData = (byte *)RVA.FindData(pRet->pRVA, metaDataRVA); // Load all metadata { uint versionLen = *(uint *)&(pRawMetaData[12]); uint ofs, numberOfStreams; void *pTableStream = null; uint tableStreamSize = 0; pRet->pVersion = &(pRawMetaData[16]); Sys.log_f(1, "CLI version: %s\n", (PTR)pRet->pVersion); ofs = 16 + versionLen; numberOfStreams = *(ushort *)&(pRawMetaData[ofs + 2]); ofs += 4; for (i = 0; i < (int)numberOfStreams; i++) { uint streamOffset = *(uint *)&pRawMetaData[ofs]; uint streamSize = *(uint *)&pRawMetaData[ofs + 4]; byte *pStreamName = &pRawMetaData[ofs + 8]; void *pStream = pRawMetaData + streamOffset; ofs += (uint)((S.strlen(pStreamName) + 4) & (~0x3)) + 8; if (S.strcasecmp(pStreamName, "#Strings") == 0) { MetaData.LoadStrings(pMetaData, pStream, streamSize); } else if (S.strcasecmp(pStreamName, "#US") == 0) { MetaData.LoadUserStrings(pMetaData, pStream, streamSize); } else if (S.strcasecmp(pStreamName, "#Blob") == 0) { MetaData.LoadBlobs(pMetaData, pStream, streamSize); } else if (S.strcasecmp(pStreamName, "#GUID") == 0) { MetaData.LoadGUIDs(pMetaData, pStream, streamSize); } else if (S.strcasecmp(pStreamName, "#~") == 0) { pTableStream = pStream; tableStreamSize = streamSize; } } // Must load tables last if (pTableStream != null) { MetaData.LoadTables(pMetaData, pRet->pRVA, pTableStream, (uint)tableStreamSize); } } // Mark all generic definition type and methods as such for (i = (int)pMetaData->tables.numRows[MetaDataTable.MD_TABLE_GENERICPARAM]; i > 0; i--) { tMD_GenericParam * pGenericParam; /*IDX_TABLE*/ uint ownerIdx; pGenericParam = (tMD_GenericParam *)MetaData.GetTableRow (pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_GENERICPARAM, (uint)i)); ownerIdx = pGenericParam->owner; switch (MetaData.TABLE_ID(ownerIdx)) { case MetaDataTable.MD_TABLE_TYPEDEF: { tMD_TypeDef *pTypeDef = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, ownerIdx); pTypeDef->isGenericDefinition = 1; } break; case MetaDataTable.MD_TABLE_METHODDEF: { tMD_MethodDef *pMethodDef = (tMD_MethodDef *)MetaData.GetTableRow(pMetaData, ownerIdx); pMethodDef->isGenericDefinition = 1; } break; default: Sys.Crash("Wrong generic parameter owner: 0x%08x", ownerIdx); break; } } // Mark all nested classes as such for (i = (int)pMetaData->tables.numRows[MetaDataTable.MD_TABLE_NESTEDCLASS]; i > 0; i--) { tMD_NestedClass *pNested; tMD_TypeDef * pParent; tMD_TypeDef * pChild; pNested = (tMD_NestedClass *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_NESTEDCLASS, (uint)i)); pParent = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, pNested->enclosingClass); pChild = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, pNested->nestedClass); pChild->pNestedIn = pParent; } return(pRet); }
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 Fill_MethodDef(tMD_TypeDef *pParentType, tMD_MethodDef *pMethodDef, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { /*SIG*/ byte *sig; uint i, entry, totalSize, start; if (pMethodDef->isFilled == 1) { return; } // Note: parent type can be null for module level methods (not typical in C# assemblies) pMethodDef->pParentType = pParentType; pMethodDef->pMethodDef = pMethodDef; pMethodDef->isFilled = 1; if (pMethodDef->isGenericDefinition != 0) { // Generic definition method, so can't do any more. //Sys.log_f("Method<>: %s.%s.%s()\n", pParentType->nameSpace, pParentType->name, pMethodDef->name); return; } sig = MetaData.GetBlob(pMethodDef->signature, null); entry = MetaData.DecodeSigEntry(&sig); if ((entry & SIG_METHODDEF_GENERIC) != 0) { // Has generic parameters. Read how many, but don't care about the answer MetaData.DecodeSigEntry(&sig); } pMethodDef->numberOfParameters = (ushort)(MetaData.DecodeSigEntry(&sig) + (MetaData.METHOD_ISSTATIC(pMethodDef)?0:1)); pMethodDef->pReturnType = Type.GetTypeFromSig(pMethodDef->pMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs, null); if (pMethodDef->pReturnType != null && pMethodDef->pReturnType->fillState < Type.TYPE_FILL_ALL) { Fill_Defer(pMethodDef->pReturnType, ppClassTypeArgs, ppMethodTypeArgs); } pMethodDef->pParams = (tParameter *)Mem.malloc((SIZE_T)(pMethodDef->numberOfParameters * sizeof(tParameter))); totalSize = 0; start = 0; if (!MetaData.METHOD_ISSTATIC(pMethodDef)) { // Fill in parameter info for the 'this' pointer pMethodDef->pParams->offset = 0; if (pParentType->isValueType != 0) { // If this is a value-type then the 'this' pointer is actually an IntPtr to the value-type's location pMethodDef->pParams->size = sizeof(PTR); pMethodDef->pParams->pStackTypeDef = Type.types[Type.TYPE_SYSTEM_INTPTR]; } else { pMethodDef->pParams->size = sizeof(PTR); pMethodDef->pParams->pStackTypeDef = pParentType; } totalSize = sizeof(PTR); start = 1; } for (i = start; i < pMethodDef->numberOfParameters; i++) { tMD_TypeDef *pStackTypeDef; tMD_TypeDef *pByRefTypeDef; uint size; pByRefTypeDef = null; pStackTypeDef = Type.GetTypeFromSig(pMethodDef->pMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs, &pByRefTypeDef); if (pStackTypeDef != null) { if (pStackTypeDef->fillState < Type.TYPE_FILL_LAYOUT) { MetaData.Fill_TypeDef(pStackTypeDef, null, null, Type.TYPE_FILL_LAYOUT); } else if (pStackTypeDef->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pStackTypeDef, null, null); } size = pStackTypeDef->stackSize; } else { size = 0; } if (pByRefTypeDef != null) { if (pByRefTypeDef->fillState < Type.TYPE_FILL_LAYOUT) { MetaData.Fill_TypeDef(pByRefTypeDef, null, null, Type.TYPE_FILL_LAYOUT); } else if (pByRefTypeDef->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pByRefTypeDef, null, null); } } pMethodDef->pParams[i].pStackTypeDef = pStackTypeDef; pMethodDef->pParams[i].pByRefTypeDef = pByRefTypeDef; pMethodDef->pParams[i].offset = totalSize; pMethodDef->pParams[i].size = size; totalSize += size; } pMethodDef->parameterStackSize = totalSize; }
// Loads a single table, returns pointer to table in memory. public static void *LoadSingleTable(tMetaData *pThis, tRVA *pRVA, int tableID, void **ppTable) { int numRows = (int)pThis->tables.numRows[tableID]; int rowLen = tableRowSize[tableID]; int i, row; /*char**/ byte *pDef = tableDefs[tableID]; int defLen = (int)S.strlen(pDef); void * pRet; byte * pSource = (byte *)*ppTable; byte * pDest; uint v = 0; SIZE_T p = 0; // Allocate memory for destination table pRet = Mem.malloc((SIZE_T)(numRows * rowLen)); pDest = (byte *)pRet; // Load table int srcLen = 0; for (row = 0; row < numRows; row++) { byte *pSrcStart = pSource; for (i = 0; i < defLen; i += 2) { byte d = pDef[i]; if (d < MAX_TABLES) { if (pThis->tables.numRows[d] < 0x10000) { // Use 16-bit offset v = GetU16(pSource); pSource += 2; } else { // Use 32-bit offset v = GetU32(pSource); pSource += 4; } v |= (uint)d << 24; } else { switch ((char)d) { case 'c': // 8-bit value v = *(byte *)pSource; pSource++; break; case 's': // 16-bit short v = GetU16(pSource); pSource += 2; break; case 'i': // 32-bit int v = GetU32(pSource); pSource += 4; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ':': case ';': case '<': { int ofs = pDef[i] - '0'; /*char*/ byte *pCoding = codedTags[ofs]; int tagBits = codedTagBits[ofs]; byte tag = (byte)(*pSource & ((1 << tagBits) - 1)); int idxIntoTableID = pCoding[tag]; // The actual table index that we're looking for if (idxIntoTableID < 0 || idxIntoTableID > MAX_TABLES) { Sys.Crash("Error: Bad table index: 0x%02x\n", idxIntoTableID); } if (pThis->tables.codedIndex32Bit[ofs] != 0) { // Use 32-bit number v = GetU32(pSource) >> tagBits; pSource += 4; } else { // Use 16-bit number v = GetU16(pSource) >> tagBits; pSource += 2; } v |= (uint)idxIntoTableID << 24; } break; case 'S': // index into string heap if (pThis->index32BitString != 0) { v = GetU32(pSource); pSource += 4; } else { v = GetU16(pSource); pSource += 2; } p = (PTR)(pThis->strings.pStart + v); // NOTE: Quick way to validate metadata loading, check if all strings are valid! if (S.isvalidstr((byte *)p) == 0) { Sys.Crash("Invalid string %s", (PTR)p); } break; case 'G': // index into GUID heap if (pThis->index32BitGUID != 0) { v = GetU32(pSource); pSource += 4; } else { v = GetU16(pSource); pSource += 2; } p = (PTR)(pThis->GUIDs.pGUID1 + ((v - 1) * 16)); break; case 'B': // index into BLOB heap if (pThis->index32BitBlob != 0) { v = GetU32(pSource); pSource += 4; } else { v = GetU16(pSource); pSource += 2; } p = (PTR)(pThis->blobs.pStart + v); break; case '^': // RVA to convert to pointer v = GetU32(pSource); pSource += 4; p = (PTR)RVA.FindData(pRVA, v); break; case 'm': // Pointer to this metadata p = (PTR)pThis; break; case 'l': // Is this the last table entry? v = (row == numRows - 1) ? (uint)1 : (uint)0; break; case 'I': // Original table index v = MetaData.MAKE_TABLE_INDEX((uint)tableID, (uint)(row + 1)); break; case 'x': // Nothing, use 0 v = 0; p = 0; break; default: Sys.Crash("Cannot handle MetaData source definition character '%c' (0x%02X)\n", d, d); break; } } switch ((char)pDef[i + 1]) { case '*': *(SIZE_T *)pDest = p; pDest += sizeof(SIZE_T); break; case 'i': *(uint *)pDest = v; pDest += 4; break; case 's': *(ushort *)pDest = (ushort)v; pDest += 2; break; case 'c': *(byte *)pDest = (byte)v; pDest++; break; case 'x': // Do nothing break; default: Sys.Crash("Cannot handle MetaData destination definition character '%c'\n", pDef[i + 1]); break; } } if (srcLen == 0) { srcLen = (int)(pSource - pSrcStart); } } Sys.log_f(1, "Loaded MetaData table 0x%02X; %d rows %d len\n", tableID, numRows, srcLen); // Update the parameter to the position after this table *ppTable = pSource; // Return new table information return(pRet); }
public static void Init() { toFinalizeCapacity = 4; ppToFinalize = (/*HEAP_PTR*/ byte **)Mem.malloc((SIZE_T)(toFinalizeCapacity * sizeof(void *))); toFinalizeOfs = 0; }
static tMD_MethodDef *FindMethodInType(tMD_TypeDef *pTypeDef, /*STRING*/ byte *name, tMetaData *pSigMetaData, /*BLOB_*/ byte *sigBlob, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { uint i; tMD_TypeDef *pLookInType = pTypeDef; if (pLookInType->fillState < Type.TYPE_FILL_MEMBERS) { MetaData.Fill_TypeDef(pTypeDef, ppClassTypeArgs, ppMethodTypeArgs, Type.TYPE_FILL_MEMBERS); } do { for (i = 0; i < pLookInType->numMethods; i++) { if (MetaData.CompareNameAndSig(name, sigBlob, pSigMetaData, ppClassTypeArgs, ppMethodTypeArgs, pLookInType->ppMethods[i], pLookInType->ppClassTypeArgs, null) != 0) { return(pLookInType->ppMethods[i]); } } pLookInType = pLookInType->pParent; } while (pLookInType != null); { // Error reporting!! uint entry, numParams, j; /*SIG*/ byte * sig; /*char**/ byte *pMsg, pMsgPos, pMsgEnd; tMD_TypeDef * pParamTypeDef; pMsgPos = pMsg = (byte *)Mem.malloc(MSG_BUF_SIZE); pMsgEnd = pMsg + MSG_BUF_SIZE; *pMsg = 0; sig = MetaData.GetBlob(sigBlob, &j); entry = MetaData.DecodeSigEntry(&sig); if ((entry & SIG_METHODDEF_HASTHIS) == 0) { pMsgPos = S.scatprintf(pMsgPos, pMsgEnd, "static "); } if ((entry & SIG_METHODDEF_GENERIC) != 0) { // read number of generic type args - don't care what it is MetaData.DecodeSigEntry(&sig); } numParams = MetaData.DecodeSigEntry(&sig); pParamTypeDef = Type.GetTypeFromSig(pSigMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs, null); // return type if (pParamTypeDef != null) { pMsgPos = S.scatprintf(pMsgPos, pMsgEnd, "%s ", (PTR)pParamTypeDef->name); } pMsgPos = S.scatprintf(pMsgPos, pMsgEnd, "%s.%s.%s(", (PTR)pTypeDef->nameSpace, (PTR)pTypeDef->name, (PTR)name); for (j = 0; j < numParams; j++) { pParamTypeDef = Type.GetTypeFromSig(pSigMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs, null); if (j > 0) { pMsgPos = S.scatprintf(pMsgPos, pMsgEnd, ","); } if (pParamTypeDef != null) { pMsgPos = S.scatprintf(pMsgPos, pMsgEnd, "%s", (PTR)pParamTypeDef->name); } else { pMsgPos = S.scatprintf(pMsgPos, pMsgEnd, "???"); } } Sys.Crash("FindMethodInType(): Cannot find method %s)", (PTR)pMsg); } return(null); }