Merge pull request #164 from dwango/work_aot

Reduce Expression.Compile
This commit is contained in:
ousttrue 2019-02-02 15:51:27 +09:00 committed by GitHub
commit 1e7c340efa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 868 additions and 130 deletions

View File

@ -83,6 +83,8 @@ namespace UniJSON
SerializeValue(HogeFuga.Fuga, "1");
SerializeValue(new EnumTest(), "{\"EnumDefault\":0,\"EnumAsInt\":0,\"EnumAsString\":\"Hoge\",\"EnumAsLowerString\":\"hoge\"}");
SerializeValue((object)new Point { X = 1 }, "{\"X\":1,\"Y\":0}");
}
[Test]

View File

@ -0,0 +1,85 @@
using System;
using System.IO;
using System.Text;
using UnityEngine;
using System.Reflection;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniJSON
{
public static partial class ConcreteCast
{
public static string GetMethodName(Type src, Type dst)
{
return string.Format("Cast{0}To{1}", src.Name, dst.Name);
}
public static MethodInfo GetMethod(Type src, Type dst)
{
var name = GetMethodName(src, dst);
var mi = typeof(ConcreteCast).GetMethod(name,
BindingFlags.Static | BindingFlags.Public);
return mi;
}
#if UNITY_EDITOR
static Type[] s_castTypes = new Type[]
{
typeof(byte),
typeof(ushort),
typeof(uint),
typeof(ulong),
typeof(sbyte),
typeof(short),
typeof(int),
typeof(long),
typeof(float),
typeof(double),
};
[MenuItem(UniGLTF.UniGLTFVersion.MENU + "/Generate ConcreteCast")]
public static void GenerateGenericCast()
{
var s = new StringBuilder();
using (var w = new StringWriter(s))
{
w.WriteLine(@"
using System;
namespace UniJSON {
public static partial class ConcreteCast
{
");
foreach (var x in s_castTypes)
{
foreach (var y in s_castTypes)
{
w.WriteLine(@"
public static $1 $2($0 src)
{
return ($1)src;
}
".Replace("$0", x.Name).Replace("$1", y.Name).Replace("$2", GetMethodName(x, y)));
}
}
w.WriteLine(@"
}
}
");
}
var path = Application.dataPath + SOURCE;
Debug.LogFormat("{0}", path);
File.WriteAllText(path, s.ToString().Replace("\r\n", "\n"), new UTF8Encoding(false));
AssetDatabase.ImportAsset("Assets" + SOURCE);
}
const string SOURCE = "/VRM/UniJSON/Scripts/ConcreteCast.g.cs";
#endif
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7c7697929e4510048a5238dd9d227b2e
timeCreated: 1549025672
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,611 @@
using System;
namespace UniJSON {
public static partial class ConcreteCast
{
public static Byte CastByteToByte(Byte src)
{
return (Byte)src;
}
public static UInt16 CastByteToUInt16(Byte src)
{
return (UInt16)src;
}
public static UInt32 CastByteToUInt32(Byte src)
{
return (UInt32)src;
}
public static UInt64 CastByteToUInt64(Byte src)
{
return (UInt64)src;
}
public static SByte CastByteToSByte(Byte src)
{
return (SByte)src;
}
public static Int16 CastByteToInt16(Byte src)
{
return (Int16)src;
}
public static Int32 CastByteToInt32(Byte src)
{
return (Int32)src;
}
public static Int64 CastByteToInt64(Byte src)
{
return (Int64)src;
}
public static Single CastByteToSingle(Byte src)
{
return (Single)src;
}
public static Double CastByteToDouble(Byte src)
{
return (Double)src;
}
public static Byte CastUInt16ToByte(UInt16 src)
{
return (Byte)src;
}
public static UInt16 CastUInt16ToUInt16(UInt16 src)
{
return (UInt16)src;
}
public static UInt32 CastUInt16ToUInt32(UInt16 src)
{
return (UInt32)src;
}
public static UInt64 CastUInt16ToUInt64(UInt16 src)
{
return (UInt64)src;
}
public static SByte CastUInt16ToSByte(UInt16 src)
{
return (SByte)src;
}
public static Int16 CastUInt16ToInt16(UInt16 src)
{
return (Int16)src;
}
public static Int32 CastUInt16ToInt32(UInt16 src)
{
return (Int32)src;
}
public static Int64 CastUInt16ToInt64(UInt16 src)
{
return (Int64)src;
}
public static Single CastUInt16ToSingle(UInt16 src)
{
return (Single)src;
}
public static Double CastUInt16ToDouble(UInt16 src)
{
return (Double)src;
}
public static Byte CastUInt32ToByte(UInt32 src)
{
return (Byte)src;
}
public static UInt16 CastUInt32ToUInt16(UInt32 src)
{
return (UInt16)src;
}
public static UInt32 CastUInt32ToUInt32(UInt32 src)
{
return (UInt32)src;
}
public static UInt64 CastUInt32ToUInt64(UInt32 src)
{
return (UInt64)src;
}
public static SByte CastUInt32ToSByte(UInt32 src)
{
return (SByte)src;
}
public static Int16 CastUInt32ToInt16(UInt32 src)
{
return (Int16)src;
}
public static Int32 CastUInt32ToInt32(UInt32 src)
{
return (Int32)src;
}
public static Int64 CastUInt32ToInt64(UInt32 src)
{
return (Int64)src;
}
public static Single CastUInt32ToSingle(UInt32 src)
{
return (Single)src;
}
public static Double CastUInt32ToDouble(UInt32 src)
{
return (Double)src;
}
public static Byte CastUInt64ToByte(UInt64 src)
{
return (Byte)src;
}
public static UInt16 CastUInt64ToUInt16(UInt64 src)
{
return (UInt16)src;
}
public static UInt32 CastUInt64ToUInt32(UInt64 src)
{
return (UInt32)src;
}
public static UInt64 CastUInt64ToUInt64(UInt64 src)
{
return (UInt64)src;
}
public static SByte CastUInt64ToSByte(UInt64 src)
{
return (SByte)src;
}
public static Int16 CastUInt64ToInt16(UInt64 src)
{
return (Int16)src;
}
public static Int32 CastUInt64ToInt32(UInt64 src)
{
return (Int32)src;
}
public static Int64 CastUInt64ToInt64(UInt64 src)
{
return (Int64)src;
}
public static Single CastUInt64ToSingle(UInt64 src)
{
return (Single)src;
}
public static Double CastUInt64ToDouble(UInt64 src)
{
return (Double)src;
}
public static Byte CastSByteToByte(SByte src)
{
return (Byte)src;
}
public static UInt16 CastSByteToUInt16(SByte src)
{
return (UInt16)src;
}
public static UInt32 CastSByteToUInt32(SByte src)
{
return (UInt32)src;
}
public static UInt64 CastSByteToUInt64(SByte src)
{
return (UInt64)src;
}
public static SByte CastSByteToSByte(SByte src)
{
return (SByte)src;
}
public static Int16 CastSByteToInt16(SByte src)
{
return (Int16)src;
}
public static Int32 CastSByteToInt32(SByte src)
{
return (Int32)src;
}
public static Int64 CastSByteToInt64(SByte src)
{
return (Int64)src;
}
public static Single CastSByteToSingle(SByte src)
{
return (Single)src;
}
public static Double CastSByteToDouble(SByte src)
{
return (Double)src;
}
public static Byte CastInt16ToByte(Int16 src)
{
return (Byte)src;
}
public static UInt16 CastInt16ToUInt16(Int16 src)
{
return (UInt16)src;
}
public static UInt32 CastInt16ToUInt32(Int16 src)
{
return (UInt32)src;
}
public static UInt64 CastInt16ToUInt64(Int16 src)
{
return (UInt64)src;
}
public static SByte CastInt16ToSByte(Int16 src)
{
return (SByte)src;
}
public static Int16 CastInt16ToInt16(Int16 src)
{
return (Int16)src;
}
public static Int32 CastInt16ToInt32(Int16 src)
{
return (Int32)src;
}
public static Int64 CastInt16ToInt64(Int16 src)
{
return (Int64)src;
}
public static Single CastInt16ToSingle(Int16 src)
{
return (Single)src;
}
public static Double CastInt16ToDouble(Int16 src)
{
return (Double)src;
}
public static Byte CastInt32ToByte(Int32 src)
{
return (Byte)src;
}
public static UInt16 CastInt32ToUInt16(Int32 src)
{
return (UInt16)src;
}
public static UInt32 CastInt32ToUInt32(Int32 src)
{
return (UInt32)src;
}
public static UInt64 CastInt32ToUInt64(Int32 src)
{
return (UInt64)src;
}
public static SByte CastInt32ToSByte(Int32 src)
{
return (SByte)src;
}
public static Int16 CastInt32ToInt16(Int32 src)
{
return (Int16)src;
}
public static Int32 CastInt32ToInt32(Int32 src)
{
return (Int32)src;
}
public static Int64 CastInt32ToInt64(Int32 src)
{
return (Int64)src;
}
public static Single CastInt32ToSingle(Int32 src)
{
return (Single)src;
}
public static Double CastInt32ToDouble(Int32 src)
{
return (Double)src;
}
public static Byte CastInt64ToByte(Int64 src)
{
return (Byte)src;
}
public static UInt16 CastInt64ToUInt16(Int64 src)
{
return (UInt16)src;
}
public static UInt32 CastInt64ToUInt32(Int64 src)
{
return (UInt32)src;
}
public static UInt64 CastInt64ToUInt64(Int64 src)
{
return (UInt64)src;
}
public static SByte CastInt64ToSByte(Int64 src)
{
return (SByte)src;
}
public static Int16 CastInt64ToInt16(Int64 src)
{
return (Int16)src;
}
public static Int32 CastInt64ToInt32(Int64 src)
{
return (Int32)src;
}
public static Int64 CastInt64ToInt64(Int64 src)
{
return (Int64)src;
}
public static Single CastInt64ToSingle(Int64 src)
{
return (Single)src;
}
public static Double CastInt64ToDouble(Int64 src)
{
return (Double)src;
}
public static Byte CastSingleToByte(Single src)
{
return (Byte)src;
}
public static UInt16 CastSingleToUInt16(Single src)
{
return (UInt16)src;
}
public static UInt32 CastSingleToUInt32(Single src)
{
return (UInt32)src;
}
public static UInt64 CastSingleToUInt64(Single src)
{
return (UInt64)src;
}
public static SByte CastSingleToSByte(Single src)
{
return (SByte)src;
}
public static Int16 CastSingleToInt16(Single src)
{
return (Int16)src;
}
public static Int32 CastSingleToInt32(Single src)
{
return (Int32)src;
}
public static Int64 CastSingleToInt64(Single src)
{
return (Int64)src;
}
public static Single CastSingleToSingle(Single src)
{
return (Single)src;
}
public static Double CastSingleToDouble(Single src)
{
return (Double)src;
}
public static Byte CastDoubleToByte(Double src)
{
return (Byte)src;
}
public static UInt16 CastDoubleToUInt16(Double src)
{
return (UInt16)src;
}
public static UInt32 CastDoubleToUInt32(Double src)
{
return (UInt32)src;
}
public static UInt64 CastDoubleToUInt64(Double src)
{
return (UInt64)src;
}
public static SByte CastDoubleToSByte(Double src)
{
return (SByte)src;
}
public static Int16 CastDoubleToInt16(Double src)
{
return (Int16)src;
}
public static Int32 CastDoubleToInt32(Double src)
{
return (Int32)src;
}
public static Int64 CastDoubleToInt64(Double src)
{
return (Int64)src;
}
public static Single CastDoubleToSingle(Double src)
{
return (Single)src;
}
public static Double CastDoubleToDouble(Double src)
{
return (Double)src;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d15ce8227d1aec64ab3fd82c4b271747
timeCreated: 1549025426
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -45,6 +45,7 @@ namespace UniJSON
return method.MakeGenericMethod(typeof(T));
}
[Obsolete("error when AOT. use Key, Value")]
public static void KeyValue<T>(this IFormatter f, Expression<Func<T>> expression)
{
var func = expression.Compile();

View File

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace UniJSON
{
public static class FormatterExtensionsSerializer
@ -67,6 +67,11 @@ namespace UniJSON
{
GenericSerializer<T>.Set(serializer);
}
public static MethodInfo GetMethod(string name)
{
return typeof(FormatterExtensionsSerializer).GetMethod(name);
}
}
static class GenericSerializer<T>
@ -78,13 +83,8 @@ namespace UniJSON
// object
if (typeof(T) == typeof(object) && t.GetType() != typeof(object))
{
var self = Expression.Parameter(typeof(IFormatter), "f");
var arg = Expression.Parameter(t, "value");
var call = Expression.Call(typeof(FormatterExtensionsSerializer), "SerializeObject",
new Type[] { },
self, arg);
var lambda = Expression.Lambda(call, self, arg);
return (Action<IFormatter, T>)lambda.Compile();
var mi = FormatterExtensionsSerializer.GetMethod("SerializeObject");
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
}
try
@ -93,13 +93,7 @@ namespace UniJSON
var mi = typeof(IFormatter).GetMethod("Value", new Type[] { t });
if (mi != null)
{
// primitives
var self = Expression.Parameter(typeof(IFormatter), "f");
var arg = Expression.Parameter(t, "value");
var call = Expression.Call(self, mi, arg);
var lambda = Expression.Lambda(call, self, arg);
return (Action<IFormatter, T>)lambda.Compile();
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
}
}
catch (AmbiguousMatchException)
@ -116,14 +110,8 @@ namespace UniJSON
);
if (idictionary != null)
{
//var mi = typeof(IFormatter).GetMethod("SerializeDictionary", new Type[] { t });
var self = Expression.Parameter(typeof(IFormatter), "f");
var arg = Expression.Parameter(t, "value");
var call = Expression.Call(typeof(FormatterExtensionsSerializer), "SerializeDictionary",
new Type[] { },
self, arg);
var lambda = Expression.Lambda(call, self, arg);
return (Action<IFormatter, T>)lambda.Compile();
var mi = FormatterExtensionsSerializer.GetMethod("SerializeDictionary");
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
}
}
@ -131,13 +119,8 @@ namespace UniJSON
// object[]
if (t == typeof(object[]))
{
var self = Expression.Parameter(typeof(IFormatter), "f");
var arg = Expression.Parameter(t, "value");
var call = Expression.Call(typeof(FormatterExtensionsSerializer), "SerializeObjectArray",
new Type[] { },
self, arg);
var lambda = Expression.Lambda(call, self, arg);
return (Action<IFormatter, T>)lambda.Compile();
var mi = FormatterExtensionsSerializer.GetMethod("SerializeObjectArray");
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
}
}
@ -149,13 +132,9 @@ namespace UniJSON
);
if (ienumerable != null)
{
var self = Expression.Parameter(typeof(IFormatter), "f");
var arg = Expression.Parameter(t, "value");
var call = Expression.Call(typeof(FormatterExtensionsSerializer), "SerializeArray",
ienumerable.GetGenericArguments(),
self, arg);
var lambda = Expression.Lambda(call, self, arg);
return (Action<IFormatter, T>)lambda.Compile();
var g = FormatterExtensionsSerializer.GetMethod("SerializeArray");
var mi = g.MakeGenericMethod(ienumerable.GetGenericArguments());
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
}
}

View File

@ -49,13 +49,13 @@ namespace UniJSON
var a = String.Join(", ", GetArgs("a", i).ToArray());
var source = @"
public static Delegate Create<S, $0>(MethodInfo m)
public static Action<S, $0> Create<S, $0>(MethodInfo m)
{
var self = Expression.Parameter(m.DeclaringType, m.Name);
var args = m.GetParameters().Select(x => Expression.Parameter(x.ParameterType, x.Name)).ToArray();
var call = Expression.Call(self, m, args);
return
Expression.Lambda(call, new[] { self }.Concat(args).ToArray()).Compile();
(Action<S, $0>)Expression.Lambda(call, new[] { self }.Concat(args).ToArray()).Compile();
}
".Replace("$0", g).Replace("$1", a);
@ -68,7 +68,7 @@ namespace UniJSON
var g = String.Join(", ", GetArgs("A", i).ToArray());
var source = @"
public static Delegate CreateWithThis<S, $0>(MethodInfo m, S instance)
public static Action<$0> CreateWithThis<S, $0>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
@ -97,7 +97,7 @@ namespace UniJSON
call = Expression.Call(self, m, args);
}
return
Expression.Lambda(call, args).Compile();
(Action<$0>)Expression.Lambda(call, args).Compile();
}
".Replace("$0", g);

