Exemple #1
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;
}
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 #3
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;
}
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;
			}
		}
	}
}
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 #6
0
tMD_TypeDef* Generics_GetGenericTypeFromSig
	(tMetaData *pMetaData, SIG *pSig, tMD_TypeDef **ppCallingClassTypeArgs, tMD_TypeDef **ppCallingMethodTypeArgs) {
	tMD_TypeDef *pCoreType, *pRet;
	U32 numTypeArgs, i;
	tMD_TypeDef **ppTypeArgs;

	pCoreType = Type_GetTypeFromSig(pMetaData, pSig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs);
	MetaData_Fill_TypeDef(pCoreType, ppCallingClassTypeArgs, ppCallingMethodTypeArgs); //NULL, NULL);

	numTypeArgs = MetaData_DecodeSigEntry(pSig);
	ppTypeArgs = (tMD_TypeDef**)malloc(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);
		}
	}

	pRet = Generics_GetGenericTypeFromCoreType(pCoreType, numTypeArgs, ppTypeArgs);
	free(ppTypeArgs);
	return pRet;
}
Exemple #7
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);
}
Exemple #8
0
// Get the TypeDef from the type signature
// Also get the size of a field from the signature
// This is needed to avoid recursive sizing of types like System.Boolean,
// that has a field of type System.Boolean
tMD_TypeDef* Type_GetTypeFromSig(tMetaData *pMetaData, SIG *pSig, tMD_TypeDef **ppClassTypeArgs, tMD_TypeDef **ppMethodTypeArgs) {
	U32 entry;

	entry = MetaData_DecodeSigEntry(pSig);
	switch (entry) {
		case ELEMENT_TYPE_VOID:
			return NULL;

		case ELEMENT_TYPE_BOOLEAN:
			return types[TYPE_SYSTEM_BOOLEAN];

		case ELEMENT_TYPE_CHAR:
			return types[TYPE_SYSTEM_CHAR];

		case ELEMENT_TYPE_I1:
			return types[TYPE_SYSTEM_SBYTE];

		case ELEMENT_TYPE_U1:
			return types[TYPE_SYSTEM_BYTE];

		case ELEMENT_TYPE_I2:
			return types[TYPE_SYSTEM_INT16];

		case ELEMENT_TYPE_U2:
			return types[TYPE_SYSTEM_UINT16];

		case ELEMENT_TYPE_I4:
			return types[TYPE_SYSTEM_INT32];

		case ELEMENT_TYPE_I8:
			return types[TYPE_SYSTEM_INT64];

		case ELEMENT_TYPE_U8:
			return types[TYPE_SYSTEM_UINT64];

		case ELEMENT_TYPE_U4:
			return types[TYPE_SYSTEM_UINT32];

		case ELEMENT_TYPE_R4:
			return types[TYPE_SYSTEM_SINGLE];

		case ELEMENT_TYPE_R8:
			return types[TYPE_SYSTEM_DOUBLE];

		case ELEMENT_TYPE_STRING:
			return types[TYPE_SYSTEM_STRING];

		case ELEMENT_TYPE_PTR:
			return types[TYPE_SYSTEM_UINTPTR];

		case ELEMENT_TYPE_BYREF:
			{
				tMD_TypeDef *pByRefType;

				// type of the by-ref parameter, don't care
				pByRefType = Type_GetTypeFromSig(pMetaData, pSig, ppClassTypeArgs, ppMethodTypeArgs);
			}
			// fall-through
		case ELEMENT_TYPE_INTPTR:
			return types[TYPE_SYSTEM_INTPTR];

		case ELEMENT_TYPE_VALUETYPE:
		case ELEMENT_TYPE_CLASS:
			entry = MetaData_DecodeSigEntryToken(pSig);
			return MetaData_GetTypeDefFromDefRefOrSpec(pMetaData, entry, ppClassTypeArgs, ppMethodTypeArgs);

		case ELEMENT_TYPE_VAR:
			entry = MetaData_DecodeSigEntry(pSig); // This is the argument number
			if (ppClassTypeArgs == NULL) {
				// Return null here as we don't yet know what the type really is.
				// The generic instantiation code figures this out later.
				return NULL;
			} else {
				return ppClassTypeArgs[entry];
			}

		case ELEMENT_TYPE_GENERICINST:
			{
				tMD_TypeDef *pType;

				pType = Generics_GetGenericTypeFromSig(pMetaData, pSig, ppClassTypeArgs, ppMethodTypeArgs);
				return pType;
			}

		//case ELEMENT_TYPE_INTPTR:
		//	return types[TYPE_SYSTEM_INTPTR];

		case ELEMENT_TYPE_UINTPTR:
			return types[TYPE_SYSTEM_UINTPTR];

		case ELEMENT_TYPE_OBJECT:
			return types[TYPE_SYSTEM_OBJECT];

		case ELEMENT_TYPE_SZARRAY:
			{
				tMD_TypeDef *pElementType;

				pElementType = Type_GetTypeFromSig(pMetaData, pSig, ppClassTypeArgs, ppMethodTypeArgs);
				return Type_GetArrayTypeDef(pElementType, ppClassTypeArgs, ppMethodTypeArgs);
			}

		case ELEMENT_TYPE_MVAR:
			entry = MetaData_DecodeSigEntry(pSig); // This is the argument number
			if (ppMethodTypeArgs == NULL) {
				// Can't do anything sensible, as we don't have any type args
				return NULL;
			} else {
				return ppMethodTypeArgs[entry];
			}

		default:
			Crash("Type_GetTypeFromSig(): Cannot handle signature element type: 0x%02x", entry);
			FAKE_RETURN;
	}
}