Skip to content

Commit

Permalink
[fix] 修复对嵌套结构计算arm64 HFA的bug
Browse files Browse the repository at this point in the history
  • Loading branch information
pirunxi committed May 21, 2022
1 parent 67bf68f commit 324a148
Show file tree
Hide file tree
Showing 5 changed files with 207,851 additions and 206,774 deletions.
8 changes: 4 additions & 4 deletions huatuo/interpreter/InterpreterModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ namespace interpreter
const NativeCallMethod* GetNativeCallMethod(const T* method, bool forceStatic)
{
char sigName[1000];
ComputSignature(method, !forceStatic, sigName, sizeof(sigName) - 1);
ComputeSignature(method, !forceStatic, sigName, sizeof(sigName) - 1);
auto it = s_calls.find(sigName);
return (it != s_calls.end()) ? &it->second : nullptr;
}
Expand All @@ -71,7 +71,7 @@ namespace interpreter
const NativeInvokeMethod* GetNativeInvokeMethod(const T* method)
{
char sigName[1000];
ComputSignature(method, false, sigName, sizeof(sigName) - 1);
ComputeSignature(method, false, sigName, sizeof(sigName) - 1);
auto it = s_invokes.find(sigName);
return (it != s_invokes.end()) ? &it->second : nullptr;
}
Expand Down Expand Up @@ -161,7 +161,7 @@ namespace interpreter
return ncm->managed2NativeMethod;
}
char sigName[1000];
ComputSignature(method, !forceStatic, sigName, sizeof(sigName) - 1);
ComputeSignature(method, !forceStatic, sigName, sizeof(sigName) - 1);

TEMP_FORMAT(errMsg, "GetManaged2NativeMethodPointer. sinature:%s not support.", sigName);
RaiseMethodNotSupportException(method, errMsg);
Expand All @@ -171,7 +171,7 @@ namespace interpreter
Managed2NativeCallMethod InterpreterModule::GetManaged2NativeMethodPointer(const metadata::ResolveStandAloneMethodSig& method)
{
char sigName[1000];
ComputSignature(&method.returnType, method.params, method.paramCount, false, sigName, sizeof(sigName) - 1);
ComputeSignature(&method.returnType, method.params, method.paramCount, false, sigName, sizeof(sigName) - 1);
auto it = s_calls.find(sigName);
if (it != s_calls.end())
{
Expand Down
123 changes: 80 additions & 43 deletions huatuo/interpreter/MethodBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,66 +259,103 @@ namespace huatuo
}
}

static void AppendString(char* sigBuf, size_t bufSize, size_t& pos, const char* str)
struct HFATypeInfo
{
size_t len = std::strlen(str);
if (pos + len < bufSize)
{
std::strcpy(sigBuf + pos, str);
pos += len;
}
else
{
IL2CPP_ASSERT(false);
}
}
const Il2CppType* eleType;
int32_t count;
};

static void AppendValueTypeSignature(Il2CppClass* klass, bool returnType, char* sigBuf, size_t bufferSize, size_t& pos)

