diff options
author | jfrijters <jfrijters> | 2014-07-09 12:45:25 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2014-07-09 12:45:25 +0400 |
commit | bb2d12a8a4a7c1070ac19499170a26e96252704c (patch) | |
tree | 46b64f829297f18c8c1c3efe48fc470f120fc842 | |
parent | c1a9246c7ee5282addc07b533aaef9c8ee524c8d (diff) |
Added .NET serialization interop to lambda classes.
-rw-r--r-- | runtime/LambdaMetafactory.cs | 19 | ||||
-rw-r--r-- | runtime/Serialization.cs | 17 | ||||
-rw-r--r-- | runtime/TypeWrapper.cs | 13 |
3 files changed, 43 insertions, 6 deletions
diff --git a/runtime/LambdaMetafactory.cs b/runtime/LambdaMetafactory.cs index 9a2a7258..7ea26157 100644 --- a/runtime/LambdaMetafactory.cs +++ b/runtime/LambdaMetafactory.cs @@ -464,6 +464,13 @@ namespace IKVM.Internal ctorSerializedLambda.EmitNewobj(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); + + if (!context.TypeWrapper.GetClassLoader().NoAutomagicSerialization) + { + // add .NET serialization interop support + Serialization.MarkSerializable(tb); + Serialization.AddGetObjectData(tb); + } } return ctor; @@ -740,10 +747,18 @@ namespace IKVM.Internal return true; } + private static bool IsSupportedInterface(TypeWrapper tw, TypeWrapper caller) + { + return tw.IsInterface + && !tw.IsGhost + && tw.IsAccessibleFrom(caller) + && !Serialization.IsISerializable(tw); + } + private static bool CheckSupportedInterfaces(TypeWrapper caller, TypeWrapper tw, TypeWrapper[] markers, ClassFile.ConstantPoolItemMethodType[] bridges, out MethodWrapper[] methodList) { // we don't need to check for unloadable, because we already did that while validating the invoke signature - if (!tw.IsInterface || tw.IsGhost || !tw.IsAccessibleFrom(caller)) + if (!IsSupportedInterface(tw, caller)) { methodList = null; return false; @@ -755,7 +770,7 @@ namespace IKVM.Internal { foreach (TypeWrapper marker in markers) { - if (!marker.IsInterface || marker.IsGhost || !marker.IsAccessibleFrom(caller)) + if (!IsSupportedInterface(marker, caller)) { methodList = null; return false; diff --git a/runtime/Serialization.cs b/runtime/Serialization.cs index 1145d351..024c12d6 100644 --- a/runtime/Serialization.cs +++ b/runtime/Serialization.cs @@ -52,6 +52,11 @@ namespace IKVM.Internal psetSerializationFormatter.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter)); } + internal static bool IsISerializable(TypeWrapper wrapper) + { + return wrapper == iserializable; + } + private static bool IsSafeForAutomagicSerialization(TypeWrapper wrapper) { if (wrapper.TypeAsBaseType.IsSerializable) @@ -147,15 +152,21 @@ namespace IKVM.Internal return null; } - private static void MarkSerializable(TypeBuilder tb) + internal static void MarkSerializable(TypeBuilder tb) { tb.SetCustomAttribute(serializableAttribute); } - private static void AddGetObjectData(TypeBuilder tb) + internal static void AddGetObjectData(TypeBuilder tb) { + string name = tb.IsSealed + ? "System.Runtime.Serialization.ISerializable.GetObjectData" + : "GetObjectData"; + MethodAttributes attr = tb.IsSealed + ? MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final + : MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; tb.AddInterfaceImplementation(JVM.Import(typeof(ISerializable))); - MethodBuilder getObjectData = tb.DefineMethod("GetObjectData", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot, null, + MethodBuilder getObjectData = tb.DefineMethod(name, attr, null, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) }); getObjectData.SetCustomAttribute(securityCriticalAttribute); AttributeHelper.HideFromJava(getObjectData); diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs index 1f7e8684..e85879ac 100644 --- a/runtime/TypeWrapper.cs +++ b/runtime/TypeWrapper.cs @@ -5730,7 +5730,18 @@ namespace IKVM.Internal internal override TypeWrapper[] Interfaces { - get { return GetImplementedInterfacesAsTypeWrappers(type); } + get + { + TypeWrapper[] interfaces = GetImplementedInterfacesAsTypeWrappers(type); + if (type.IsSerializable) + { + // we have to remove the System.Runtime.Serialization.ISerializable interface + List<TypeWrapper> list = new List<TypeWrapper>(interfaces); + list.RemoveAll(Serialization.IsISerializable); + return list.ToArray(); + } + return interfaces; + } } internal override TypeWrapper[] InnerClasses |