Browse Source

Devirutalized converter calls in generated code

pull/46/head
Anairkoen Schno 5 years ago
parent
commit
1b0c44cbaf
1 changed files with 19 additions and 11 deletions
  1. +19
    -11
      IPA.Loader/Config/Stores/GeneratedStore.cs

+ 19
- 11
IPA.Loader/Config/Stores/GeneratedStore.cs View File

@ -1256,18 +1256,22 @@ namespace IPA.Config.Stores
if (member.IsGenericConverter) if (member.IsGenericConverter)
{ {
var toValue = member.ConverterBase.GetMethod(nameof(ValueConverter<int>.ToValue),
var toValueBase = member.ConverterBase.GetMethod(nameof(ValueConverter<int>.ToValue),
new[] { member.ConverterTarget, typeof(object) }); new[] { member.ConverterTarget, typeof(object) });
var toValue = member.Converter.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.FirstOrDefault(m => m.GetBaseDefinition() == toValueBase) ?? toValueBase;
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Callvirt, toValue); // TODO: figure out how to devirtualize this
il.Emit(OpCodes.Call, toValue);
} }
else else
{ {
var toValue = typeof(IValueConverter).GetMethod(nameof(IValueConverter.ToValue),
var toValueBase = typeof(IValueConverter).GetMethod(nameof(IValueConverter.ToValue),
new[] { typeof(object), typeof(object) }); new[] { typeof(object), typeof(object) });
il.Emit(OpCodes.Box);
var toValue = member.Converter.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.FirstOrDefault(m => m.GetBaseDefinition() == toValueBase) ?? toValueBase;
il.Emit(OpCodes.Box);
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Callvirt, toValue);
il.Emit(OpCodes.Call, toValue);
} }
il.Emit(OpCodes.Stloc, valLocal); il.Emit(OpCodes.Stloc, valLocal);
@ -1438,15 +1442,19 @@ namespace IPA.Config.Stores
if (member.IsGenericConverter) if (member.IsGenericConverter)
{ {
var fromValue = member.ConverterBase.GetMethod(nameof(ValueConverter<int>.FromValue),
new[] { typeof(Value), typeof(object) });
il.Emit(OpCodes.Callvirt, fromValue);
var fromValueBase = member.ConverterBase.GetMethod(nameof(ValueConverter<int>.FromValue),
new[] { typeof(Value), typeof(object) });
var fromValue = member.Converter.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.FirstOrDefault(m => m.GetBaseDefinition() == fromValueBase) ?? fromValueBase;
il.Emit(OpCodes.Call, fromValue);
} }
else else
{ {
var fromValue = typeof(IValueConverter).GetMethod(nameof(IValueConverter.FromValue),
new[] { typeof(Value), typeof(object) });
il.Emit(OpCodes.Callvirt, fromValue);
var fromValueBase = typeof(IValueConverter).GetMethod(nameof(IValueConverter.FromValue),
new[] { typeof(Value), typeof(object) });
var fromValue = member.Converter.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.FirstOrDefault(m => m.GetBaseDefinition() == fromValueBase) ?? fromValueBase;
il.Emit(OpCodes.Call, fromValue);
if (member.Type.IsValueType) if (member.Type.IsValueType)
il.Emit(OpCodes.Unbox); il.Emit(OpCodes.Unbox);
} }


Loading…
Cancel
Save