Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Reflection;
using Cpp2IL.Core.Utils;
using LibCpp2IL;

namespace Cpp2IL.Core.Model.Contexts;

Expand All @@ -9,8 +10,8 @@ public class ConcreteGenericFieldAnalysisContext : FieldAnalysisContext
public FieldAnalysisContext BaseFieldContext { get; }
public override FieldAttributes DefaultAttributes => BaseFieldContext.DefaultAttributes;
public override FieldAttributes? OverrideAttributes { get => BaseFieldContext.OverrideAttributes; set => BaseFieldContext.OverrideAttributes = value; }
public override object? DefaultConstantValue => BaseFieldContext.DefaultConstantValue;
public override object? OverrideConstantValue { get => BaseFieldContext.OverrideConstantValue; set => BaseFieldContext.OverrideConstantValue = value; }
public override DefaultValue? DefaultConstantValue => BaseFieldContext.DefaultConstantValue;
public override DefaultValue? OverrideConstantValue { get => BaseFieldContext.OverrideConstantValue; set => BaseFieldContext.OverrideConstantValue = value; }
public override int DefaultOffset => BaseFieldContext.DefaultOffset;
public override int? OverrideOffset { get => BaseFieldContext.OverrideOffset; set => BaseFieldContext.OverrideOffset = value; }
public override byte[] DefaultStaticArrayInitialValue => BaseFieldContext.DefaultStaticArrayInitialValue;
Expand Down
7 changes: 4 additions & 3 deletions Cpp2IL.Core/Model/Contexts/FieldAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Reflection;
using Cpp2IL.Core.Utils;
using LibCpp2IL;
using LibCpp2IL.BinaryStructures;
using LibCpp2IL.Reflection;
using StableNameDotNet.Providers;
Expand Down Expand Up @@ -43,11 +44,11 @@ public FieldAttributes Attributes

public bool IsStatic => (Attributes & FieldAttributes.Static) != 0;

public virtual object? DefaultConstantValue => BackingData?.Field.DefaultValue?.Value;
public virtual DefaultValue? DefaultConstantValue => BackingData?.Field.DefaultValue?.Value;

public virtual object? OverrideConstantValue { get; set; }
public virtual DefaultValue? OverrideConstantValue { get; set; }

