1
1
using System ;
2
2
using System . Reflection ;
3
+ using System . Runtime . Serialization ;
4
+ using System . Runtime . Serialization . Formatters . Binary ;
5
+ using System . IO ;
3
6
4
7
namespace Python . Runtime
5
8
{
@@ -9,11 +12,97 @@ namespace Python.Runtime
9
12
[ Serializable ]
10
13
internal class FieldObject : ExtensionType
11
14
{
12
- private FieldInfo info ;
15
+ [ Serializable ]
16
+ private struct SerializedFieldInfo : ISerializable
17
+ {
18
+ // The field if we can find it. Otherwise null.
19
+ private FieldInfo m_info ;
20
+
21
+ // The name of the field if the field is missing. Otherwise null.
22
+ private string m_name ;
23
+
24
+ public SerializedFieldInfo ( FieldInfo info )
25
+ {
26
+ if ( info == null )
27
+ {
28
+ throw new System . ArgumentNullException ( "null FieldInfo" ) ;
29
+ }
30
+ m_info = info ;
31
+ m_name = null ;
32
+ }
33
+
34
+ public FieldInfo Value
35
+ {
36
+ get
37
+ {
38
+ if ( m_info == null )
39
+ {
40
+ throw new SerializationException ( $ ".NET field { m_name } was renamed or removed during domain reload") ;
41
+ }
42
+ return m_info ;
43
+ }
44
+ }
45
+
46
+ public string Name
47
+ {
48
+ get
49
+ {
50
+ if ( m_info == null )
51
+ {
52
+ return $ "(missing { m_name } )";
53
+ }
54
+ else
55
+ {
56
+ return m_info . Name ;
57
+ }
58
+ }
59
+ }
60
+
61
+ public void GetObjectData ( SerializationInfo info , StreamingContext context )
62
+ {
63
+ if ( m_info == null )
64
+ {
65
+ info . AddValue ( "n" , m_name ) ;
66
+ }
67
+ else
68
+ {
69
+ // Serialize in a silly way. TODO optimize.
70
+ var formatter = new BinaryFormatter ( ) ;
71
+ using ( var ms = new MemoryStream ( ) )
72
+ {
73
+ formatter . Serialize ( ms , m_info ) ;
74
+ info . AddValue ( "i" , ms . ToArray ( ) ) ;
75
+ }
76
+
77
+ // Also save the name in case the info doesn't deserialize
78
+ info . AddValue ( "n" , m_info . ToString ( ) ) ;
79
+ }
80
+ }
81
+
82
+ private SerializedFieldInfo ( SerializationInfo info , StreamingContext context )
83
+ {
84
+ try
85
+ {
86
+ var serialized = ( byte [ ] ) info . GetValue ( "i" , typeof ( byte [ ] ) ) ;
87
+ var formatter = new BinaryFormatter ( ) ;
88
+ using ( var ms = new MemoryStream ( serialized ) )
89
+ {
90
+ m_info = ( FieldInfo ) formatter . Deserialize ( ms ) ;
91
+ }
92
+ }
93
+ catch ( SerializationException _ )
94
+ {
95
+ m_info = null ;
96
+ }
97
+ m_name = ( m_info != null ) ? null : info . GetString ( "n" ) ;
98
+ }
99
+ }
100
+
101
+ private SerializedFieldInfo m_info ;
13
102
14
103
public FieldObject ( FieldInfo info )
15
104
{
16
- this . info = info ;
105
+ m_info = new SerializedFieldInfo ( info ) ;
17
106
}
18
107
19
108
/// <summary>
@@ -24,14 +113,25 @@ public FieldObject(FieldInfo info)
24
113
public static IntPtr tp_descr_get ( IntPtr ds , IntPtr ob , IntPtr tp )
25
114
{
26
115
var self = ( FieldObject ) GetManagedObject ( ds ) ;
27
- object result ;
28
116
29
117
if ( self == null )
30
118
{
31
119
return IntPtr . Zero ;
32
120
}
121
+ try
122
+ {
123
+ return self . tp_descr_get ( ob , tp ) ;
124
+ }
125
+ catch ( Exception e )
126
+ {
127
+ Exceptions . SetError ( Exceptions . TypeError , e . Message ) ;
128
+ return IntPtr . Zero ;
129
+ }
130
+ }
33
131
34
- FieldInfo info = self . info ;
132
+ IntPtr tp_descr_get ( IntPtr ob , IntPtr tp )
133
+ {
134
+ FieldInfo info = m_info . Value ;
35
135
36
136
if ( ob == IntPtr . Zero || ob == Runtime . PyNone )
37
137
{
@@ -43,7 +143,7 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
43
143
}
44
144
try
45
145
{
46
- result = info . GetValue ( null ) ;
146
+ var result = info . GetValue ( null ) ;
47
147
return Converter . ToPython ( result , info . FieldType ) ;
48
148
}
49
149
catch ( Exception e )
@@ -61,7 +161,7 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
61
161
Exceptions . SetError ( Exceptions . TypeError , "instance is not a clr object" ) ;
62
162
return IntPtr . Zero ;
63
163
}
64
- result = info . GetValue ( co . inst ) ;
164
+ var result = info . GetValue ( co . inst ) ;
65
165
return Converter . ToPython ( result , info . FieldType ) ;
66
166
}
67
167
catch ( Exception e )
@@ -79,7 +179,6 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
79
179
public new static int tp_descr_set ( IntPtr ds , IntPtr ob , IntPtr val )
80
180
{
81
181
var self = ( FieldObject ) GetManagedObject ( ds ) ;
82
- object newval ;
83
182
84
183
if ( self == null )
85
184
{
@@ -91,8 +190,21 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
91
190
Exceptions . SetError ( Exceptions . TypeError , "cannot delete field" ) ;
92
191
return - 1 ;
93
192
}
193
+ try
194
+ {
195
+ return self . tp_descr_set ( ob , val ) ;
196
+ }
197
+ catch ( Exception e )
198
+ {
199
+ Exceptions . SetError ( Exceptions . TypeError , e . Message ) ;
200
+ return - 1 ;
201
+ }
202
+ }
203
+
94
204
95
- FieldInfo info = self . info ;
205
+ int tp_descr_set ( IntPtr ob , IntPtr val )
206
+ {
207
+ FieldInfo info = m_info . Value ;
96
208
97
209
if ( info . IsLiteral || info . IsInitOnly )
98
210
{
@@ -111,6 +223,7 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
111
223
}
112
224
}
113
225
226
+ object newval ;
114
227
if ( ! Converter . ToManaged ( val , info . FieldType , out newval , true ) )
115
228
{
116
229
return - 1 ;
@@ -147,7 +260,7 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
147
260
public static IntPtr tp_repr ( IntPtr ob )
148
261
{
149
262
var self = ( FieldObject ) GetManagedObject ( ob ) ;
150
- return Runtime . PyString_FromString ( $ "<field '{ self . info . Name } '>") ;
263
+ return Runtime . PyString_FromString ( $ "<field '{ self . m_info . Name } '>") ;
151
264
}
152
265
}
153
266
}
0 commit comments