static bool ComputeHFATypeInfo0(Il2CppClass* klass, HFATypeInfo& typeInfo)
{
int typeSize = il2cpp::vm::Class::GetValueSize(klass, nullptr);
#if HUATUO_TARGET_ARM
const Il2CppType* fieldType = nullptr;
int32_t fieldSize = 0;
int32_t humoFieldCount = 0;
bool isHFA = true;
il2cpp::vm::Class::SetupFields(klass);
for (uint16_t i = 0; i < klass->field_count; i++)
{
FieldInfo* field = &klass->fields[i];
if (!metadata::IsInstanceField(field->type))
FieldInfo* field = klass->fields + i;
const Il2CppType* ftype = field->type;
if (!metadata::IsInstanceField(ftype))
{
continue;
}
if (fieldType == nullptr)
if (ftype->byref)
{
if (!field->type->byref && (field->type->type == IL2CPP_TYPE_R4 || field->type->type == IL2CPP_TYPE_R8))
return false;
}
if ((ftype->type != IL2CPP_TYPE_R4 && ftype->type != IL2CPP_TYPE_R8))
{
if (ftype->type == IL2CPP_TYPE_VALUETYPE || (ftype->type == IL2CPP_TYPE_GENERICINST && ftype->data.generic_class->type->type == IL2CPP_TYPE_VALUETYPE))
{
fieldType = field->type;
fieldSize = field->type->type == IL2CPP_TYPE_R4 ? 4 : 8;
Il2CppClass* fieldKlass = il2cpp::vm::Class::FromIl2CppType(ftype);
if (!ComputeHFATypeInfo0(fieldKlass, typeInfo))
{
return false;
}
}
else
{
isHFA = false;
break;
return false;
}
}
else if (!metadata::IsTypeEqual(field->type, fieldType))
else if (typeInfo.eleType == nullptr || metadata::IsTypeEqual(ftype, typeInfo.eleType))
{
isHFA = false;
break;
typeInfo.eleType = ftype;
++typeInfo.count;
}
int32_t fieldOffsetSinceData = field->offset - sizeof(Il2CppObject);
if (fieldOffsetSinceData != humoFieldCount * fieldSize)
else
{
isHFA = false;
break;
return false;
}
++humoFieldCount;
}
if (isHFA && humoFieldCount > 0)
return typeInfo.count <= 4;
}

static bool ComputeHFATypeInfo(Il2CppClass* klass, HFATypeInfo& typeInfo)
{
typeInfo = {};
int32_t size = metadata::GetTypeValueSize(klass);
switch (size)
{
case 8:
case 12:
case 16:
case 24:
case 32: break;
default: return false;
}

bool isHFA = ComputeHFATypeInfo0(klass, typeInfo);
if (isHFA && typeInfo.count >= 2 && typeInfo.count <= 4)
{
int32_t fieldSize = typeInfo.eleType->type == IL2CPP_TYPE_R4 ? 4 : 8;
return size == fieldSize * typeInfo.count;
}
return false;
}

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
{
IL2CPP_ASSERT(false);
}
}

static void AppendValueTypeSignature(Il2CppClass* klass, bool returnType, char* sigBuf, size_t bufferSize, size_t& pos)
{
int typeSize = il2cpp::vm::Class::GetValueSize(klass, nullptr);
#if HUATUO_TARGET_ARM
HFATypeInfo typeInfo = {};
if (ComputeHFATypeInfo(klass, typeInfo))
{
if (fieldSize == 4)
if (typeInfo.eleType->type == IL2CPP_TYPE_R4)
{
switch (humoFieldCount)
switch (typeInfo.count)
{
case 2:
{
Expand All @@ -339,8 +376,8 @@ namespace huatuo
}
else
{
IL2CPP_ASSERT(fieldSize == 8);
switch (humoFieldCount)
IL2CPP_ASSERT(typeInfo.eleType->type == IL2CPP_TYPE_R8);
switch (typeInfo.count)
{
case 2:
{
Expand Down Expand Up @@ -464,7 +501,7 @@ namespace huatuo
}
}

bool ComputSignature(const Il2CppType* ret, const Il2CppType* params, uint32_t paramCount, bool instanceCall, char* sigBuf, size_t bufferSize)
bool ComputeSignature(const Il2CppType* ret, const Il2CppType* params, uint32_t paramCount, bool instanceCall, char* sigBuf, size_t bufferSize)
{
size_t pos = 0;
AppendSignature(ret, true, sigBuf, bufferSize, pos);
Expand All @@ -482,7 +519,7 @@ namespace huatuo
return true;
}

bool ComputSignature(const Il2CppMethodDefinition* method, bool call, char* sigBuf, size_t bufferSize)
bool ComputeSignature(const Il2CppMethodDefinition* method, bool call, char* sigBuf, size_t bufferSize)
{
size_t pos = 0;

Expand All @@ -504,7 +541,7 @@ namespace huatuo
return true;
}

bool ComputSignature(const MethodInfo* method, bool call, char* sigBuf, size_t bufferSize)
bool ComputeSignature(const MethodInfo* method, bool call, char* sigBuf, size_t bufferSize)
{
size_t pos = 0;

Expand Down
Loading

0 comments on commit 324a148

Please sign in to comment.