public static void GetConstant(tMetaData *pThis, /*IDX_TABLE*/ uint idx, byte *pResultMem) { tMD_Constant *pConst = null; switch (MetaData.TABLE_ID(idx)) { case MetaDataTable.MD_TABLE_FIELDDEF: { tMD_FieldDef *pField = (tMD_FieldDef *)MetaData.GetTableRow(pThis, idx); pConst = (tMD_Constant *)pField->pMemory; } break; default: Sys.Crash("MetaData.GetConstant() Cannot handle idx: 0x%08x", idx); break; } switch (pConst->type) { case Type.ELEMENT_TYPE_I4: //*(uint*)pReturnMem = MetaData.DecodeSigEntry( Mem.memcpy(pResultMem, pConst->value + 1, 4); return; default: Sys.Crash("MetaData.GetConstant() Cannot handle value type: 0x%02x", pConst->type); break; } }
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 void GetHeapRoots(tHeapRoots *pHeapRoots, tMetaData *pMetaData) { uint i, top; // Go through all Type.types, getting their static variables. top = pMetaData->tables.numRows[MetaDataTable.MD_TABLE_TYPEDEF]; for (i = 1; i <= top; i++) { tMD_TypeDef *pTypeDef; pTypeDef = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_TYPEDEF, i)); if (pTypeDef->isGenericDefinition != 0) { Generics.GetHeapRoots(pHeapRoots, pTypeDef); } else { if (pTypeDef->staticFieldSize > 0) { Heap.SetRoots(pHeapRoots, pTypeDef->pStaticFields, pTypeDef->staticFieldSize); } } } }
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 tMetaData *GetResolutionScopeMetaData(tMetaData *pMetaData, /*IDX_TABLE*/ uint resolutionScopeToken, tMD_TypeDef **ppInNestedType) { switch (MetaData.TABLE_ID(resolutionScopeToken)) { case MetaDataTable.MD_TABLE_ASSEMBLYREF: { tMD_AssemblyRef *pAssemblyRef; pAssemblyRef = (tMD_AssemblyRef *)MetaData.GetTableRow(pMetaData, resolutionScopeToken); *ppInNestedType = null; return(CLIFile.GetMetaDataForAssembly(pAssemblyRef->name)); } case MetaDataTable.MD_TABLE_TYPEREF: { tMD_TypeDef *pTypeDef; pTypeDef = MetaData.GetTypeDefFromDefRefOrSpec(pMetaData, resolutionScopeToken, null, null); *ppInNestedType = pTypeDef; return(pTypeDef->pMetaData); } default: Sys.Crash("MetaData.GetResolutionScopeMetaData(): Cannot resolve token: 0x%08x", resolutionScopeToken); return(null); } }
public static tAsyncCall *GetTypeFromName(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue) { byte * namespaceName = stackalloc byte[256]; byte * className = stackalloc byte[256]; tMD_TypeDef *pTypeDef; DotNetStringToCString(namespaceName, 256, ((tSystemString **)pParams)[1]); DotNetStringToCString(className, 256, ((tSystemString **)pParams)[2]); if (((/*HEAP_PTR*/ byte **)pParams)[0] == null) { // assemblyName is null, so search all loaded assemblies pTypeDef = CLIFile.FindTypeInAllLoadedAssemblies(namespaceName, className); } else { // assemblyName is specified byte *assemblyName = stackalloc byte[256]; DotNetStringToCString(assemblyName, 256, ((tSystemString **)pParams)[0]); tMetaData *pAssemblyMetadata = CLIFile.GetMetaDataForAssembly(assemblyName); pTypeDef = MetaData.GetTypeDefFromName(pAssemblyMetadata, namespaceName, className, null, /* assertExists */ 1); } MetaData.Fill_TypeDef(pTypeDef, null, null); *(/*HEAP_PTR*/ byte **)pReturnValue = Type.GetTypeObject(pTypeDef); return(null); }
public static tMethodState *New(tThread *pThread, tMetaData *pMetaData, /*IDX_TABLE*/ uint methodToken, tMethodState *pCaller) { tMD_MethodDef *pMethod; pMethod = MetaData.GetMethodDefFromDefRefOrSpec(pMetaData, methodToken, null, null); return(Direct(pThread, pMethod, pCaller, 0)); }
public static void SetEntryPoint(tThread *pThis, tMetaData *pMetaData, /*IDX_TABLE*/ uint entryPointToken, byte *_params, uint paramBytes) { // Set up the initial MethodState pThis->pCurrentMethodState = MethodState.New(pThis, pMetaData, entryPointToken, null); // Insert initial parameters (if any) if (paramBytes > 0) { Mem.memcpy(pThis->pCurrentMethodState->pParamsLocals, _params, paramBytes); } }
public static void LoadGUIDs(tMetaData *pThis, void *pStream, uint streamLen) { pThis->GUIDs.numGUIDs = streamLen / 16; // This is stored -16 because numbering starts from 1. This means that a simple indexing calculation // can be used, as if it started from 0 pThis->GUIDs.pGUID1 = (byte *)pStream; Sys.log_f(1, "Read %d GUIDs\n", pThis->GUIDs.numGUIDs); }
// Returns length in bytes, not characters public static /*STRING2*/ ushort *GetUserString(tMetaData *pThis, /*IDX_USERSTRINGS*/ uint index, uint *pStringLength) { byte *pString = pThis->userStrings.pStart + (index & 0x00ffffff); uint len = MetaData.DecodeHeapEntryLength(&pString); if (pStringLength != null) { // -1 because of extra terminating character in the heap *pStringLength = len - 1; } return((/*STRING2*/ ushort *)pString); }
public static /*HEAP_PTR*/ byte *FromUserStrings(tMetaData *pMetaData, /*IDX_USERSTRINGS*/ uint index) { uint stringLen; /*STRING2*/ ushort *str; tSystemString * pSystemString; string s; str = MetaData.GetUserString(pMetaData, index, &stringLen); s = System.Runtime.InteropServices.Marshal.PtrToStringUni((System.IntPtr)str, (int)(stringLen >> 1)); pSystemString = (tSystemString *)FromMonoString(s); return((/*HEAP_PTR*/ byte *)pSystemString); }
public static tMD_FieldDef *GetFieldDefFromDefOrRef(tMetaData *pMetaData, /*IDX_TABLE*/ uint token, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { void *pTableEntry; pTableEntry = MetaData.GetTableRow(pMetaData, token); if (((tMDC_ToFieldDef *)pTableEntry)->pFieldDef != null) { return(((tMDC_ToFieldDef *)pTableEntry)->pFieldDef); } switch (MetaData.TABLE_ID(token)) { case MetaDataTable.MD_TABLE_FIELDDEF: ((tMDC_ToFieldDef *)pTableEntry)->pFieldDef = (tMD_FieldDef *)pTableEntry; return((tMD_FieldDef *)pTableEntry); case MetaDataTable.MD_TABLE_MEMBERREF: { tMD_MemberRef *pMemberRef; pMemberRef = (tMD_MemberRef *)pTableEntry; switch (MetaData.TABLE_ID(pMemberRef->class_)) { case MetaDataTable.MD_TABLE_TYPEREF: case MetaDataTable.MD_TABLE_TYPESPEC: { tMD_TypeDef * pTypeDef; tMD_FieldDef *pFieldDef; pTypeDef = MetaData.GetTypeDefFromDefRefOrSpec(pMetaData, pMemberRef->class_, ppClassTypeArgs, ppMethodTypeArgs); pFieldDef = FindFieldInType(pTypeDef, pMemberRef->name); if (MetaData.TABLE_ID(pMemberRef->class_) == MetaDataTable.MD_TABLE_TYPEREF) { // Can't do this for TypeSpec because the resulting TypeDef will change // depending on what the class type arguments are. ((tMDC_ToFieldDef *)pTableEntry)->pFieldDef = pFieldDef; } return(pFieldDef); } default: Sys.Crash("MetaData.GetMethodDefFromMethodDefOrRef(): Cannot handle pMemberRef->class_=0x%08x", pMemberRef->class_); break; } return(null); } } Sys.Crash("MetaData.GetFieldDefFromDefOrRef(): Cannot handle token: 0x%08x", token); return(null); }
public static void *GetTableRow(tMetaData *pThis, /*IDX_TABLE*/ uint index) { /*char**/ byte *pData; uint tableId; if (MetaData.TABLE_OFS(index) == 0) { return(null); } tableId = MetaData.TABLE_ID(index); pData = (byte *)pThis->tables.data[tableId]; // Table indexes start at one, hence the -1 here. return(pData + (MetaData.TABLE_OFS(index) - 1) * tableRowSize[tableId]); }
public static /*HEAP_PTR*/ byte *FromUserStrings(tMetaData *pMetaData, /*IDX_USERSTRINGS*/ uint index) { uint stringLen; /*STRING2*/ ushort *str; tSystemString * pSystemString; char *pSystemStringChars; str = MetaData.GetUserString(pMetaData, index, &stringLen); // Note: stringLen is in bytes pSystemString = (tSystemString *)CreateStringHeapObj(stringLen >> 1); pSystemStringChars = tSystemString.GetChars(pSystemString); Mem.memcpy(pSystemStringChars, str, (SIZE_T)stringLen); return((/*HEAP_PTR*/ byte *)pSystemString); }
public static tMD_ImplMap *GetImplMap(tMetaData *pMetaData, /*IDX_TABLE*/ uint memberForwardedToken) { uint i; for (i = pMetaData->tables.numRows[MetaDataTable.MD_TABLE_IMPLMAP]; i >= 1; i--) { tMD_ImplMap *pImplMap = (tMD_ImplMap *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_IMPLMAP, i)); if (pImplMap->memberForwarded == memberForwardedToken) { return(pImplMap); } } Sys.Crash("MetaData.GetImplMap() Cannot find mapping for token: 0x%08x", memberForwardedToken); return(null); }
public static tMD_TypeDef *GetTypeDefFromName(tMetaData *pMetaData, /*STRING*/ byte *nameSpace, /*STRING*/ byte *name, tMD_TypeDef *pInNestedClass, byte assertExists) { uint i, numRows; tMD_TypeDef *pTypeDef = null; numRows = pMetaData->tables.numRows[MetaDataTable.MD_TABLE_TYPEDEF]; for (i = 1; i <= numRows; i++) { pTypeDef = (tMD_TypeDef *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_TYPEDEF, i)); if (pInNestedClass == pTypeDef->pNestedIn && S.strcmp(name, pTypeDef->name) == 0 && (pInNestedClass != null || S.strcmp(nameSpace, pTypeDef->nameSpace) == 0)) { return(pTypeDef); } } if (pMetaData->ppChildMetaData != null) { i = 0; while (pMetaData->ppChildMetaData[i] != null) { pTypeDef = GetTypeDefFromName(pMetaData->ppChildMetaData[i], nameSpace, name, pInNestedClass, assertExists); if (pTypeDef != null) { return(pTypeDef); } i++; } } if (assertExists != 0) { Sys.Crash("MetaData.GetTypeDefFromName(): Cannot find type %s.%s", (PTR)nameSpace, (PTR)name); return(null); } else { return(null); } }
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); }
public static uint CompareNameAndSig(/*STRING*/ byte *name, /*BLOB_*/ byte *sigBlob, tMetaData *pSigMetaData, tMD_TypeDef **ppSigClassTypeArgs, tMD_TypeDef **ppSigMethodTypeArgs, tMD_MethodDef *pMethod, tMD_TypeDef **ppMethodClassTypeArgs, tMD_TypeDef **ppMethodMethodTypeArgs) { if (S.strcmp(name, pMethod->name) == 0) { if (pMethod->signature != null) { /*SIG*/ byte *sig, thisSig; uint e, thisE, paramCount, i; sig = MetaData.GetBlob(sigBlob, null); thisSig = MetaData.GetBlob(pMethod->signature, null); e = MetaData.DecodeSigEntry(&sig); thisE = MetaData.DecodeSigEntry(&thisSig); // Check method call type (static, etc...) if (e != thisE) { return(0); } // If method has generic arguments, check the generic type argument count if ((e & SIG_METHODDEF_GENERIC) != 0) { e = MetaData.DecodeSigEntry(&sig); thisE = MetaData.DecodeSigEntry(&thisSig); // Generic argument count if (e != thisE) { return(0); } } e = MetaData.DecodeSigEntry(&sig); thisE = MetaData.DecodeSigEntry(&thisSig); // check parameter count if (e != thisE) { return(0); } paramCount = e + 1; // +1 to include the return type // check all parameters for (i = 0; i < paramCount; i++) { tMD_TypeDef *pParamType; tMD_TypeDef *pThisParamType; pParamType = Type.GetTypeFromSig(pSigMetaData, &sig, ppSigClassTypeArgs, ppSigMethodTypeArgs, null); pThisParamType = Type.GetTypeFromSig(pMethod->pMetaData, &thisSig, ppMethodClassTypeArgs, ppMethodMethodTypeArgs, null); if (pParamType != pThisParamType) { return(0); } } // All parameters the same, so found the right method return(1); } else if (pMethod->monoMethodInfo != null) { /*SIG*/ byte * sig; uint e, paramCount, i; MethodBase methodBase = H.ToObj(pMethod->monoMethodInfo) as MethodBase; sig = MetaData.GetBlob(sigBlob, null); e = MetaData.DecodeSigEntry(&sig); // Check method call type (static, etc...) if (methodBase.IsStatic && (e & (SIG_METHODDEF_HASTHIS | SIG_METHODDEF_EXPLICITTHIS)) != 0) { return(0); } // If method has generic arguments, check the generic type argument count if ((e & SIG_METHODDEF_GENERIC) != 0) { if (!methodBase.IsGenericMethod) { return(0); } e = MetaData.DecodeSigEntry(&sig); // Generic argument count if (e != methodBase.GetGenericArguments().Length) { return(0); } } paramCount = MetaData.DecodeSigEntry(&sig); System.Reflection.ParameterInfo[] paramInfos = methodBase.GetParameters(); if (paramCount != paramInfos.Length) { return(0); } tMD_TypeDef *pReturnType = Type.GetTypeFromSig(pSigMetaData, &sig, ppSigClassTypeArgs, ppSigMethodTypeArgs, null); if (methodBase is MethodInfo) { tMD_TypeDef *pThisReturnType = MonoType.GetTypeForMonoType(((MethodInfo)methodBase).ReturnType, ppMethodClassTypeArgs, ppMethodMethodTypeArgs); if (pReturnType == null) { if (pThisReturnType != Type.types[Type.TYPE_SYSTEM_VOID]) { return(0); } } else if (pReturnType != pThisReturnType) { return(0); } } // check all parameters for (i = 0; i < paramCount; i++) { tMD_TypeDef *pParamType; tMD_TypeDef *pThisParamType; pParamType = Type.GetTypeFromSig(pSigMetaData, &sig, ppSigClassTypeArgs, ppSigMethodTypeArgs, null); pThisParamType = MonoType.GetTypeForMonoType(paramInfos[i].ParameterType, ppMethodClassTypeArgs, ppMethodMethodTypeArgs); if (pParamType != pThisParamType) { return(0); } } // All parameters the same, so found the right method return(1); } else { Sys.Crash("Method with no sig or methodInfo"); } } return(0); }
public static void LoadTables(tMetaData *pThis, tRVA *pRVA, void *pStream, uint streamLen) { ulong valid, j; byte c; int i, k, numTables; void *pTable; c = *(byte *)&((byte *)pStream)[6]; pThis->index32BitString = (c & 1) > 0 ? (byte)1 : (byte)0; pThis->index32BitGUID = (c & 2) > 0 ? (byte)1 : (byte)0; pThis->index32BitBlob = (c & 4) > 0 ? (byte)1 : (byte)0; valid = *(ulong *)&((byte *)pStream)[8]; // Count how many tables there are, and read in all the number of rows of each table. numTables = 0; for (i = 0, j = 1; i < MAX_TABLES; i++, j <<= 1) { if ((valid & j) != 0) { pThis->tables.numRows[i] = *(uint *)&((byte *)pStream)[24 + numTables * 4]; numTables++; } else { pThis->tables.numRows[i] = 0; pThis->tables.data[i] = /*null*/ 0; } } // Determine if each coded index lookup type needs to use 16 or 32 bit indexes for (i = 0; i < 13; i++) { /*char*/ byte *pCoding = codedTags[i]; int tagBits = codedTagBits[i]; // Discover max table size uint maxTableLen = 0; for (k = 0; k < (1 << tagBits); k++) { byte t = pCoding[k]; if (t != 'z') { if (pThis->tables.numRows[t] > maxTableLen) { maxTableLen = pThis->tables.numRows[t]; } } } if (maxTableLen < (uint)(1 << (16 - tagBits))) { // Use 16-bit number pThis->tables.codedIndex32Bit[i] = 0; } else { // Use 32-bit number pThis->tables.codedIndex32Bit[i] = 1; } } pTable = &((byte *)pStream)[24 + numTables * 4]; for (i = 0; i < MAX_TABLES; i++) { if (pThis->tables.numRows[i] > 0) { if (i >= TABLEDEFS_LENGTH || tableDefs[i] == null) { Sys.Crash("No table definition for MetaData table 0x%02x\n", i); } pThis->tables.data[i] = (PTR)LoadSingleTable(pThis, pRVA, i, &pTable); } } }
// 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 LoadUserStrings(tMetaData *pThis, void *pStream, uint streamLen) { pThis->userStrings.pStart = (byte *)pStream; Sys.log_f(1, "Loaded User Strings\n"); }
public static void Fill_TypeDef(tMD_TypeDef *pTypeDef, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs, uint resolve = Type.TYPE_FILL_ALL) { /*IDX_TABLE*/ uint firstIdx, lastIdx, token; uint instanceMemSize, staticMemSize, virtualOfs, isDeferred, i, j; tMetaData * pMetaData = pTypeDef->pMetaData; tMD_TypeDef *pParent; if (pTypeDef->fillState >= resolve) { return; } if (pTypeDef->monoType != null) { MonoType.Fill_TypeDef(pTypeDef, ppClassTypeArgs, ppMethodTypeArgs, resolve); return; } // Sys.printf("FILLING TYPE: %s\n", (PTR)pTypeDef->name); // string name = System.Runtime.InteropServices.Marshal.PtrToStringAnsi((System.IntPtr)pTypeDef->name); if (typesToFill == null) { Fill_StartDefer(); isDeferred = 1; } else { isDeferred = 0; } if (resolve < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pTypeDef, ppClassTypeArgs, ppMethodTypeArgs); } MetaData.Fill_GetDeferredTypeArgs(pTypeDef, ref ppClassTypeArgs, ref ppMethodTypeArgs); // Fill parent info if (pTypeDef->fillState < Type.TYPE_FILL_PARENTS) { pTypeDef->fillState = Type.TYPE_FILL_PARENTS; pTypeDef->pTypeDef = pTypeDef; if (pTypeDef->alignment == 0) { pTypeDef->alignment = 1; } if (pTypeDef->pParent == null) { pTypeDef->pParent = MetaData.GetTypeDefFromDefRefOrSpec(pMetaData, pTypeDef->extends, ppClassTypeArgs, ppMethodTypeArgs); } pParent = pTypeDef->pParent; if (pParent != null) { if (pParent->fillState < Type.TYPE_FILL_PARENTS) { MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_PARENTS); } else if (pParent->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pParent, null, null); } pTypeDef->hasMonoBase = pParent->hasMonoBase; if (pParent->hasMonoBase == 0) { // If we have a mono base type, we have at least 1 non-blittable field pTypeDef->blittable = pParent->blittable; pTypeDef->fixedBlittable = pParent->fixedBlittable; } else { pTypeDef->blittable = pTypeDef->fixedBlittable = 0; } } else { pTypeDef->blittable = pTypeDef->fixedBlittable = 1; } // If this type is an interface, then return 0 if (pTypeDef->stackSize != 0) { pTypeDef->isValueType = (byte)(pTypeDef->stackType != EvalStack.EVALSTACK_O ? 1 : 0); } else if (MetaData.TYPE_ISINTERFACE(pTypeDef)) { pTypeDef->isValueType = 0; } else if (pTypeDef->nameSpace[0] == 'S' && S.strcmp(pTypeDef->nameSpace, new S(ref scSystem, "System")) == 0) { if ((pTypeDef->name[0] == 'V' && S.strcmp(pTypeDef->name, new S(ref scValueType, "ValueType")) == 0) || (pTypeDef->name[0] == 'E' && S.strcmp(pTypeDef->name, new S(ref scEnum, "Enum")) == 0)) { pTypeDef->isValueType = 1; } else if (pTypeDef->name[0] == 'O' && S.strcmp(pTypeDef->name, new S(ref scObject, "Object")) == 0) { pTypeDef->isValueType = 0; } else if (pParent != null) { pTypeDef->isValueType = pParent->isValueType; } } else if (pParent != null) { pTypeDef->isValueType = pParent->isValueType; } // If not primed, then work out how many methods & fields there are. if (pTypeDef->isPrimed == 0) { // Methods lastIdx = (pTypeDef->isLast != 0) ? MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_METHODDEF, pTypeDef->pMetaData->tables.numRows[MetaDataTable.MD_TABLE_METHODDEF]) : (pTypeDef[1].methodList - 1); pTypeDef->numMethods = lastIdx - pTypeDef->methodList + 1; // Fields lastIdx = (pTypeDef->isLast != 0) ? MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_FIELDDEF, pTypeDef->pMetaData->tables.numRows[MetaDataTable.MD_TABLE_FIELDDEF]) : (pTypeDef[1].fieldList - 1); pTypeDef->numFields = lastIdx - pTypeDef->fieldList + 1; } // If this is a nested type, then find the namespace of it if (pTypeDef->pNestedIn != null) { tMD_TypeDef *pRootTypeDef = pTypeDef->pNestedIn; while (pRootTypeDef->pNestedIn != null) { pRootTypeDef = pRootTypeDef->pNestedIn; } pTypeDef->nameSpace = pRootTypeDef->nameSpace; } // If this is an enum type, then pretend its stack type is its underlying type if (pTypeDef->pParent == Type.types[Type.TYPE_SYSTEM_ENUM]) { pTypeDef->stackType = EvalStack.EVALSTACK_INT32; pTypeDef->stackSize = sizeof(PTR); pTypeDef->instanceMemSize = 4; pTypeDef->arrayElementSize = 4; pTypeDef->blittable = pTypeDef->fixedBlittable = 1; } if (pTypeDef->fillState >= resolve) { return; } } else { pParent = pTypeDef->pParent; } if (pTypeDef->fillState < Type.TYPE_FILL_LAYOUT) { pTypeDef->fillState = Type.TYPE_FILL_LAYOUT; if (pParent != null) { if (pParent->fillState < Type.TYPE_FILL_LAYOUT) { MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_LAYOUT); } else if (pParent->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pParent, null, null); } } if (pTypeDef->isGenericDefinition == 0) { // Resolve fields, members, interfaces. // Only needs to be done if it's not a generic definition type // It it's not a value-type and the stack-size is not preset, then set it up now. // It needs to be done here as non-static fields in non-value type can point to the containing type if (pTypeDef->stackSize == 0 && pTypeDef->isValueType == 0) { pTypeDef->stackType = EvalStack.EVALSTACK_O; pTypeDef->stackSize = sizeof(PTR); pTypeDef->alignment = sizeof(PTR); } // Resolve all fields - instance ONLY at this point, // because static fields in value-Type.types can be of the containing type, and the size is not yet known. firstIdx = pTypeDef->fieldList; lastIdx = firstIdx + pTypeDef->numFields - 1; staticMemSize = 0; if (pTypeDef->numFields > 0) { pTypeDef->ppFields = (tMD_FieldDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numFields * sizeof(tMD_FieldDef *))); } instanceMemSize = (pParent == null ? 0 : pTypeDef->pParent->instanceMemSize); if (pTypeDef->hasMonoBase != 0 && pParent->hasMonoBase == 0) { // Some DNA types like String are actually wrappers around mono objects. In those cases, we need to allocate the // space in the instance memory for the GCHandle to the mono object. We distinguish this case from the case // where we're just extending a Mono Type object by checking if the parent also has the hasMonoBase flag set. instanceMemSize += (uint)sizeof(void *); } for (token = firstIdx, i = 0; token <= lastIdx; token++, i++) { tMD_FieldDef *pFieldDef; pFieldDef = MetaData.GetFieldDefFromDefOrRef(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs); if (!MetaData.FIELD_ISSTATIC(pFieldDef)) { // Only handle non-static fields at the moment if (pTypeDef->pGenericDefinition != null) { // If this is a generic instantiation type, then all field defs need to be copied, // as there will be lots of different instantiations. tMD_FieldDef *pFieldCopy = ((tMD_FieldDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_FieldDef))); Mem.memcpy(pFieldCopy, pFieldDef, (SIZE_T)sizeof(tMD_FieldDef)); pFieldDef = pFieldCopy; } if (MetaData.FIELD_ISLITERAL(pFieldDef) || MetaData.FIELD_HASFIELDRVA(pFieldDef)) { // If it's a literal, then analyse the field, but don't include it in any memory allocation // If is has an RVA, then analyse the field, but don't include it in any memory allocation MetaData.Fill_FieldDef(pTypeDef, pFieldDef, 0, null, ppClassTypeArgs); } else { MetaData.Fill_FieldDef(pTypeDef, pFieldDef, instanceMemSize, &(pTypeDef->alignment), ppClassTypeArgs); instanceMemSize = pFieldDef->memOffset + pFieldDef->memSize; } // Update blittable and fixedBlittable status for type - if any non-blittable fields are included set to 0 if (pTypeDef->blittable != 0 || pTypeDef->fixedBlittable != 0) { if (pFieldDef->pType->isValueType == 0 || pFieldDef->pType->blittable == 0) { pTypeDef->blittable = pTypeDef->fixedBlittable = 0; } else if (pFieldDef->pType->typeInitId == Type.TYPE_SYSTEM_INTPTR || pFieldDef->pType->typeInitId == Type.TYPE_SYSTEM_UINTPTR) { pTypeDef->fixedBlittable = 0; } } pTypeDef->ppFields[i] = pFieldDef; } } if (pTypeDef->instanceMemSize == 0) { pTypeDef->instanceMemSize = (instanceMemSize + (pTypeDef->alignment - 1)) & ~(pTypeDef->alignment - 1); } // Sort out stack type and size. // Note that this may already be set, as some basic type have this preset; // or if it's not a value-type it'll already be set if (pTypeDef->stackSize == 0) { // if it gets here then it must be a value type pTypeDef->stackType = EvalStack.EVALSTACK_VALUETYPE; pTypeDef->stackSize = pTypeDef->instanceMemSize; } // Sort out array element size. Note that some basic type will have this preset. if (pTypeDef->arrayElementSize == 0) { pTypeDef->arrayElementSize = pTypeDef->stackSize; } // Make sure stack size is even multiple of stack alignment pTypeDef->stackSize = (pTypeDef->stackSize + (STACK_ALIGNMENT - 1)) & ~(STACK_ALIGNMENT - 1); // Handle static fields for (token = firstIdx, i = 0; token <= lastIdx; token++, i++) { tMD_FieldDef *pFieldDef; pFieldDef = MetaData.GetFieldDefFromDefOrRef(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs); if (MetaData.FIELD_ISSTATIC(pFieldDef)) { // Only handle static fields here if (pTypeDef->pGenericDefinition != null) { // If this is a generic instantiation type, then all field defs need to be copied, // as there will be lots of different instantiations. tMD_FieldDef *pFieldCopy = ((tMD_FieldDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_FieldDef))); Mem.memcpy(pFieldCopy, pFieldDef, (SIZE_T)sizeof(tMD_FieldDef)); pFieldDef = pFieldCopy; } if (MetaData.FIELD_ISLITERAL(pFieldDef) || MetaData.FIELD_HASFIELDRVA(pFieldDef)) { // If it's a literal, then analyse the field, but don't include it in any memory allocation // If is has an RVA, then analyse the field, but don't include it in any memory allocation MetaData.Fill_FieldDef(pTypeDef, pFieldDef, 0, null, ppClassTypeArgs); } else { MetaData.Fill_FieldDef(pTypeDef, pFieldDef, staticMemSize, null, ppClassTypeArgs); staticMemSize += pFieldDef->memSize; } pTypeDef->ppFields[i] = pFieldDef; } } if (staticMemSize > 0) { pTypeDef->pStaticFields = (byte *)Mem.mallocForever((SIZE_T)staticMemSize); Mem.memset(pTypeDef->pStaticFields, 0, staticMemSize); // Set the field addresses (->pMemory) of all static fields for (i = 0; i < pTypeDef->numFields; i++) { tMD_FieldDef *pFieldDef; pFieldDef = pTypeDef->ppFields[i]; if (MetaData.FIELD_ISSTATIC(pFieldDef) && pFieldDef->pMemory == null) { // Only set it if it isn't already set. It will be already set if this field has an RVA pFieldDef->pMemory = pTypeDef->pStaticFields + pFieldDef->memOffset; } } pTypeDef->staticFieldSize = staticMemSize; } } if (pTypeDef->fillState >= resolve) { return; } } // This only needs to be done for non-generic Type.types, or for generic type that are not a definition // I.e. Fully instantiated generic Type.types if (pTypeDef->fillState < Type.TYPE_FILL_VTABLE) { pTypeDef->fillState = Type.TYPE_FILL_VTABLE; if (pParent != null) { if (pParent->fillState < Type.TYPE_FILL_VTABLE) { MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_VTABLE); } else if (pParent->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pParent, null, null); } } if (pTypeDef->isGenericDefinition == 0) { virtualOfs = (pParent != null) ? pParent->numVirtualMethods : 0; // Must create the virtual method table BEFORE any other type resolution is done // Note that this must not do ANY filling of type or methods. // This is to ensure that the parent object(s) in any type inheritance hierachy are allocated // their virtual method offset before derived Type.types. firstIdx = pTypeDef->methodList; lastIdx = firstIdx + pTypeDef->numMethods - 1; for (token = firstIdx; token <= lastIdx; token++) { tMD_MethodDef *pMethodDef; pMethodDef = MetaData.GetMethodDefFromDefRefOrSpec(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs); //Sys.printf("Method: %s\n", (PTR)pMethodDef->name); // This is needed, so array resolution can work correctly and FindVirtualOverriddenMethod() can work. pMethodDef->pParentType = pTypeDef; if (MetaData.METHOD_ISVIRTUAL(pMethodDef)) { if (MetaData.METHOD_ISNEWSLOT(pMethodDef) || pTypeDef->pParent == null) { // Allocate a new vTable slot if method is explicitly marked as NewSlot, or // this is of type Object. pMethodDef->vTableOfs = virtualOfs++; } else { tMD_MethodDef *pVirtualOveriddenMethod; pVirtualOveriddenMethod = FindVirtualOverriddenMethod(pTypeDef->pParent, pMethodDef); if (pVirtualOveriddenMethod == null) { Sys.Crash("Unable to find virtual override method for %s %s", (PTR)pTypeDef->name, (PTR)pMethodDef->name); } pMethodDef->vTableOfs = pVirtualOveriddenMethod->vTableOfs; } } else { // Dummy value - make it obvious it's not valid! pMethodDef->vTableOfs = 0xffffffff; } } // Create the virtual method table pTypeDef->numVirtualMethods = virtualOfs; // Resolve all members firstIdx = pTypeDef->methodList; lastIdx = firstIdx + pTypeDef->numMethods - 1; pTypeDef->ppMethods = (tMD_MethodDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numMethods * sizeof(tMD_MethodDef *))); pTypeDef->pVTable = (tMD_MethodDef **)Mem.mallocForever((SIZE_T)(pTypeDef->numVirtualMethods * sizeof(tMD_MethodDef *))); // Copy initial vTable from parent if (pTypeDef->pParent != null) { if (pTypeDef->pParent->fillState != Type.TYPE_FILL_MEMBERS) { Fill_TypeDef(pTypeDef->pParent, null, null, Type.TYPE_FILL_MEMBERS); } Mem.memcpy(pTypeDef->pVTable, pTypeDef->pParent->pVTable, (SIZE_T)(pTypeDef->pParent->numVirtualMethods * sizeof(tMD_MethodDef *))); } for (token = firstIdx, i = 0; token <= lastIdx; token++, i++) { tMD_MethodDef *pMethodDef; pMethodDef = MetaData.GetMethodDefFromDefRefOrSpec(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs); if (pTypeDef->pGenericDefinition != null) { // If this is a generic instantiation type, then all method defs need to be copied, // as there will be lots of different instantiations. tMD_MethodDef *pMethodCopy = ((tMD_MethodDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_MethodDef))); Mem.memcpy(pMethodCopy, pMethodDef, (SIZE_T)sizeof(tMD_MethodDef)); pMethodDef = pMethodCopy; } if (MetaData.METHOD_ISSTATIC(pMethodDef) && S.strcmp(pMethodDef->name, ".cctor") == 0) { // This is a static constructor pTypeDef->pStaticConstructor = pMethodDef; } if (!MetaData.METHOD_ISSTATIC(pMethodDef) && pTypeDef->pParent != null && S.strcmp(pMethodDef->name, "Finalize") == 0) { // This is a Finalizer method, but not for Object. // Delibrately miss out Object's Finalizer because it's empty and will cause every object // of any type to have a Finalizer which will be terrible for performance. pTypeDef->pFinalizer = pMethodDef; } if (MetaData.METHOD_ISVIRTUAL(pMethodDef)) { // This is a virtual method, so enter it in the vTable pTypeDef->pVTable[pMethodDef->vTableOfs] = pMethodDef; } pTypeDef->ppMethods[i] = pMethodDef; } // Find inherited Finalizer, if this type doesn't have an explicit Finalizer, and if there is one if (pTypeDef->pFinalizer == null) { tMD_TypeDef *pInheritedType = pTypeDef->pParent; while (pInheritedType != null) { if (pInheritedType->pFinalizer != null) { pTypeDef->pFinalizer = pInheritedType->pFinalizer; break; } pInheritedType = pInheritedType->pParent; } } } if (pTypeDef->fillState >= resolve) { return; } } if (pTypeDef->fillState < Type.TYPE_FILL_MEMBERS) { pTypeDef->fillState = Type.TYPE_FILL_MEMBERS; if (pParent != null) { if (pParent->fillState < Type.TYPE_FILL_MEMBERS) { MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_MEMBERS); } else if (pParent->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pParent, null, null); } } if (pTypeDef->isGenericDefinition == 0) { // Fill all method definitions for this type for (i = 0; i < pTypeDef->numMethods; i++) { MetaData.Fill_MethodDef(pTypeDef, pTypeDef->ppMethods[i], ppClassTypeArgs, ppMethodTypeArgs); } } if (pTypeDef->fillState >= resolve) { return; } } if (pTypeDef->fillState < Type.TYPE_FILL_INTERFACES) { pTypeDef->fillState = Type.TYPE_FILL_INTERFACES; if (pParent != null) { if (pParent->fillState < Type.TYPE_FILL_INTERFACES) { MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_INTERFACES); } else if (pParent->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pParent, null, null); } } if (pTypeDef->isGenericDefinition == 0 && !MetaData.TYPE_ISINTERFACE(pTypeDef)) { if (pParent != null && pParent->fillState < Type.TYPE_FILL_INTERFACES) { MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_INTERFACES); } // Map all interface method calls. This only needs to be done for Classes, not Interfaces // And is not done for generic definitions. firstIdx = 0; if (pTypeDef->pParent != null) { j = pTypeDef->numInterfaces = pTypeDef->pParent->numInterfaces; } else { j = 0; } lastIdx = firstIdx; for (i = 1; i <= pMetaData->tables.numRows[MetaDataTable.MD_TABLE_INTERFACEIMPL]; i++) { tMD_InterfaceImpl *pInterfaceImpl; pInterfaceImpl = (tMD_InterfaceImpl *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_INTERFACEIMPL, i)); if (pInterfaceImpl->class_ == pTypeDef->tableIndex) { // count how many interfaces are implemented pTypeDef->numInterfaces++; if (firstIdx == 0) { firstIdx = MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_INTERFACEIMPL, i); } lastIdx = MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_INTERFACEIMPL, i); } } if (pTypeDef->numInterfaces > 0) { uint mapNum; pTypeDef->pInterfaceMaps = (tInterfaceMap *)Mem.mallocForever((SIZE_T)(pTypeDef->numInterfaces * sizeof(tInterfaceMap))); // Copy interface maps from parent type if (j > 0) { Mem.memcpy(pTypeDef->pInterfaceMaps, pTypeDef->pParent->pInterfaceMaps, (SIZE_T)(j * sizeof(tInterfaceMap))); } mapNum = j; if (firstIdx > 0) { for (token = firstIdx; token <= lastIdx; token++, mapNum++) { tMD_InterfaceImpl *pInterfaceImpl; pInterfaceImpl = (tMD_InterfaceImpl *)MetaData.GetTableRow(pMetaData, token); if (pInterfaceImpl->class_ == pTypeDef->tableIndex) { tMD_TypeDef * pInterface; tInterfaceMap *pMap; // Get the interface that this type implements pInterface = MetaData.GetTypeDefFromDefRefOrSpec(pMetaData, pInterfaceImpl->interface_, ppClassTypeArgs, ppMethodTypeArgs); MetaData.Fill_TypeDef(pInterface, null, null, Type.TYPE_FILL_INTERFACES); pMap = &pTypeDef->pInterfaceMaps[mapNum]; pMap->pInterface = pInterface; pMap->pVTableLookup = (uint *)Mem.mallocForever((SIZE_T)(pInterface->numVirtualMethods * sizeof(uint))); pMap->ppMethodVLookup = (tMD_MethodDef **)Mem.mallocForever((SIZE_T)(pInterface->numVirtualMethods * sizeof(tMD_MethodDef *))); // Discover interface mapping for each interface method for (i = 0; i < pInterface->numVirtualMethods; i++) { tMD_MethodDef *pInterfaceMethod; tMD_MethodDef *pOverriddenMethod; pInterfaceMethod = pInterface->pVTable[i]; pOverriddenMethod = FindVirtualOverriddenMethod(pTypeDef, pInterfaceMethod); pMap->pVTableLookup[i] = pOverriddenMethod->vTableOfs; pMap->ppMethodVLookup[i] = pOverriddenMethod; } } else { Sys.Crash("Problem with interface class"); } } } } } if (pTypeDef->fillState >= resolve) { return; } } if (pTypeDef->fillState < Type.TYPE_FILL_ALL) { pTypeDef->fillState = Type.TYPE_FILL_ALL; if (pTypeDef->isGenericDefinition == 0 && pTypeDef->stackSize == 0) { j = 0; } if (pParent != null && pParent->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_TypeDef(pParent, null, null, Type.TYPE_FILL_ALL); } if (isDeferred != 0) { Fill_ResolveDeferred(); } } Sys.log_f(2, "Type: %s.%s\n", (PTR)pTypeDef->nameSpace, (PTR)pTypeDef->name); }
public static tMD_TypeDef *GetTypeDefFromDefRefOrSpec(tMetaData *pMetaData, /*IDX_TABLE*/ uint token, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { void *pTableEntry; pTableEntry = MetaData.GetTableRow(pMetaData, token); if (pTableEntry == null) { return(null); } if (((tMDC_ToTypeDef *)pTableEntry)->pTypeDef != null) { if (((tMDC_ToTypeDef *)pTableEntry)->pTypeDef->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(((tMDC_ToTypeDef *)pTableEntry)->pTypeDef, null, null); } return(((tMDC_ToTypeDef *)pTableEntry)->pTypeDef); } switch (MetaData.TABLE_ID(token)) { case MetaDataTable.MD_TABLE_TYPEDEF: ((tMDC_ToTypeDef *)pTableEntry)->pTypeDef = (tMD_TypeDef *)pTableEntry; return((tMD_TypeDef *)pTableEntry); case MetaDataTable.MD_TABLE_TYPEREF: { tMetaData * pTypeDefMetaData; tMD_TypeRef *pTypeRef; tMD_TypeDef *pTypeDef; tMD_TypeDef *pInNestedClass; pTypeRef = (tMD_TypeRef *)pTableEntry; pTypeDefMetaData = MetaData.GetResolutionScopeMetaData(pMetaData, pTypeRef->resolutionScope, &pInNestedClass); pTypeDef = MetaData.GetTypeDefFromName(pTypeDefMetaData, pTypeRef->nameSpace, pTypeRef->name, pInNestedClass, /* assertExists */ 1); if (pTypeDef->fillState < Type.TYPE_FILL_ALL) { MetaData.Fill_Defer(pTypeDef, null, null); } pTypeRef->pTypeDef = pTypeDef; return(pTypeDef); } case MetaDataTable.MD_TABLE_TYPESPEC: { tMD_TypeSpec *pTypeSpec; tMD_TypeDef * pTypeDef; /*SIG*/ byte *sig; pTypeSpec = (tMD_TypeSpec *)pTableEntry; sig = MetaData.GetBlob(pTypeSpec->signature, null); pTypeDef = Type.GetTypeFromSig(pTypeSpec->pMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs, null); // Note: Cannot cache the TypeDef for this TypeSpec because it // can change depending on class arguemnts given. return(pTypeDef); } default: Sys.Crash("MetaData.GetTypeDefFromDefRefOrSpec(): Cannot handle token: 0x%08x", token); return(null); } }
public static tMD_MethodDef *GetMethodDefFromDefRefOrSpec(tMetaData *pMetaData, /*IDX_TABLE*/ uint token, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { void *pTableEntry; pTableEntry = MetaData.GetTableRow(pMetaData, token); if (((tMDC_ToMethodDef *)pTableEntry)->pMethodDef != null) { return(((tMDC_ToMethodDef *)pTableEntry)->pMethodDef); } switch (MetaData.TABLE_ID(token)) { case MetaDataTable.MD_TABLE_METHODDEF: ((tMDC_ToMethodDef *)pTableEntry)->pMethodDef = (tMD_MethodDef *)pTableEntry; return((tMD_MethodDef *)pTableEntry); case MetaDataTable.MD_TABLE_MEMBERREF: { tMD_MemberRef *pMemberRef; pMemberRef = (tMD_MemberRef *)pTableEntry; switch (MetaData.TABLE_ID(pMemberRef->class_)) { case MetaDataTable.MD_TABLE_TYPEREF: case MetaDataTable.MD_TABLE_TYPESPEC: { tMD_TypeDef * pTypeDef; tMD_MethodDef *pMethodDef; pTypeDef = MetaData.GetTypeDefFromDefRefOrSpec(pMetaData, pMemberRef->class_, ppClassTypeArgs, ppMethodTypeArgs); MetaData.Fill_TypeDef(pTypeDef, null, null); pMethodDef = FindMethodInType(pTypeDef, pMemberRef->name, pMetaData, pMemberRef->signature, pTypeDef->ppClassTypeArgs, ppMethodTypeArgs); //pMethodDef->pMethodDef = pMethodDef; return(pMethodDef); } default: Sys.Crash("MetaData.GetMethodDefFromMethodDefOrRef(): Cannot handle pMemberRef->class_=0x%08x", pMemberRef->class_); return(null); } } case MetaDataTable.MD_TABLE_METHODSPEC: { tMD_MethodSpec *pMethodSpec; tMD_MethodDef * pMethodDef; pMethodSpec = (tMD_MethodSpec *)pTableEntry; pMethodDef = Generics.GetMethodDefFromSpec(pMethodSpec, ppClassTypeArgs, ppMethodTypeArgs); // Note: Cannot cache the MethodDef from the MethodSpec, as class generic arguments // may be different. return(pMethodDef); } } Sys.Crash("MetaData.GetMethodDefFromMethodDefOrRef(): Cannot handle token: 0x%08x", token); return(null); }
// Return pointer to the relevant Def structure. // pObjectType returns: // 0 - tMD_TypeDef // 1 - tMD_MethodDef // 2 - tMD_FieldDef // (These link up with the JitOps.JIT_LOADTOKEN_* opcodes) public static byte *GetTypeMethodField(tMetaData *pMetaData, /*IDX_TABLE*/ uint token, uint *pObjectType, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) { switch (MetaData.TABLE_ID(token)) { case MetaDataTable.MD_TABLE_TYPEDEF: case MetaDataTable.MD_TABLE_TYPEREF: case MetaDataTable.MD_TABLE_TYPESPEC: { tMD_TypeDef *pTypeDef; pTypeDef = MetaData.GetTypeDefFromDefRefOrSpec(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs); //MetaData.Fill_TypeDef(pTypeDef, null, null); *pObjectType = 0; return((byte *)pTypeDef); } case MetaDataTable.MD_TABLE_METHODDEF: method: { tMD_MethodDef *pMethodDef; pMethodDef = MetaData.GetMethodDefFromDefRefOrSpec(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs); if (pMethodDef->isFilled == 0) { tMD_TypeDef *pTypeDef; pTypeDef = MetaData.GetTypeDefFromMethodDef(pMethodDef); //MetaData.Fill_TypeDef(pTypeDef, null, null); } *pObjectType = 1; return((byte *)pMethodDef); } case MetaDataTable.MD_TABLE_FIELDDEF: field: { tMD_FieldDef *pFieldDef; pFieldDef = MetaData.GetFieldDefFromDefOrRef(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs); if (pFieldDef->pParentType == null) { tMD_TypeDef *pTypeDef; pTypeDef = MetaData.GetTypeDefFromFieldDef(pFieldDef); //MetaData.Fill_TypeDef(pTypeDef, null, null); } *pObjectType = 2; return((byte *)pFieldDef); } case MetaDataTable.MD_TABLE_MEMBERREF: { tMD_MemberRef *pMemberRef; /*SIG*/ byte * sig; pMemberRef = (tMD_MemberRef *)MetaData.GetTableRow(pMetaData, token); sig = MetaData.GetBlob(pMemberRef->signature, null); if (*(byte *)sig == 0x06) { // Field goto field; } else { // Method goto method; } } } Sys.Crash("MetaData.GetTypeMethodField(): Cannot handle token: 0x%08x", token); return(null); }
public static uint CompareNameAndMethodInfo(/*STRING*/ byte *name, System.Reflection.MethodBase methodBase, tMetaData *pSigMetaData, tMD_TypeDef **ppSigClassTypeArgs, tMD_TypeDef **ppSigMethodTypeArgs, tMD_MethodDef *pMethod, tMD_TypeDef **ppMethodClassTypeArgs, tMD_TypeDef **ppMethodMethodTypeArgs) { if (S.strcmp(name, pMethod->name) == 0) { uint i; if (METHOD_ISSTATIC(pMethod) != methodBase.IsStatic || METHOD_ISVIRTUAL(pMethod) != methodBase.IsVirtual) { return(0); } System.Reflection.ParameterInfo[] paramInfos = methodBase.GetParameters(); uint numberOfParameters = (uint)(paramInfos.Length + (methodBase.IsStatic ? 0 : 1)); if ((uint)pMethod->numberOfParameters != numberOfParameters) { return(0); } if (methodBase.IsGenericMethod != (pMethod->isGenericDefinition != 0)) { return(0); } if (methodBase is MethodInfo) { if (pMethod->pReturnType == null) { if (((MethodInfo)methodBase).ReturnType != typeof(void)) { return(0); } } else if (pMethod->pReturnType != MonoType.GetTypeForMonoType(((MethodInfo)methodBase).ReturnType, ppMethodClassTypeArgs, ppMethodMethodTypeArgs)) { return(0); } } uint start = 0; if (!methodBase.IsStatic) { // if (pMethod->pParams[0].pStackTypeDef != MonoType.GetTypeForMonoType(methodInfo.DeclaringType)) // return 0; start = 1; } for (i = start; i < numberOfParameters; i++) { tParameter *pParam = &pMethod->pParams[i]; System.Reflection.ParameterInfo paramInfo = paramInfos[i - start]; // NOTE: We are not checking to see if params are REF params here. Potentially a problem. if (pParam->pStackTypeDef != MonoType.GetTypeForMonoType(paramInfo.ParameterType, ppMethodClassTypeArgs, ppMethodMethodTypeArgs)) { return(0); } } return(1); } return(0); }
public static tAsyncCall *GetProperties(tJITCallNative *pCallNative, byte *pThis_, byte *pParams, byte *pReturnValue) { tRuntimeType *pRuntimeType = (tRuntimeType *)pThis_; tMD_TypeDef * pTypeDef = pRuntimeType->pTypeDef; tMetaData * pMetaData = pTypeDef->pMetaData; // First we search through the table of propertymaps to find the propertymap for the requested type uint i; /*IDX_TABLE*/ uint firstIdx = 0, lastIdxExc = 0; uint numPropertyRows = pMetaData->tables.numRows[MetaDataTable.MD_TABLE_PROPERTY]; uint numPropertymapRows = pMetaData->tables.numRows[MetaDataTable.MD_TABLE_PROPERTYMAP]; for (i = 1; i <= numPropertymapRows; i++) { tMD_PropertyMap *pPropertyMap = (tMD_PropertyMap *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_PROPERTYMAP, i)); if (pPropertyMap->parent == pTypeDef->tableIndex) { firstIdx = MetaData.TABLE_OFS(pPropertyMap->propertyList); if (i < numPropertymapRows) { tMD_PropertyMap *pNextPropertyMap = (tMD_PropertyMap *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_PROPERTYMAP, i + 1)); lastIdxExc = MetaData.TABLE_OFS(pNextPropertyMap->propertyList); } else { lastIdxExc = numPropertyRows + 1; } break; } } // Instantiate a PropertyInfo[] uint numProperties = lastIdxExc - firstIdx; tMD_TypeDef *pArrayType = Type.GetArrayTypeDef(Type.types[Type.TYPE_SYSTEM_REFLECTION_PROPERTYINFO], null, null); /*HEAP_PTR*/ byte *ret = System_Array.NewVector(pArrayType, numProperties); // Allocate to return value straight away, so it cannot be GCed *(/*HEAP_PTR*/ byte **)pReturnValue = ret; // Now fill the PropertyInfo[] for (i = 0; i < numProperties; i++) { tMD_Property *pPropertyMetadata = (tMD_Property *)MetaData.GetTableRow(pMetaData, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_PROPERTY, firstIdx + i)); // Instantiate PropertyInfo and put it in the array tPropertyInfo *pPropertyInfo = (tPropertyInfo *)Heap.AllocType(Type.types[Type.TYPE_SYSTEM_REFLECTION_PROPERTYINFO]); System_Array.StoreElement(ret, i, (byte *)&pPropertyInfo); // Assign ownerType pPropertyInfo->ownerType = pThis_; // Assign name pPropertyInfo->name = System_String.FromCharPtrASCII(pPropertyMetadata->name); // Assign propertyType uint sigLength; byte *typeSig = MetaData.GetBlob(pPropertyMetadata->typeSig, &sigLength); MetaData.DecodeSigEntry(&typeSig); // Ignored: prolog MetaData.DecodeSigEntry(&typeSig); // Ignored: number of 'getter' parameters tMD_TypeDef *propertyTypeDef = Type.GetTypeFromSig(pMetaData, &typeSig, null, null); MetaData.Fill_TypeDef(propertyTypeDef, null, null); pPropertyInfo->propertyType = Type.GetTypeObject(propertyTypeDef); } return(null); }
public static void LoadBlobs(tMetaData *pThis, void *pStream, uint streamLen) { pThis->blobs.pStart = (byte *)pStream; Sys.log_f(1, "Loaded blobs\n"); }
public static /*STRING*/ byte *GetModuleRefName(tMetaData *pMetaData, /*IDX_TABLE*/ uint memberRefToken) { tMD_ModuleRef *pModRef = (tMD_ModuleRef *)MetaData.GetTableRow(pMetaData, memberRefToken); return(pModRef->name); }