View File

@ -11,37 +11,37 @@ namespace UniJSON
{
public static Delegate Create<S, A0>(MethodInfo m)
public static Action<S, A0> Create<S, A0>(MethodInfo m)
{
var self = Expression.Parameter(m.DeclaringType, m.Name);
var args = m.GetParameters().Select(x => Expression.Parameter(x.ParameterType, x.Name)).ToArray();
var call = Expression.Call(self, m, args);
return
Expression.Lambda(call, new[] { self }.Concat(args).ToArray()).Compile();
(Action<S, A0>)Expression.Lambda(call, new[] { self }.Concat(args).ToArray()).Compile();
}
public static Delegate Create<S, A0, A1>(MethodInfo m)
public static Action<S, A0, A1> Create<S, A0, A1>(MethodInfo m)
{
var self = Expression.Parameter(m.DeclaringType, m.Name);
var args = m.GetParameters().Select(x => Expression.Parameter(x.ParameterType, x.Name)).ToArray();
var call = Expression.Call(self, m, args);
return
Expression.Lambda(call, new[] { self }.Concat(args).ToArray()).Compile();
(Action<S, A0, A1>)Expression.Lambda(call, new[] { self }.Concat(args).ToArray()).Compile();
}
public static Delegate Create<S, A0, A1, A2>(MethodInfo m)
public static Action<S, A0, A1, A2> Create<S, A0, A1, A2>(MethodInfo m)
{
var self = Expression.Parameter(m.DeclaringType, m.Name);
var args = m.GetParameters().Select(x => Expression.Parameter(x.ParameterType, x.Name)).ToArray();
var call = Expression.Call(self, m, args);
return
Expression.Lambda(call, new[] { self }.Concat(args).ToArray()).Compile();
(Action<S, A0, A1, A2>)Expression.Lambda(call, new[] { self }.Concat(args).ToArray()).Compile();
}
public static Delegate CreateWithThis<S, A0>(MethodInfo m, S instance)
public static Action<A0> CreateWithThis<S, A0>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
@ -70,11 +70,11 @@ namespace UniJSON
call = Expression.Call(self, m, args);
}
return
Expression.Lambda(call, args).Compile();
(Action<A0>)Expression.Lambda(call, args).Compile();
}
public static Delegate CreateWithThis<S, A0, A1>(MethodInfo m, S instance)
public static Action<A0, A1> CreateWithThis<S, A0, A1>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
@ -103,11 +103,11 @@ namespace UniJSON
call = Expression.Call(self, m, args);
}
return
Expression.Lambda(call, args).Compile();
(Action<A0, A1>)Expression.Lambda(call, args).Compile();
}
public static Delegate CreateWithThis<S, A0, A1, A2>(MethodInfo m, S instance)
public static Action<A0, A1, A2> CreateWithThis<S, A0, A1, A2>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
@ -136,11 +136,11 @@ namespace UniJSON
call = Expression.Call(self, m, args);
}
return
Expression.Lambda(call, args).Compile();
(Action<A0, A1, A2>)Expression.Lambda(call, args).Compile();
}
public static Delegate CreateWithThis<S, A0, A1, A2, A3>(MethodInfo m, S instance)
public static Action<A0, A1, A2, A3> CreateWithThis<S, A0, A1, A2, A3>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
@ -169,7 +169,7 @@ namespace UniJSON
call = Expression.Call(self, m, args);
}
return
Expression.Lambda(call, args).Compile();
(Action<A0, A1, A2, A3>)Expression.Lambda(call, args).Compile();
}

