Browse Source

Pulled correction stuff out into its own file

pull/44/head
Anairkoen Schno 4 years ago
parent
commit
e186cf634e
3 changed files with 92 additions and 70 deletions
  1. +91
    -0
      IPA.Loader/Config/Stores/GeneratedStoreImpl/Correction.cs
  2. +0
    -70
      IPA.Loader/Config/Stores/GeneratedStoreImpl/MakeCreator.cs
  3. +1
    -0
      IPA.Loader/IPA.Loader.csproj

+ 91
- 0
IPA.Loader/Config/Stores/GeneratedStoreImpl/Correction.cs View File

@ -0,0 +1,91 @@
using IPA.Config.Data;
using IPA.Config.Stores.Attributes;
using IPA.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
#if NET3
using Net3_Proxy;
using Array = Net3_Proxy.Array;
#endif
namespace IPA.Config.Stores
{
internal static partial class GeneratedStoreImpl
{
private static bool NeedsCorrection(SerializedMemberInfo member)
{
if (member.HasConverter) return false;
var memberType = member.ConversionType;
var expectType = GetExpectedValueTypeForType(memberType);
if (expectType == typeof(Map)) // TODO: make this slightly saner
return true;
return false;
}
// expects start value on stack, exits with final value on stack
private static void EmitCorrectMember(ILGenerator il, SerializedMemberInfo member, bool shouldLock, bool alwaysNew, GetLocal GetLocal,
Action<ILGenerator> thisobj, Action<ILGenerator> parentobj)
{
if (!NeedsCorrection(member)) return;
var endLabel = il.DefineLabel();
if (member.IsNullable)
{
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Call, member.Nullable_HasValue.GetGetMethod());
il.Emit(OpCodes.Brfalse, endLabel);
il.Emit(OpCodes.Call, member.Nullable_Value.GetGetMethod());
}
if (!member.ConversionType.IsValueType)
{
// currently the only thing for this is where expect == Map, so do generate shit
var copyFrom = typeof(IGeneratedStore<>).MakeGenericType(member.ConversionType).GetMethod(nameof(IGeneratedStore<Config>.CopyFrom));
var noCreate = il.DefineLabel();
var valLocal = GetLocal(member.Type);
if (!alwaysNew)
{
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Isinst, typeof(IGeneratedStore));
il.Emit(OpCodes.Brtrue_S, endLabel); // our input is already something we like
}
il.Emit(OpCodes.Stloc, valLocal);
if (!alwaysNew)
{
EmitLoad(il, member, thisobj);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Isinst, typeof(IGeneratedStore));
il.Emit(OpCodes.Brtrue_S, noCreate);
il.Emit(OpCodes.Pop);
}
EmitCreateChildGenerated(il, member.Type, parentobj);
il.MarkLabel(noCreate);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldloc, valLocal);
il.Emit(shouldLock ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Callvirt, copyFrom);
}
else
{
// TODO: impl the rest of this
}
if (member.IsNullable)
il.Emit(OpCodes.Newobj, member.Nullable_Construct);
il.MarkLabel(endLabel);
}
}
}

+ 0
- 70
IPA.Loader/Config/Stores/GeneratedStoreImpl/MakeCreator.cs View File

@ -745,75 +745,5 @@ namespace IPA.Config.Stores
return (creatorDel, genType); return (creatorDel, genType);
} }
#region Correction
private static bool NeedsCorrection(SerializedMemberInfo member)
{
if (member.HasConverter) return false;
var memberType = member.ConversionType;
var expectType = GetExpectedValueTypeForType(memberType);
if (expectType == typeof(Map)) // TODO: make this slightly saner
return true;
return false;
}
// expects start value on stack, exits with final value on stack
private static void EmitCorrectMember(ILGenerator il, SerializedMemberInfo member, bool shouldLock, bool alwaysNew, GetLocal GetLocal,
Action<ILGenerator> thisobj, Action<ILGenerator> parentobj)
{
if (!NeedsCorrection(member)) return;
var endLabel = il.DefineLabel();
if (member.IsNullable)
{
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Call, member.Nullable_HasValue.GetGetMethod());
il.Emit(OpCodes.Brfalse, endLabel);
il.Emit(OpCodes.Call, member.Nullable_Value.GetGetMethod());
}
if (!member.ConversionType.IsValueType)
{
// currently the only thing for this is where expect == Map, so do generate shit
var copyFrom = typeof(IGeneratedStore<>).MakeGenericType(member.ConversionType).GetMethod(nameof(IGeneratedStore<Config>.CopyFrom));
var noCreate = il.DefineLabel();
var valLocal = GetLocal(member.Type);
if (!alwaysNew)
{
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Isinst, typeof(IGeneratedStore));
il.Emit(OpCodes.Brtrue_S, endLabel); // our input is already something we like
}
il.Emit(OpCodes.Stloc, valLocal);
if (!alwaysNew)
{
EmitLoad(il, member, thisobj);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Isinst, typeof(IGeneratedStore));
il.Emit(OpCodes.Brtrue_S, noCreate);
il.Emit(OpCodes.Pop);
}
EmitCreateChildGenerated(il, member.Type, parentobj);
il.MarkLabel(noCreate);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldloc, valLocal);
il.Emit(shouldLock ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Callvirt, copyFrom);
}
else
{
// TODO: impl the rest of this
}
if (member.IsNullable)
il.Emit(OpCodes.Newobj, member.Nullable_Construct);
il.MarkLabel(endLabel);
}
#endregion
} }
} }

+ 1
- 0
IPA.Loader/IPA.Loader.csproj View File

@ -103,6 +103,7 @@
<Compile Include="Config\Stores\Converters.cs" /> <Compile Include="Config\Stores\Converters.cs" />
<Compile Include="Config\Stores\CustomObjectConverter.cs" /> <Compile Include="Config\Stores\CustomObjectConverter.cs" />
<Compile Include="Config\Stores\CollectionConverter.cs" /> <Compile Include="Config\Stores\CollectionConverter.cs" />
<Compile Include="Config\Stores\GeneratedStoreImpl\Correction.cs" />
<Compile Include="Config\Stores\GeneratedStoreImpl\Deserialization.cs" /> <Compile Include="Config\Stores\GeneratedStoreImpl\Deserialization.cs" />
<Compile Include="Config\Stores\GeneratedStoreImpl\GeneratedStoreImpl.cs" /> <Compile Include="Config\Stores\GeneratedStoreImpl\GeneratedStoreImpl.cs" />
<Compile Include="Config\Stores\GeneratedStoreCollections.cs" /> <Compile Include="Config\Stores\GeneratedStoreCollections.cs" />


Loading…
Cancel
Save