Skip to content

Commit

Permalink
Fix rare case when generic params can be out-of-order, nerf reg2regmo…
Browse files Browse the repository at this point in the history
…ve slightly
  • Loading branch information
Sam Byass committed Oct 12, 2021
1 parent 7227d17 commit 9726ab4
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 21 deletions.
5 changes: 5 additions & 0 deletions Cpp2IL.Core/Analysis/Actions/x86/RegToRegMoveAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public RegToRegMoveAction(MethodAnalysis<Instruction> context, Instruction instr

if (localBeingMoved.Type.FullName == _localBeingOverwritten?.Type?.FullName && (localBeingMoved.KnownInitialValue == _localBeingOverwritten.KnownInitialValue))
{
//For now, let's leave this to only work on primitives, because this is giving false positives everywhere

if(!localBeingMoved.Type.IsPrimitive)
return;

//Variable being overwritten is the same type as this one - are we maybe just changing the value of that one (e.g. in a loop)?
context.SetRegContent(newReg, _localBeingOverwritten);
copyingValueNotLocal = true;
Expand Down
50 changes: 29 additions & 21 deletions Cpp2IL.Core/AssemblyPopulator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public static void ConfigureHierarchy()
foreach (var typeDefinition in SharedState.AllTypeDefinitions)
{
var il2cppTypeDef = SharedState.ManagedToUnmanagedTypes[typeDefinition];

//Type generic params.
PopulateGenericParamsForType(il2cppTypeDef, typeDefinition);

//Set base type
if (il2cppTypeDef.RawBaseType is { } parent)
Expand Down Expand Up @@ -196,27 +199,8 @@ private static void CopyIl2CppDataToManagedType(Il2CppTypeDefinition cppTypeDefi
ilTypeDefinition.CustomAttributes.Add(customTokenAttribute);
}

if (cppTypeDefinition.GenericContainer != null)
{
//Type generic params.
foreach (var param in cppTypeDefinition.GenericContainer.GenericParameters)
{
if (!SharedState.GenericParamsByIndex.TryGetValue(param.Index, out var p))
{
p = new GenericParameter(param.Name, ilTypeDefinition).WithFlags(param.flags);
SharedState.GenericParamsByIndex[param.Index] = p;

ilTypeDefinition.GenericParameters.Add(p);

param.ConstraintTypes!
.Select(c => new GenericParameterConstraint(Utils.ImportTypeInto(ilTypeDefinition, c)))
.ToList()
.ForEach(p.Constraints.Add);
}
else if (!ilTypeDefinition.GenericParameters.Contains(p))
ilTypeDefinition.GenericParameters.Add(p);
}
}
//Type generic params.
// PopulateGenericParamsForType(cppTypeDefinition, ilTypeDefinition);

//Fields
ProcessFieldsInType(cppTypeDefinition, ilTypeDefinition, stringType, fieldOffsetAttribute, tokenAttribute);
Expand All @@ -231,6 +215,30 @@ private static void CopyIl2CppDataToManagedType(Il2CppTypeDefinition cppTypeDefi
ProcessEventsInType(cppTypeDefinition, ilTypeDefinition, tokenAttribute, stringType);
}

private static void PopulateGenericParamsForType(Il2CppTypeDefinition cppTypeDefinition, TypeDefinition ilTypeDefinition)
{
if (cppTypeDefinition.GenericContainer == null)
return;

foreach (var param in cppTypeDefinition.GenericContainer.GenericParameters)
{
if (!SharedState.GenericParamsByIndex.TryGetValue(param.Index, out var p))
{
p = new GenericParameter(param.Name, ilTypeDefinition).WithFlags(param.flags);
SharedState.GenericParamsByIndex[param.Index] = p;

ilTypeDefinition.GenericParameters.Add(p);

param.ConstraintTypes!
.Select(c => new GenericParameterConstraint(Utils.ImportTypeInto(ilTypeDefinition, c)))
.ToList()
.ForEach(p.Constraints.Add);
}
else if (!ilTypeDefinition.GenericParameters.Contains(p))
ilTypeDefinition.GenericParameters.Add(p);
}
}

private static (MethodDefinition addressAttribute, MethodDefinition fieldOffsetAttribute, MethodDefinition tokenAttribute) GetInjectedAttributes(TypeDefinition ilTypeDefinition)
{
MethodDefinition addressAttribute;
Expand Down

0 comments on commit 9726ab4

Please sign in to comment.