View File

@ -54,13 +54,23 @@ namespace UniJSON
var source = @"
public static Delegate Create<S, $0>(MethodInfo m)
public static Action<S, $0> Create<S, $0>(MethodInfo m)
{
Action<S, $0> callback=
(s, $1) =>
Action<S, $0> callback = null;
if (m.IsStatic)
{
m.Invoke(s, new object[] { $1 });
};
callback = (s, $1) =>
{
m.Invoke(null, new object[] { s, $1 });
};
}
else
{
callback = (s, $1) =>
{
m.Invoke(s, new object[] { $1 });
};
}
return callback;
}
".Replace("$0", g).Replace("$1", a);
@ -78,7 +88,7 @@ namespace UniJSON
var a = String.Join(", ", GetArgs("a", i).ToArray());
var source = @"
public static Delegate CreateWithThis<S, $0>(MethodInfo m, S instance)
public static Action<$0> CreateWithThis<S, $0>(MethodInfo m, S instance)
{
if (m.IsStatic)
{

View File

@ -10,41 +10,71 @@ namespace UniJSON
//////////// Create
public static Delegate Create<S, A0>(MethodInfo m)
public static Action<S, A0> Create<S, A0>(MethodInfo m)
{
Action<S, A0> callback=
(s, a0) =>
Action<S, A0> callback = null;
if (m.IsStatic)
{
m.Invoke(s, new object[] { a0 });
};
callback = (s, a0) =>
{
m.Invoke(null, new object[] { s, a0 });
};
}
else
{
callback = (s, a0) =>
{
m.Invoke(s, new object[] { a0 });
};
}
return callback;
}
public static Delegate Create<S, A0, A1>(MethodInfo m)
public static Action<S, A0, A1> Create<S, A0, A1>(MethodInfo m)
{
Action<S, A0, A1> callback=
(s, a0, a1) =>
Action<S, A0, A1> callback = null;
if (m.IsStatic)
{
m.Invoke(s, new object[] { a0, a1 });
};
callback = (s, a0, a1) =>
{
m.Invoke(null, new object[] { s, a0, a1 });
};
}
else
{
callback = (s, a0, a1) =>
{
m.Invoke(s, new object[] { a0, a1 });
};
}
return callback;
}
public static Delegate Create<S, A0, A1, A2>(MethodInfo m)
public static Action<S, A0, A1, A2> Create<S, A0, A1, A2>(MethodInfo m)
{
Action<S, A0, A1, A2> callback=
(s, a0, a1, a2) =>
Action<S, A0, A1, A2> callback = null;
if (m.IsStatic)
{
m.Invoke(s, new object[] { a0, a1, a2 });
};
callback = (s, a0, a1, a2) =>
{
m.Invoke(null, new object[] { s, a0, a1, a2 });
};
}
else
{
callback = (s, a0, a1, a2) =>
{
m.Invoke(s, new object[] { a0, a1, a2 });
};
}
return callback;
}
//////////// CreateWithThis
public static Delegate CreateWithThis<S, A0>(MethodInfo m, S instance)
public static Action<A0> CreateWithThis<S, A0>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
@ -70,7 +100,7 @@ namespace UniJSON
}
public static Delegate CreateWithThis<S, A0, A1>(MethodInfo m, S instance)
public static Action<A0, A1> CreateWithThis<S, A0, A1>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
@ -96,7 +126,7 @@ namespace UniJSON
}
public static Delegate CreateWithThis<S, A0, A1, A2>(MethodInfo m, S instance)
public static Action<A0, A1, A2> CreateWithThis<S, A0, A1, A2>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
@ -122,7 +152,7 @@ namespace UniJSON
}
public static Delegate CreateWithThis<S, A0, A1, A2, A3>(MethodInfo m, S instance)
public static Action<A0, A1, A2, A3> CreateWithThis<S, A0, A1, A2, A3>(MethodInfo m, S instance)
{
if (m.IsStatic)
{

View File

@ -1,5 +1,4 @@
using System;
using System.Linq.Expressions;
namespace UniJSON
@ -43,37 +42,34 @@ namespace UniJSON
}
}
static class GenericCast
static partial class GenericCast
{
public static Func<S, T> CreateCast<S, T>()
{
if (typeof(S) == typeof(T))
var mi = ConcreteCast.GetMethod(typeof(S), typeof(T));
if (mi == null)
{
// through
var src = Expression.Parameter(typeof(S), "src");
var lambda = Expression.Lambda(src, src);
return (Func<S, T>)lambda.Compile();
return (Func<S, T>)((S s) =>
{
return (T)(object)s;
});
}
else
{
// cast
var src = Expression.Parameter(typeof(S), "src");
var cast = Expression.Convert(src, typeof(T));
var lambda = Expression.Lambda(cast, src);
return (Func<S, T>)lambda.Compile();
return (Func<S, T>)((S s) =>
{
return (T)mi.Invoke(null, new object[] { s });
});
}
}
public static Func<S, Func<T>> CreateConst<S, T>()
{
var src = Expression.Parameter(typeof(S), "src");
var convert = Expression.Convert(src, typeof(T));
var lambda = (Func<S, T>)Expression.Lambda(convert, src).Compile();
return s =>
var cast = CreateCast<S, T>();
return (Func<S, Func<T>>)((S s) =>
{
var t = lambda(s);
return () => t;
};
return (Func<T>)(() => cast(s));
});
}
}
}