public object? ConstantValue
public DefaultValue? ConstantValue
{
get => OverrideConstantValue ?? DefaultConstantValue;
set => OverrideConstantValue = value;
Expand Down
20 changes: 10 additions & 10 deletions Cpp2IL.Core/Model/Contexts/ParameterAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,17 @@ public override string ToString()
else
result.Append(ParameterName);

if (Attributes.HasFlag(ParameterAttributes.HasDefault))
if (Attributes.HasFlag(ParameterAttributes.HasDefault) && DefaultValue?.ContainedDefaultValue is { } defaultValue)
{
var defaultValue = DefaultValue!.ContainedDefaultValue;
if (defaultValue is string stringDefaultValue)
defaultValue = $"\"{stringDefaultValue}\"";
else if (defaultValue is bool boolDefaultValue)
defaultValue = boolDefaultValue.ToString().ToLowerInvariant();
else if (defaultValue is null)
defaultValue = "null";

result.Append(" = ").Append(defaultValue);
string defaultValueString;
if (defaultValue.Value is string stringDefaultValue)
defaultValueString = $"\"{stringDefaultValue}\"";
else if (defaultValue.Value is bool boolDefaultValue)
defaultValueString = boolDefaultValue.ToString().ToLowerInvariant();
else
defaultValueString = defaultValue.ToString();

result.Append(" = ").Append(defaultValueString);
}

return result.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public CustomAttributeEnumParameter(Il2CppType enumType, ApplicationAnalysisCont
public override string ToString()
{
var enumTypeDef = EnumType.AsClass();
var matchingField = enumTypeDef.Fields?.FirstOrDefault(f => Equals(f.DefaultValue?.Value, UnderlyingPrimitiveParameter.PrimitiveValue));
var matchingField = enumTypeDef.Fields?.FirstOrDefault(f => Equals(f.DefaultValue?.Value?.Value, UnderlyingPrimitiveParameter.PrimitiveValue));

if (matchingField != null)
return $"{enumTypeDef.Name}::{matchingField.Name} ({UnderlyingPrimitiveParameter.PrimitiveValue})";
Expand Down
12 changes: 6 additions & 6 deletions Cpp2IL.Core/OutputFormats/DiffableCsOutputFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private static void AppendType(StringBuilder sb, TypeAnalysisContext type, int i
sb.Append('\t', indent);
sb.Append(enumValue.Name);
sb.Append(" = ");
sb.Append(InvariantValue(enumValue.BackingData!.DefaultValue));
sb.Append(InvariantValue(enumValue.ConstantValue?.Value));
sb.Append(',');
sb.AppendLine();
}
Expand Down Expand Up @@ -191,16 +191,16 @@ private static void AppendField(StringBuilder sb, FieldAnalysisContext field, in
}
}

if (field.BackingData?.DefaultValue is { } defaultValue)
if (field.ConstantValue is { } defaultValue)
{
sb.Append(" = ");

if (defaultValue is string stringDefaultValue)
if (defaultValue.Value is string stringDefaultValue)
sb.Append('"').Append(stringDefaultValue).Append('"');
else if (defaultValue is char charDefaultValue)
else if (defaultValue.Value is char charDefaultValue)
sb.Append("'\\u").Append(((int)charDefaultValue).ToString("X")).Append("'");
else
sb.Append(InvariantValue(defaultValue));
sb.Append(InvariantValue(defaultValue.Value));
}

sb.Append("; //Field offset: 0x");
Expand Down Expand Up @@ -401,5 +401,5 @@ private static void AppendCustomAttributes(StringBuilder sb, HasCustomAttributes
=> sb.Append(CsFileUtils.GetCustomAttributeStrings(owner, indent, true, true));

private static string InvariantValue(object? value)
=> value is null ? "" : value is IFormattable f ? f.ToString(null, CultureInfo.InvariantCulture) : value.ToString() ?? "";
=> value is null ? "null" : value is IFormattable f ? f.ToString(null, CultureInfo.InvariantCulture) : value.ToString() ?? "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public override void Process(ApplicationAnalysisContext appContext, Action<int,
if (!StableNameGenerator.IsObfuscated(field.Name))
continue;

field.OverrideName = $"EnumValue" + field.BackingData!.DefaultValue;
field.OverrideName = $"EnumValue{field.ConstantValue}";
}
}

Expand Down
9 changes: 2 additions & 7 deletions Cpp2IL.Core/Utils/AsmResolver/AsmResolverAssemblyPopulator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ private static void CopyFieldsInType(ReferenceImporter importer, TypeAnalysisCon

//Field default values
if (managedField.HasDefault && fieldContext.ConstantValue is { } constVal)
managedField.Constant = AsmResolverConstants.GetOrCreateConstant(constVal);
managedField.Constant = AsmResolverConstants.GetOrCreateConstant(constVal.Value);

//Field Initial Values (used for allocation of Array Literals)
if (managedField.HasFieldRva)
Expand Down Expand Up @@ -389,12 +389,7 @@ private static void CopyMethodsInType(ReferenceImporter importer, TypeAnalysisCo
continue;

if (defaultValueData?.ContainedDefaultValue is { } constVal)
parameterDefinitions[i].Constant = AsmResolverConstants.GetOrCreateConstant(constVal);
else if (defaultValueData is { dataIndex.IsNull: true })
{
//Literal null
parameterDefinitions[i].Constant = AsmResolverConstants.Null;
}
parameterDefinitions[i].Constant = AsmResolverConstants.GetOrCreateConstant(constVal.Value);
}


Expand Down
11 changes: 5 additions & 6 deletions Cpp2IL.Core/Utils/AsmResolver/AsmResolverConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Cpp2IL.Core.Utils.AsmResolver;

public static class AsmResolverConstants
{
public static readonly Constant Null = Constant.FromNull();
private static readonly Constant Null = Constant.FromNull();

private static readonly Dictionary<int, Constant> IntegerCache = new();
private static readonly Dictionary<byte, Constant> ByteCache = new();
Expand All @@ -27,10 +27,11 @@ static AsmResolverConstants()
}
}

public static Constant GetOrCreateConstant(object from)
public static Constant GetOrCreateConstant(object? from)
{
return from switch
{
null => Null,
string s => new(ElementType.String, new(Encoding.Unicode.GetBytes(s))),
bool b => b ? BoolTrue : BoolFalse,
byte and >= 0 and < 16 => ByteCache[(byte)@from],
Expand All @@ -45,10 +46,8 @@ private static Constant CreateNewConstant(IConvertible from)
return new(GetElementTypeFromConstant(from), new(MiscUtils.RawBytes(from)));
}

private static ElementType GetElementTypeFromConstant(object? primitive)
=> primitive is null
? ElementType.Object
: primitive switch
private static ElementType GetElementTypeFromConstant(IConvertible primitive)
=> primitive switch
{
sbyte => ElementType.I1,
byte => ElementType.U1,
Expand Down
25 changes: 25 additions & 0 deletions LibCpp2IL/DefaultValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace LibCpp2IL;

public readonly record struct DefaultValue(object? Value)
{
public static DefaultValue Null => new(null);

public static implicit operator DefaultValue(sbyte value) => new(value);
public static implicit operator DefaultValue(byte value) => new(value);
public static implicit operator DefaultValue(short value) => new(value);
public static implicit operator DefaultValue(ushort value) => new(value);
public static implicit operator DefaultValue(int value) => new(value);
public static implicit operator DefaultValue(uint value) => new(value);
public static implicit operator DefaultValue(long value) => new(value);
public static implicit operator DefaultValue(ulong value) => new(value);
public static implicit operator DefaultValue(float value) => new(value);
public static implicit operator DefaultValue(double value) => new(value);
public static implicit operator DefaultValue(bool value) => new(value);
public static implicit operator DefaultValue(char value) => new(value);
public static implicit operator DefaultValue(string? value) => new(value);

public override string ToString()
{
return Value is null ? "null" : Value.ToString() ?? "";
}
}
4 changes: 2 additions & 2 deletions LibCpp2IL/LibCpp2IlUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,12 @@ public static string GetTypeName(LibCpp2IlContext context, Il2CppType type, bool
return ret;
}

internal static object? GetDefaultValue(Il2CppVariableWidthIndex<Il2CppDefaultValueDataDummy> dataIndex, Il2CppVariableWidthIndex<Il2CppType> typeIndex, LibCpp2IlContext context)
internal static DefaultValue? GetDefaultValue(Il2CppVariableWidthIndex<Il2CppDefaultValueDataDummy> dataIndex, Il2CppVariableWidthIndex<Il2CppType> typeIndex, LibCpp2IlContext context)
{
var metadata = context.Metadata;

if (dataIndex.IsNull)
return null; //Literally null.
return DefaultValue.Null;

var pointer = metadata.GetDefaultValueFromIndex(dataIndex);
if (pointer <= 0) return null;
Expand Down
2 changes: 1 addition & 1 deletion LibCpp2IL/Metadata/Il2CppFieldDefaultValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class Il2CppFieldDefaultValue : ReadableClass
public Il2CppVariableWidthIndex<Il2CppType> typeIndex;
public Il2CppVariableWidthIndex<Il2CppDefaultValueDataDummy> dataIndex;

public object? Value => dataIndex.IsNull ? null : LibCpp2ILUtils.GetDefaultValue(dataIndex, typeIndex, OwningContext);
public DefaultValue? Value => LibCpp2ILUtils.GetDefaultValue(dataIndex, typeIndex, OwningContext);

public override void Read(ClassReadingBinaryReader reader)
{
Expand Down
2 changes: 1 addition & 1 deletion LibCpp2IL/Metadata/Il2CppParameterDefaultValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class Il2CppParameterDefaultValue : ReadableClass
public Il2CppVariableWidthIndex<Il2CppType> typeIndex;
public Il2CppVariableWidthIndex<Il2CppDefaultValueDataDummy> dataIndex;

public object? ContainedDefaultValue => LibCpp2ILUtils.GetDefaultValue(dataIndex, typeIndex, OwningContext);
public DefaultValue? ContainedDefaultValue => LibCpp2ILUtils.GetDefaultValue(dataIndex, typeIndex, OwningContext);

public override void Read(ClassReadingBinaryReader reader)
{
Expand Down
6 changes: 3 additions & 3 deletions LibCpp2IL/Metadata/Il2CppTypeDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public Il2CppFieldDefinition[]? Fields
.Select(t => (FieldAttributes)t.Attrs)
.ToArray();

public object?[]? FieldDefaults => Fields?
public DefaultValue?[]? FieldDefaults => Fields?
.Select((f, idx) => (f.FieldIndex, FieldAttributes![idx]))
.Select(tuple => (tuple.Item2 & System.Reflection.FieldAttributes.HasDefault) != 0 ? OwningContext.Metadata.GetFieldDefaultValueFromIndex(tuple.FieldIndex) : null)
.Select(def => def == null ? null : LibCpp2ILUtils.GetDefaultValue(def.dataIndex, def.typeIndex, OwningContext))
Expand All @@ -257,8 +257,8 @@ public Il2CppFieldReflectionData[]? FieldInfos
{
ret[i] = new(
fields[i],
attributes![i],
defaults![i],
attributes[i],
defaults[i],
i,
OwningContext.Binary.GetFieldOffsetFromIndex(TypeIndex, i, fields[i].FieldIndex, IsValueType, attributes[i].HasFlag(System.Reflection.FieldAttributes.Static))
);
Expand Down
6 changes: 3 additions & 3 deletions LibCpp2IL/Reflection/Il2CppFieldReflectionData.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
using System.Reflection;
using System.Reflection;
using LibCpp2IL.Metadata;

namespace LibCpp2IL.Reflection;

public class Il2CppFieldReflectionData(
Il2CppFieldDefinition field,
FieldAttributes attributes,
object? defaultValue,
DefaultValue? defaultValue,
int indexInParent,
int fieldOffset)
{
public Il2CppFieldDefinition Field = field;
public FieldAttributes Attributes = attributes;
public object? DefaultValue = defaultValue;
public DefaultValue? DefaultValue = defaultValue;
public int IndexInParent = indexInParent;
public int FieldOffset = fieldOffset;
}
8 changes: 4 additions & 4 deletions LibCpp2IL/Reflection/Il2CppParameterReflectionData.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Reflection;
using System.Reflection;
using System.Text;
using LibCpp2IL.BinaryStructures;

Expand All @@ -11,7 +11,7 @@ public class Il2CppParameterReflectionData
public Il2CppType RawType;
public Il2CppTypeReflectionData Type;
public ParameterAttributes Attributes;
public object? DefaultValue;
public DefaultValue? DefaultValue;
public int ParameterIndex;

public bool IsRefOrOut => Attributes.HasFlag(ParameterAttributes.Out) || RawType.Byref == 1;
Expand All @@ -34,8 +34,8 @@ public override string ToString()
else
result.Append(ParameterName);

if (Attributes.HasFlag(ParameterAttributes.HasDefault))
result.Append(" = ").Append(DefaultValue ?? "null");
if (Attributes.HasFlag(ParameterAttributes.HasDefault) && DefaultValue != null)
result.Append(" = ").Append(DefaultValue.ToString());

return result.ToString();
}
Expand Down
Loading