-
Notifications
You must be signed in to change notification settings - Fork 774
Expand file tree
/
Copy pathClrObject.cs
More file actions
80 lines (63 loc) · 2.49 KB
/
ClrObject.cs
File metadata and controls
80 lines (63 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Python.Runtime
{
[Serializable]
[DebuggerDisplay("clrO: {inst}")]
internal sealed class CLRObject : ManagedType
{
internal readonly object inst;
internal static bool creationBlocked = false;
// "borrowed" references
internal static readonly HashSet<IntPtr> reflectedObjects = new();
static NewReference Create(object ob, BorrowedReference tp)
{
if (creationBlocked)
throw new InvalidOperationException("Reflected objects should not be created anymore.");
Debug.Assert(tp != null);
var py = Runtime.PyType_GenericAlloc(tp, 0);
var self = new CLRObject(ob);
GCHandle gc = GCHandle.Alloc(self);
InitGCHandle(py.Borrow(), type: tp, gc);
bool isNew = reflectedObjects.Add(py.DangerousGetAddress());
Debug.Assert(isNew);
// Fix the BaseException args (and __cause__ in case of Python 3)
// slot if wrapping a CLR exception
if (ob is Exception e) Exceptions.SetArgsAndCause(py.Borrow(), e);
return py;
}
CLRObject(object inst)
{
this.inst = inst;
}
internal static NewReference GetReference(object ob, BorrowedReference pyType)
=> Create(ob, pyType);
internal static NewReference GetReference(object ob, Type type)
{
BorrowedReference cc = ClassManager.GetClass(type);
return Create(ob, cc);
}
internal static NewReference GetReference(object ob)
{
BorrowedReference cc = ClassManager.GetClass(ob.GetType());
return Create(ob, cc);
}
internal static void Restore(object ob, BorrowedReference pyHandle, Dictionary<string, object?> context)
{
var co = new CLRObject(ob);
co.OnLoad(pyHandle, context);
}
protected override void OnLoad(BorrowedReference ob, Dictionary<string, object?>? context)
{
if (creationBlocked)
throw new InvalidOperationException("Reflected objects should not be loaded anymore.");
base.OnLoad(ob, context);
GCHandle gc = GCHandle.Alloc(this);
SetGCHandle(ob, gc);
bool isNew = reflectedObjects.Add(ob.DangerousGetAddress());
Debug.Assert(isNew);
}
}
}