-
Notifications
You must be signed in to change notification settings - Fork 147
Open
Description
Here's the error (which was reported previously, but nobody actually solved):
InvalidProgramException: Invalid IL code in (wrapper dynamic-method) FakeVector3:_cgm (object): IL_0013: ret
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, System.Boolean throwOnBindFailure, System.Boolean allowClosed) (at <695d1cc93cca45069c528c15c9fdd749>:0)
Here is some simple test code that shows it broken:
public struct FakeVector3
{
public float x;
public float y;
public float z;
public static FakeVector3 right { get { return new FakeVector3() { x=1,y=2,z=3 }; } }
}
FakeVector3 v = new FakeVector3() { x=0, y=1, z=2 };
string json = fastJSON.JSON.ToJSON(v);
FakeVector3 newV = fastJSON.JSON.ToObject<FakeVector3>(json);
Basically what is happening is the Reflection.CreateGetMethod() was doing the wrong thing for static getters in structs. Here's how I modified it to work, which does deserialize properly:
internal static GenericGetter CreateGetMethod(Type type, PropertyInfo propertyInfo)
{
MethodInfo getMethod = propertyInfo.GetGetMethod();
if (getMethod == null)
return null;
DynamicMethod getter = new DynamicMethod("_cgm", typeof(object), new Type[] { typeof(object) }, type, true);
ILGenerator il = getter.GetILGenerator();
if (!type.IsClass) // structs
{
var lv = il.DeclareLocal(type);
if (!getMethod.IsStatic)
{
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Unbox_Any, type);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldloca_S, lv);
il.EmitCall(OpCodes.Call, getMethod, null);
}
else // call a static method on a struct type
{
il.Emit(OpCodes.Call, getMethod);
}
if (propertyInfo.PropertyType.IsValueType)
il.Emit(OpCodes.Box, propertyInfo.PropertyType);
}
else
{
if (!getMethod.IsStatic)
{
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
il.EmitCall(OpCodes.Callvirt, getMethod, null);
}
else
il.Emit(OpCodes.Call, getMethod);
if (propertyInfo.PropertyType.IsValueType)
il.Emit(OpCodes.Box, propertyInfo.PropertyType);
}
il.Emit(OpCodes.Ret);
return (GenericGetter)getter.CreateDelegate(typeof(GenericGetter));
}
Metadata
Metadata
Assignees
Labels
No labels