U32 MetaData_CompareNameAndSig(STRING name, BLOB_ sigBlob, tMetaData *pSigMetaData, tMD_TypeDef **ppSigClassTypeArgs, tMD_TypeDef **ppSigMethodTypeArgs, tMD_MethodDef *pMethod, tMD_TypeDef **ppMethodClassTypeArgs, tMD_TypeDef **ppMethodMethodTypeArgs) {
	if (strcmp(name, pMethod->name) == 0) {
		SIG sig, thisSig;
		U32 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) {
			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, *pThisParamType;

			pParamType = Type_GetTypeFromSig(pSigMetaData, &sig, ppSigClassTypeArgs, ppSigMethodTypeArgs);
			pThisParamType = Type_GetTypeFromSig(pMethod->pMetaData, &thisSig, ppMethodClassTypeArgs, ppMethodMethodTypeArgs);
			if (pParamType != pThisParamType) {
				return 0;
			}
		}
		// All parameters the same, so found the right method
		return 1;
	}
	return 0;
}
Exemple #2
0
tMD_MethodDef* Generics_GetMethodDefFromSpec
	(tMD_MethodSpec *pMethodSpec, tMD_TypeDef **ppCallingClassTypeArgs, tMD_TypeDef **ppCallingMethodTypeArgs) {

	tMD_MethodDef *pCoreMethod, *pMethod;
	SIG sig;
	U32 argCount, i;
	tMD_TypeDef **ppTypeArgs;

	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 = malloc(argCount * sizeof(tMD_TypeDef*));

	for (i=0; i<argCount; i++) {
		tMD_TypeDef *pArgType;

		pArgType = Type_GetTypeFromSig(pMethodSpec->pMetaData, &sig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs);
		ppTypeArgs[i] = pArgType;
	}

	pMethod = Generics_GetMethodDefFromCoreMethod(pCoreMethod, pCoreMethod->pParentType, argCount, ppTypeArgs);
	free(ppTypeArgs);

	return pMethod;
}
void MetaData_Fill_FieldDef(tMD_TypeDef *pParentType, tMD_FieldDef *pFieldDef, U32 memOffset, tMD_TypeDef **ppClassTypeArgs) {
	U32 sigLength;
	PTR sig;
	tMetaData *pMetaData;
	//log_f(5,"MetaData_Fill_FieldDef %s.%s\n", pParentType->name,pFieldDef->name);

	pFieldDef->pParentType = pParentType;

	sig = MetaData_GetBlob(pFieldDef->signature, &sigLength);

	MetaData_DecodeSigEntry(&sig); // First entry always 0x06
	pFieldDef->pType = Type_GetTypeFromSig(pFieldDef->pMetaData, &sig, ppClassTypeArgs, NULL);
	if (pFieldDef->pType == NULL) {
		// If the field is a core generic type definition, then we can't do anything more
		return;
	}
	MetaData_Fill_TypeDef(pFieldDef->pType, NULL, NULL);
	// A check for 0 is done so if a type has a field of it's own type it is handled correctly.
	pFieldDef->memSize = (pFieldDef->pType->stackSize>0)?pFieldDef->pType->stackSize:sizeof(void*);
	pFieldDef->memOffset = memOffset;
	pFieldDef->pFieldDef = pFieldDef;

	pMetaData = pFieldDef->pMetaData;
	if (FIELD_HASFIELDRVA(pFieldDef)) {
		U32 i, top;

		// Field has RVA, so load it from FieldRVA
		top = pMetaData->tables.numRows[MD_TABLE_FIELDRVA];
		for (i=1; i<=top; i++) {
			tMD_FieldRVA *pFieldRVA;

			pFieldRVA = (tMD_FieldRVA*)MetaData_GetTableRow(pMetaData, MAKE_TABLE_INDEX(MD_TABLE_FIELDRVA, i));
			if (pFieldRVA->field == pFieldDef->tableIndex) {
				pFieldDef->pMemory = (PTR)pFieldRVA->rva;
				break;
			}
		}
	} else if (FIELD_ISLITERAL(pFieldDef)) {
		// Field is literal, so make pMemory point to the value signature
		U32 i, top;

		top = pMetaData->tables.numRows[MD_TABLE_CONSTANT];
		for (i=1; i<=top; i++) {
			tMD_Constant *pConst;
			pConst = (tMD_Constant*)MetaData_GetTableRow(pMetaData, MAKE_TABLE_INDEX(MD_TABLE_CONSTANT, i));
			if (pConst->parent == pFieldDef->tableIndex) {
				// Found the field
				pFieldDef->pMemory = (PTR)pConst;
				break;
			}
		}
	}
}
static tMD_MethodDef* FindMethodInType(tMD_TypeDef *pTypeDef, STRING name, tMetaData *pSigMetaData, BLOB_ sigBlob, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) {
	U32 i;
	tMD_TypeDef *pLookInType = pTypeDef;

	do {
		for (i=0; i<pLookInType->numMethods; i++) {
			if (MetaData_CompareNameAndSig(name, sigBlob, pSigMetaData, ppClassTypeArgs, ppMethodTypeArgs, pLookInType->ppMethods[i], pLookInType->ppClassTypeArgs, NULL)) {
				return pLookInType->ppMethods[i];
			}
		}
		pLookInType = pLookInType->pParent;
	} while (pLookInType != NULL);

	{
		// Error reporting!!
		U32 entry, numParams, i;
		SIG sig;
		char *pMsg;
		tMD_TypeDef *pParamTypeDef;

		pMsg = (char*)malloc(2048);
		*pMsg = 0;
		sig = MetaData_GetBlob(sigBlob, &i);
		entry = MetaData_DecodeSigEntry(&sig);
		if ((entry & SIG_METHODDEF_HASTHIS) == 0) {
			sprintf(strchr(pMsg, 0), "static ");
		}
		if (entry & SIG_METHODDEF_GENERIC) {
			// 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); // return type
		if (pParamTypeDef != NULL) {
			sprintf(strchr(pMsg, 0), "%s ", pParamTypeDef->name);
		}
		sprintf(strchr(pMsg, 0), "%s.%s.%s(", pTypeDef->nameSpace, pTypeDef->name, name);
		for (i=0; i<numParams; i++) {
			pParamTypeDef = Type_GetTypeFromSig(pSigMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs);
			if (i > 0) {
				sprintf(strchr(pMsg, 0), ",");
			}
			if (pParamTypeDef != NULL) {
				sprintf(strchr(pMsg, 0), pParamTypeDef->name);
			} else {
				sprintf(strchr(pMsg, 0), "???");
			}
		}
		Crash("FindMethodInType(): Cannot find method %s)", pMsg);
	}
	FAKE_RETURN;
}
Exemple #5
0
U32 Type_IsMethod(tMD_MethodDef *pMethod, STRING name, tMD_TypeDef *pReturnType, U32 numParams, U8 *pParamTypeIndexs) {
	SIG sig;
	U32 sigLen, numSigParams, i, nameLen;

	nameLen = (U32)strlen(name);
	if (name[nameLen-1] == '>') {
		// Generic instance method
		if (strncmp(pMethod->name, name, nameLen - 1) != 0) {
			return 0;
		}
	} else {
		if (strcmp(pMethod->name, name) != 0) {
			return 0;
		}
	}

	sig = MetaData_GetBlob(pMethod->signature, &sigLen);
	i = MetaData_DecodeSigEntry(&sig); // Don't care about this
	if (i & SIG_METHODDEF_GENERIC) {
		MetaData_DecodeSigEntry(&sig);
	}
	numSigParams = MetaData_DecodeSigEntry(&sig);

	if (numParams != numSigParams) {
		return 0;
	}

	if (pReturnType == types[TYPE_SYSTEM_VOID]) {
		pReturnType = NULL;
	}

	for (i=0; i<numParams + 1; i++) {
		tMD_TypeDef *pSigType, *pParamType;

		pSigType = Type_GetTypeFromSig(pMethod->pMetaData, &sig, NULL, NULL);
		pParamType = (i == 0)?pReturnType:types[pParamTypeIndexs[i-1]];

		if (pSigType != NULL && TYPE_ISARRAY(pSigType) && pParamType == types[TYPE_SYSTEM_ARRAY_NO_TYPE]) {
			// It's ok...
		} else {
			if (pSigType != pParamType) {
				goto endBad;
			}
		}
	}
	return 1;

endBad:
	return 0;
}
tMD_TypeDef* MetaData_GetTypeDefFromDefRefOrSpec(tMetaData *pMetaData, IDX_TABLE 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) {
		return ((tMDC_ToTypeDef*)pTableEntry)->pTypeDef;
	}

	switch (TABLE_ID(token)) {
		case MD_TABLE_TYPEDEF:
			((tMDC_ToTypeDef*)pTableEntry)->pTypeDef = (tMD_TypeDef*)pTableEntry;
			return (tMD_TypeDef*)pTableEntry;
		case 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);
				pTypeRef->pTypeDef = pTypeDef;
				return pTypeDef;
			}
		case MD_TABLE_TYPESPEC:
			{
				tMD_TypeSpec *pTypeSpec;
				tMD_TypeDef *pTypeDef;
				SIG sig;

				pTypeSpec = (tMD_TypeSpec*)pTableEntry;
				sig = MetaData_GetBlob(pTypeSpec->signature, NULL);
				pTypeDef = Type_GetTypeFromSig(pTypeSpec->pMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs);
				// Note: Cannot cache the TypeDef for this TypeSpec because it
				// can change depending on class arguemnts given.

				return pTypeDef;
			}
			return NULL;
		default:
			Crash("MetaData_GetTypeDefFromDefRefOrSpec(): Cannot handle token: 0x%08x", token);
			FAKE_RETURN;
	}
}
// Return pointer to the relevant Def structure.
// pObjectType returns:
// 0 - tMD_TypeDef
// 1 - tMD_MethodDef
// 2 - tMD_FieldDef
// (These link up with the JIT_LOADTOKEN_* opcodes)
PTR MetaData_GetTypeMethodField(tMetaData *pMetaData, IDX_TABLE token, U32 *pObjectType, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) {
	switch (TABLE_ID(token)) {
		case MD_TABLE_TYPEDEF:
		case MD_TABLE_TYPEREF:
		case MD_TABLE_TYPESPEC:
			{
				tMD_TypeDef *pTypeDef;

				pTypeDef = MetaData_GetTypeDefFromDefRefOrSpec(pMetaData, token, ppClassTypeArgs, ppMethodTypeArgs);
				MetaData_Fill_TypeDef(pTypeDef, NULL, NULL);
				*pObjectType = 0;
				return (PTR)pTypeDef;
			}
		case 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 (PTR)pMethodDef;
			}
		case 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 (PTR)pFieldDef;
			}
		case MD_TABLE_MEMBERREF:
			{
				tMD_MemberRef *pMemberRef;
				SIG sig;

				pMemberRef = (tMD_MemberRef*)MetaData_GetTableRow(pMetaData, token);
				sig = MetaData_GetBlob(pMemberRef->signature, NULL);
				if (*(U8*)sig == 0x06) {
					// Field
					goto field;
				} else {
					// Method
					goto method;
				}
			}
	}

	Crash("MetaData_GetTypeMethodField(): Cannot handle token: 0x%08x", token);
	FAKE_RETURN;
}
Exemple #8
0
void MetaData_Fill_MethodDef(tMD_TypeDef *pParentType, tMD_MethodDef *pMethodDef, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) {
	SIG sig;
	U32 i, entry, totalSize;

	pMethodDef->pParentType = pParentType;
	pMethodDef->pMethodDef = pMethodDef;
	pMethodDef->isFilled = 1;

	if (pMethodDef->isGenericDefinition) 
	{
		// Generic definition method, so can't do any more.
		log_f(3, "Loaded Generic 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) 
	{
		// Has generic parameters. Read how many, but don't care about the answer
		MetaData_DecodeSigEntry(&sig);
	}
	pMethodDef->numberOfParameters = MetaData_DecodeSigEntry(&sig) + (METHOD_ISSTATIC(pMethodDef)?0:1);
	pMethodDef->pReturnType = Type_GetTypeFromSig(pMethodDef->pMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs);
	if (pMethodDef->pReturnType != NULL)
	{
		MetaData_Fill_TypeDef(pMethodDef->pReturnType, NULL, NULL);
	}
	pMethodDef->pParams = (tParameter*)malloc(pMethodDef->numberOfParameters * sizeof(tParameter));
	totalSize = 0;
	if (!METHOD_ISSTATIC(pMethodDef))
	{
		// Fill in parameter info for the 'this' pointer
		pMethodDef->pParams->offset = 0;
		if (pParentType->isValueType) 
		{
			// If this is a value-type then the 'this' pointer is actually an IntPtr to the value-type's location
			pMethodDef->pParams->size = 4;
			pMethodDef->pParams->pTypeDef = types[TYPE_SYSTEM_INTPTR];
		} 
		else 
		{
			pMethodDef->pParams->size = 4;
			pMethodDef->pParams->pTypeDef = pParentType;
		}
		totalSize = 4;
	}
	for (i=totalSize>>2; i<pMethodDef->numberOfParameters; i++)
	{
		tMD_TypeDef *pTypeDef;
		U32 size;

		pTypeDef = Type_GetTypeFromSig(pMethodDef->pMetaData, &sig, ppClassTypeArgs, ppMethodTypeArgs);
		//if (pTypeDef != NULL) {
			MetaData_Fill_TypeDef(pTypeDef, NULL, NULL);
			size = pTypeDef->stackSize;
		//} else {
		//	// If this method has generic-type-argument arguments, then we can't do anything very sensible yet
		//	size = 0;
		//}
		pMethodDef->pParams[i].pTypeDef = pTypeDef;
		pMethodDef->pParams[i].offset = totalSize;
		pMethodDef->pParams[i].size = size;
		totalSize += size;
	}
	pMethodDef->parameterStackSize = totalSize;

	log_f(3, "Loaded Method %s.%s::%s \n", pParentType->nameSpace, pParentType->name, pMethodDef->name);
}