diff --git a/Il2CppInterop.Generator/Extensions/AsmResolverExtensions.cs b/Il2CppInterop.Generator/Extensions/AsmResolverExtensions.cs index 7788790f..46688319 100644 --- a/Il2CppInterop.Generator/Extensions/AsmResolverExtensions.cs +++ b/Il2CppInterop.Generator/Extensions/AsmResolverExtensions.cs @@ -39,12 +39,16 @@ private static Parameter GetArgument(this ILProcessor instructions, int argument : method.Parameters[argumentIndex - 1]; } + public static bool IsReferenceType(this TypeDefinition type) => !type.IsValueType; + public static bool HasGenericParameters(this TypeDefinition type) => type.GenericParameters.Count > 0; public static bool HasGenericParameters(this MethodDefinition method) => method.GenericParameters.Count > 0; public static bool HasConstant(this FieldDefinition field) => field.Constant is not null; + public static bool IsInstance(this FieldDefinition field) => !field.IsStatic; + public static bool HasMethods(this TypeDefinition type) => type.Methods.Count > 0; public static bool HasFields(this TypeDefinition type) => type.Fields.Count > 0; diff --git a/Il2CppInterop.Generator/Passes/Pass80UnstripFields.cs b/Il2CppInterop.Generator/Passes/Pass80UnstripFields.cs index 4c9dcf1a..e0e77c89 100644 --- a/Il2CppInterop.Generator/Passes/Pass80UnstripFields.cs +++ b/Il2CppInterop.Generator/Passes/Pass80UnstripFields.cs @@ -25,13 +25,15 @@ public static void DoPass(RewriteGlobalContext context) var processedType = processedAssembly.TryGetTypeByName(unityType.FullName); if (processedType == null) continue; - if (!unityType.IsValueType || unityType.IsEnum) - continue; + if (unityType.IsEnum) + continue;// Enum fields do not get stripped. foreach (var unityField in unityType.Fields) { - if (unityField.IsStatic && !unityField.HasConstant()) continue; - if (processedType.NewType.IsExplicitLayout && !unityField.IsStatic) continue; + if (unityField.IsStatic && !unityField.HasConstant()) + continue;// Non-constant static fields might require initialization, which we can't do. + if (unityField.IsInstance() && (unityType.IsReferenceType() || processedType.NewType.IsExplicitLayout)) + continue; var processedField = processedType.TryGetFieldByUnityAssemblyField(unityField); if (processedField != null) continue; diff --git a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs index 826250fb..6c20ced1 100644 --- a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs +++ b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs @@ -102,7 +102,10 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t Pass80UnstripMethods.ResolveTypeInNewAssembliesRaw(globalContext, fieldArg.DeclaringType!.ToTypeSignature(), imports); if (fieldDeclarer == null) return false; - var newField = fieldDeclarer.Resolve()?.Fields.SingleOrDefault(it => it.Name == fieldArg.Name); + var fieldDeclarerDefinition = fieldDeclarer.Resolve(); + if (fieldDeclarerDefinition == null) + return false; + var newField = fieldDeclarerDefinition.Fields.SingleOrDefault(it => it.Name == fieldArg.Name); if (newField != null) { var newInstruction = targetBuilder.Add(bodyInstruction.OpCode, imports.Module.DefaultImporter.ImportField(newField)); @@ -112,7 +115,7 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t { if (bodyInstruction.OpCode == OpCodes.Ldfld || bodyInstruction.OpCode == OpCodes.Ldsfld) { - var getterMethod = fieldDeclarer.Resolve()?.Properties + var getterMethod = fieldDeclarerDefinition.Properties .SingleOrDefault(it => it.Name == fieldArg.Name)?.GetMethod; if (getterMethod == null) return false; @@ -122,7 +125,7 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t } else if (bodyInstruction.OpCode == OpCodes.Stfld || bodyInstruction.OpCode == OpCodes.Stsfld) { - var setterMethod = fieldDeclarer.Resolve()?.Properties + var setterMethod = fieldDeclarerDefinition.Properties .SingleOrDefault(it => it.Name == fieldArg.Name)?.SetMethod; if (setterMethod == null) return false;