123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- #include "MethodBridge.h"
- #include "vm/Object.h"
- #include "vm/Class.h"
- #include "metadata/GenericMetadata.h"
- #include "../metadata/MetadataModule.h"
- #include "../metadata/MetadataUtil.h"
- #include "Interpreter.h"
- #include "InterpreterModule.h"
- #include "MemoryUtil.h"
- namespace hybridclr
- {
- namespace interpreter
- {
- void ConvertInvokeArgs(StackObject* resultArgs, const MethodInfo* method, MethodArgDesc* argDescs, void** args)
- {
- int32_t dstIdx = 0;
- for (uint8_t i = 0; i < method->parameters_count; i++)
- {
- StackObject* dst = resultArgs + dstIdx;
- MethodArgDesc& argDesc = argDescs[i];
- if (argDesc.passbyValWhenInvoke)
- {
- dst->ptr = args[i];
- ++dstIdx;
- }
- else
- {
- #if SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS
- CopyStackObject(dst, args[i], argDesc.stackObjectSize);
- #else
- std::memcpy(dst, args[i], argDesc.stackObjectSize * sizeof(StackObject));
- #endif
- dstIdx += argDesc.stackObjectSize;
- }
- }
- }
-
- static void AppendString(char* sigBuf, size_t bufSize, size_t& pos, const char* str)
- {
- size_t len = std::strlen(str);
- if (pos + len < bufSize)
- {
- std::strcpy(sigBuf + pos, str);
- pos += len;
- }
- else
- {
- RaiseExecutionEngineException("");
- }
- }
- inline void AppendSignatureObjOrRefOrPointer(char* sigBuf, size_t bufSize, size_t& pos)
- {
- AppendString(sigBuf, bufSize, pos, "u");
- }
- inline void AppendSignatureInterpreterValueType(char* sigBuf, size_t bufSize, size_t& pos)
- {
- AppendString(sigBuf, bufSize, pos, "$");
- }
- static void AppendSignature(const Il2CppType* type, char* sigBuf, size_t bufferSize, size_t& pos, bool convertTypeName2SigName = true);
- static bool IsSystemOrUnityAssembly(const Il2CppImage* image)
- {
- const char* assName = image->nameNoExt;
- if (std::strcmp(assName, "mscorlib") == 0)
- {
- return true;
- }
- if (std::strncmp(assName, "System.", 7) == 0)
- {
- return true;
- }
- if (std::strncmp(assName, "UnityEngine.", 12) == 0)
- {
- return true;
- }
- return false;
- }
- static void BuildValueTypeFullName(const Il2CppClass* klass, char* sigBuf, size_t bufferSize, size_t& pos)
- {
- if (klass->declaringType)
- {
- BuildValueTypeFullName(klass->declaringType, sigBuf, bufferSize, pos);
- AppendString(sigBuf, bufferSize, pos, "/");
- AppendString(sigBuf, bufferSize, pos, klass->name);
- return;
- }
- if (!IsSystemOrUnityAssembly(klass->image))
- {
- AppendString(sigBuf, bufferSize, pos, klass->image->nameNoExt);
- AppendString(sigBuf, bufferSize, pos, ":");
- }
- if (klass->namespaze[0])
- {
- AppendString(sigBuf, bufferSize, pos, klass->namespaze);
- AppendString(sigBuf, bufferSize, pos, ".");
- }
- AppendString(sigBuf, bufferSize, pos, klass->name);
- }
- static void BuildGenericValueTypeFullName(const Il2CppType* type, char* sigBuf, size_t bufferSize, size_t& pos)
- {
- const Il2CppType* underlyingGenericType = type->data.generic_class->type;
- const Il2CppClass* underlyingGenericClass = il2cpp::vm::Class::FromIl2CppType(underlyingGenericType);
- BuildValueTypeFullName(underlyingGenericClass, sigBuf, bufferSize, pos);
- AppendString(sigBuf, bufferSize, pos, "<");
- const Il2CppGenericInst* classInst = type->data.generic_class->context.class_inst;
- for (uint32_t i = 0 ; i < classInst->type_argc; ++i)
- {
- if (i != 0)
- {
- AppendString(sigBuf, bufferSize, pos, ",");
- }
- AppendSignature(classInst->type_argv[i], sigBuf, bufferSize, pos, false);
- }
- AppendString(sigBuf, bufferSize, pos, ">");
- }
- static void AppendSignature(const Il2CppType* type, char* sigBuf, size_t bufferSize, size_t& pos, bool convertTypeName2SigName)
- {
- if (type->byref)
- {
- AppendSignatureObjOrRefOrPointer(sigBuf, bufferSize, pos);
- return;
- }
- switch (type->type)
- {
- case IL2CPP_TYPE_VOID: AppendString(sigBuf, bufferSize, pos, "v"); break;
- case IL2CPP_TYPE_BOOLEAN: AppendString(sigBuf, bufferSize, pos, "u1"); break;
- case IL2CPP_TYPE_I1: AppendString(sigBuf, bufferSize, pos, "i1"); break;
- case IL2CPP_TYPE_U1: AppendString(sigBuf, bufferSize, pos, "u1"); break;
- case IL2CPP_TYPE_I2: AppendString(sigBuf, bufferSize, pos, "i2"); break;
- case IL2CPP_TYPE_U2:
- case IL2CPP_TYPE_CHAR: AppendString(sigBuf, bufferSize, pos, "u2"); break;
- case IL2CPP_TYPE_I4: AppendString(sigBuf, bufferSize, pos, "i4"); break;
- case IL2CPP_TYPE_U4: AppendString(sigBuf, bufferSize, pos, "u4"); break;
- case IL2CPP_TYPE_R4: AppendString(sigBuf, bufferSize, pos, "r4"); break;
- case IL2CPP_TYPE_R8: AppendString(sigBuf, bufferSize, pos, "r8"); break;
- case IL2CPP_TYPE_I8: AppendString(sigBuf, bufferSize, pos, "i8"); break;
- case IL2CPP_TYPE_U8: AppendString(sigBuf, bufferSize, pos, "u8"); break;
- case IL2CPP_TYPE_I: AppendString(sigBuf, bufferSize, pos, "i"); break;
- case IL2CPP_TYPE_U: AppendString(sigBuf, bufferSize, pos, "u"); break;
- case IL2CPP_TYPE_TYPEDBYREF:
- {
- IL2CPP_ASSERT(sizeof(Il2CppTypedRef) == sizeof(void*) * 3);
- AppendString(sigBuf, bufferSize, pos, "typedbyref");
- break;
- }
- case IL2CPP_TYPE_VALUETYPE:
- {
- const Il2CppTypeDefinition* typeDef = (const Il2CppTypeDefinition*)type->data.typeHandle;
- if (hybridclr::metadata::IsEnumType(typeDef))
- {
- AppendSignature(il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDef->elementTypeIndex), sigBuf, bufferSize, pos);
- break;
- }
- if (hybridclr::metadata::IsInterpreterType(typeDef))
- {
- AppendSignatureInterpreterValueType(sigBuf, bufferSize, pos);
- break;
- }
- char tempFullName[1024];
- size_t fullNamePos = 0;
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- BuildValueTypeFullName(klass, tempFullName, sizeof(tempFullName) - 1, fullNamePos);
- tempFullName[fullNamePos] = 0;
- AppendString(sigBuf, bufferSize, pos, convertTypeName2SigName ? InterpreterModule::GetValueTypeSignature(tempFullName) : tempFullName);
- break;
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- const Il2CppType* underlyingGenericType = type->data.generic_class->type;
- if (underlyingGenericType->type == IL2CPP_TYPE_CLASS)
- {
- AppendSignatureObjOrRefOrPointer(sigBuf, bufferSize, pos);
- break;
- }
- const Il2CppTypeDefinition* underlyingTypeDef = (const Il2CppTypeDefinition*)underlyingGenericType->data.typeHandle;
- if (hybridclr::metadata::IsEnumType(underlyingTypeDef))
- {
- AppendSignature(il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(underlyingTypeDef->elementTypeIndex), sigBuf, bufferSize, pos);
- break;
- }
- IL2CPP_ASSERT(underlyingGenericType->type == IL2CPP_TYPE_VALUETYPE);
- if (hybridclr::metadata::IsInterpreterType(underlyingTypeDef))
- {
- AppendSignatureInterpreterValueType(sigBuf, bufferSize, pos);
- break;
- }
-
- char tempFullName[1024];
- size_t fullNamePos = 0;
- BuildGenericValueTypeFullName(type, tempFullName, sizeof(tempFullName) - 1, fullNamePos);
- tempFullName[fullNamePos] = 0;
- AppendString(sigBuf, bufferSize, pos, convertTypeName2SigName ? InterpreterModule::GetValueTypeSignature(tempFullName) : tempFullName);
- break;
- }
- case IL2CPP_TYPE_VAR:
- case IL2CPP_TYPE_MVAR:
- {
- AppendString(sigBuf, bufferSize, pos, "!");
- break;
- }
- default: AppendSignatureObjOrRefOrPointer(sigBuf, bufferSize, pos); break;
- }
- }
- bool ComputeSignature(const Il2CppType* ret, const Il2CppType* params, uint32_t paramCount, bool instanceCall, char* sigBuf, size_t bufferSize)
- {
- size_t pos = 0;
- AppendSignature(ret, sigBuf, bufferSize, pos);
- if (instanceCall)
- {
- AppendSignatureObjOrRefOrPointer(sigBuf, bufferSize, pos);
- }
- for (uint32_t i = 0; i < paramCount; i++)
- {
- AppendSignature(params + i, sigBuf, bufferSize, pos);
- }
- sigBuf[pos] = 0;
- return true;
- }
- bool ComputeSignature(const Il2CppMethodDefinition* method, bool call, char* sigBuf, size_t bufferSize)
- {
- size_t pos = 0;
- if (method->genericContainerIndex != kGenericContainerIndexInvalid)
- {
- AppendString(sigBuf, bufferSize, pos, "!");
- return true;
- }
- const Il2CppImage* image = hybridclr::metadata::MetadataModule::GetImage(method)->GetIl2CppImage();
- AppendSignature(hybridclr::metadata::MetadataModule::GetIl2CppTypeFromEncodeIndex(method->returnType), sigBuf, bufferSize, pos);
- if (call && metadata::IsInstanceMethod(method))
- {
- AppendSignatureObjOrRefOrPointer(sigBuf, bufferSize, pos);
- }
- for (uint8_t i = 0; i < method->parameterCount; i++)
- {
- TypeIndex paramTypeIndex = hybridclr::metadata::MetadataModule::GetParameterDefinitionFromIndex(image, method->parameterStart + i)->typeIndex;
- AppendSignature(hybridclr::metadata::MetadataModule::GetIl2CppTypeFromEncodeIndex(paramTypeIndex), sigBuf, bufferSize, pos);
- }
- sigBuf[pos] = 0;
- return true;
- }
- inline bool ContainsGenericParameters(const MethodInfo* method)
- {
- IL2CPP_ASSERT(method->is_inflated);
- auto& ctx = method->genericMethod->context;
- if (ctx.class_inst && il2cpp::metadata::GenericMetadata::ContainsGenericParameters(ctx.class_inst))
- {
- return true;
- }
- if (ctx.method_inst && il2cpp::metadata::GenericMetadata::ContainsGenericParameters(ctx.method_inst))
- {
- return true;
- }
- return false;
- }
- bool ComputeSignature(const MethodInfo* method, bool call, char* sigBuf, size_t bufferSize)
- {
- size_t pos = 0;
- if (method->is_generic || (method->is_inflated && ContainsGenericParameters(method)))
- {
- AppendString(sigBuf, bufferSize, pos, "!");
- return true;
- }
- AppendSignature(method->return_type, sigBuf, bufferSize, pos);
- if (call && metadata::IsInstanceMethod(method))
- {
- AppendSignatureObjOrRefOrPointer(sigBuf, bufferSize, pos);
- }
- for (uint8_t i = 0; i < method->parameters_count; i++)
- {
- AppendSignature(GET_METHOD_PARAMETER_TYPE(method->parameters[i]), sigBuf, bufferSize, pos);
- }
- sigBuf[pos] = 0;
- return true;
- }
- }
- }
|