예제 #1
0
        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);
        }
예제 #2
0
파일: MetaData.cs 프로젝트: bmjoy/dnaunity
        public static tMetaData *New()
        {
            tMetaData *pRet = ((tMetaData *)Mem.malloc((SIZE_T)sizeof(tMetaData)));

            Mem.memset(pRet, 0, (SIZE_T)sizeof(tMetaData));
            return(pRet);
        }
예제 #3
0
        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);
        }
예제 #4
0
파일: RVA.cs 프로젝트: pandyer/dnaunity
        public static tRVA *New()
        {
            tRVA *pRet;

            pRet = ((tRVA *)Mem.malloc((SIZE_T)sizeof(tRVA)));
            return(pRet);
        }
예제 #5
0
파일: RVA.cs 프로젝트: pandyer/dnaunity
        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);
        }
예제 #6
0
파일: MetaData.cs 프로젝트: bmjoy/dnaunity
        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;
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
 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);
 }
예제 #10
0
//        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
 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;
     }
 }
예제 #17
0
        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);
        }
예제 #18
0
        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;
        }
예제 #19
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;
     }
 }
예제 #20
0
        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);
        }
예제 #21
0
파일: Sys.cs 프로젝트: bmjoy/dnaunity
 public static void Init()
 {
     methodNameBuf = (byte *)Mem.malloc((SIZE_T)METHOD_NAME_BUF_SIZE);
 }
예제 #22
0
        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
        }
예제 #23
0
        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);
            }
        }
예제 #24
0
        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);
        }
예제 #25
0
        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);
        }
예제 #26
0
        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);
        }
예제 #27
0
        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;
        }
예제 #28
0
파일: MetaData.cs 프로젝트: bmjoy/dnaunity
        // 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);
        }
예제 #29
0
 public static void Init()
 {
     toFinalizeCapacity = 4;
     ppToFinalize       = (/*HEAP_PTR*/ byte **)Mem.malloc((SIZE_T)(toFinalizeCapacity * sizeof(void *)));
     toFinalizeOfs      = 0;
 }
예제 #30
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);
        }