View File

@ -1,7 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
@ -116,17 +115,19 @@ namespace UniJSON
if (t.IsArray)
{
var pi = t.GetProperty("Length");
var v = Expression.Parameter(t, "value");
var call = Expression.Property(v, pi);
var compiled = (Func<T, int>)Expression.Lambda(call, v).Compile();
var compiled = (Func<T, int>)((T array) =>
{
return (int)pi.GetValue(array, null);
});
s_counter = new Counter(compiled);
}
else if (t.GetIsGenericList())
{
var pi = t.GetProperty("Count");
var v = Expression.Parameter(t, "value");
var call = Expression.Property(v, pi);
var compiled = (Func<T, int>)Expression.Lambda(call, v).Compile();
var compiled = (Func<T, int>)((T list) =>
{
return (int)pi.GetValue(list, null);
});
s_counter = new Counter(compiled);
}
else
@ -257,12 +258,17 @@ namespace UniJSON
{
throw new NotImplementedException();
}
var vv = Expression.Parameter(typeof(IJsonSchemaValidator), "v");
var ff = Expression.Parameter(typeof(IFormatter), "f");
var cc = Expression.Parameter(typeof(JsonSchemaValidationContext), "c");
var oo = Expression.Parameter(typeof(T), "o");
var call = Expression.Call(g, vv, ff, cc, oo);
var compiled = (Action<IJsonSchemaValidator, IFormatter, JsonSchemaValidationContext, T>)Expression.Lambda(call, vv, ff, cc, oo).Compile();
var compiled = (Action<
IJsonSchemaValidator,
IFormatter,
JsonSchemaValidationContext,
T>)
GenericInvokeCallFactory.Create<
IJsonSchemaValidator,
IFormatter,
JsonSchemaValidationContext,
T>(g);
s_serializer = new Serializer(compiled);
}
s_serializer(v, f, c, o);

