Skip to content

Commit

Permalink
Implement nested type lookups in GetClassFromName
Browse files Browse the repository at this point in the history
  • Loading branch information
RedBrumbler committed Dec 21, 2023
1 parent a5e0f21 commit cbb910c
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/utils/il2cpp-type-check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,32 @@ namespace il2cpp_utils {
static std::unordered_map<std::pair<std::string, std::string>, Il2CppClass*, hash_pair> namesToClassesCache;
static std::mutex nameHashLock;

Il2CppClass* FindNested(Il2CppClass* declaring, std::string_view typeName) {
static auto logger = getLogger().WithContext("FindNested");
// logger.info("trying to find: %s ", typeName.data());

if (!declaring) return nullptr;
auto token = typeName.find("/");
bool deeperNested = token != std::string::npos;

auto subTypeName = deeperNested ? typeName : typeName.substr(0, token);

void* myIter = nullptr;
Il2CppClass* found = nullptr;
while (Il2CppClass* nested = il2cpp_functions::class_get_nested_types(declaring, &myIter)) {
if (subTypeName == nested->name) {
found = nested;
break;
}
}

if (deeperNested) {
return FindNested(found, typeName.substr(token + 1));
} else {
return found;
}
}

Il2CppClass* GetClassFromName(std::string_view name_space, std::string_view type_name) {
il2cpp_functions::Init();
static auto logger = getLogger().WithContext("GetClassFromName");
Expand Down Expand Up @@ -46,6 +72,26 @@ namespace il2cpp_utils {
return klass;
}
}

// we failed to find the class directly, time to check if it is a nested class, and if so look for it
auto token = type_name.find("/");
bool nested = token != std::string::npos;
if (nested) { // this is a nested name
// get the first part of the nested type_name
auto declaringTypeName = std::string(type_name.substr(0, token));
// get the first class, which is the declaring class
auto declaring = GetClassFromName(name_space, declaringTypeName);
// recursively look through the nested classes of the declaring class until we run out of tokens ('/') or we run into a problem where we don't find a class
auto klass = FindNested(declaring, type_name.substr(token + 1));

if (klass) {
nameHashLock.lock();
namesToClassesCache.emplace(key, klass);
nameHashLock.unlock();
return klass;
}
}

logger.error("Could not find class with namepace: %s and name: %s",
name_space.data(), type_name.data());
return nullptr;
Expand Down

0 comments on commit cbb910c

Please sign in to comment.