View File

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace UniJSON
{
public static class JsonEnumValidator
@ -304,8 +304,8 @@ namespace UniJSON
GenericSerializer<T>.Serialize(this, f, c, o);
}
static class GenericDeserializer<T, U>
where T: IListTreeItem, IValue<T>
static class GenericDeserializer<T, U>
where T : IListTreeItem, IValue<T>
{
delegate U Deserializer(ListTreeNode<T> src);
static Deserializer s_d;
@ -319,13 +319,11 @@ namespace UniJSON
var mi = typeof(Enum).GetMethods(BindingFlags.Static | BindingFlags.Public).First(
x => x.Name == "Parse" && x.GetParameters().Length == 3
);
var type = Expression.Constant(typeof(U));
var value = Expression.Parameter(typeof(string), "value");
var ic = Expression.Constant(true);
var call = Expression.Call(mi, type, value, ic);
var lambda = Expression.Lambda(call, value);
var func = (Func<string, object>)lambda.Compile();
s_d = x => GenericCast<object, U>.Cast(func(x.GetString()));
s_d = x =>
{
var enumValue = mi.Invoke(null, new object[] { typeof(U), x.GetString(), true });
return GenericCast<object, U>.Cast(enumValue);
};
}
else
{
@ -336,7 +334,7 @@ namespace UniJSON
}
}
public void Deserialize<T, U>(ListTreeNode<T> src, ref U dst)
public void Deserialize<T, U>(ListTreeNode<T> src, ref U dst)
where T : IListTreeItem, IValue<T>
{
GenericDeserializer<T, U>.Deserialize(src, ref dst);
@ -414,7 +412,7 @@ namespace UniJSON
f.Serialize(GenericCast<T, int>.Cast(o));
}
static class GenericDeserializer<T, U>
static class GenericDeserializer<T, U>
where T : IListTreeItem, IValue<T>
{
delegate U Deserializer(ListTreeNode<T> src);
@ -426,17 +424,13 @@ namespace UniJSON
if (s_d == null)
{
// enum from int
var value = Expression.Parameter(typeof(int), "value");
var cast = Expression.Convert(value, typeof(U));
var lambda = Expression.Lambda(cast, value);
var func = (Func<int, U>)lambda.Compile();
s_d = s => func(s.GetInt32());
s_d = s => GenericCast<int, U>.Cast(s.GetInt32());
}
dst = s_d(src);
}
}
public void Deserialize<T, U>(ListTreeNode<T> src, ref U dst)
public void Deserialize<T, U>(ListTreeNode<T> src, ref U dst)
where T : IListTreeItem, IValue<T>
{
GenericDeserializer<T, U>.Deserialize(src, ref dst);