Skip to content

Explorarion of the new *Reference types: reimplemented some of the PyList members using BorrowedReference #1068

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/embed_tests/pyimport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void SetUp()

IntPtr str = Runtime.Runtime.PyString_FromString(testPath);
IntPtr path = Runtime.Runtime.PySys_GetObject("path");
Runtime.Runtime.PyList_Append(path, str);
Runtime.Runtime.PyList_Append(new BorrowedReference(path), str);
}

[TearDown]
Expand Down
5 changes: 4 additions & 1 deletion src/runtime/BorrowedReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ readonly ref struct BorrowedReference
public IntPtr DangerousGetAddress()
=> this.IsNull ? throw new NullReferenceException() : this.pointer;

BorrowedReference(IntPtr pointer)
/// <summary>
/// Creates new instance of <see cref="BorrowedReference"/> from raw pointer. Unsafe.
/// </summary>
public BorrowedReference(IntPtr pointer)
{
this.pointer = pointer;
}
Expand Down
8 changes: 4 additions & 4 deletions src/runtime/pylist.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public static PyList AsList(PyObject value)
/// </remarks>
public void Append(PyObject item)
{
int r = Runtime.PyList_Append(obj, item.obj);
int r = Runtime.PyList_Append(this.Reference, item.obj);
if (r < 0)
{
throw new PythonException();
Expand All @@ -135,7 +135,7 @@ public void Append(PyObject item)
/// </remarks>
public void Insert(int index, PyObject item)
{
int r = Runtime.PyList_Insert(obj, index, item.obj);
int r = Runtime.PyList_Insert(this.Reference, index, item.obj);
if (r < 0)
{
throw new PythonException();
Expand All @@ -151,7 +151,7 @@ public void Insert(int index, PyObject item)
/// </remarks>
public void Reverse()
{
int r = Runtime.PyList_Reverse(obj);
int r = Runtime.PyList_Reverse(this.Reference);
if (r < 0)
{
throw new PythonException();
Expand All @@ -167,7 +167,7 @@ public void Reverse()
/// </remarks>
public void Sort()
{
int r = Runtime.PyList_Sort(obj);
int r = Runtime.PyList_Sort(this.Reference);
if (r < 0)
{
throw new PythonException();
Expand Down
19 changes: 18 additions & 1 deletion src/runtime/pyobject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public class PyObject : DynamicObject, IEnumerable, IPyDisposable
private bool disposed = false;
private bool _finalized = false;

internal BorrowedReference Reference => new BorrowedReference(obj);

/// <summary>
/// PyObject Constructor
/// </summary>
Expand All @@ -52,9 +54,24 @@ public PyObject(IntPtr ptr)
#endif
}

/// <summary>
/// Creates new <see cref="PyObject"/> pointing to the same object as
/// the <paramref name="reference"/>. Increments refcount, allowing <see cref="PyObject"/>
/// to have ownership over its own reference.
/// </summary>
internal PyObject(BorrowedReference reference)
{
if (reference.IsNull) throw new ArgumentNullException(nameof(reference));

obj = Runtime.SelfIncRef(reference.DangerousGetAddress());
#if TRACE_ALLOC
Traceback = new StackTrace(1);
#endif
}

// Protected default constructor to allow subclasses to manage
// initialization in different ways as appropriate.
[Obsolete("Please, always use PyObject(IntPtr)")]
[Obsolete("Please, always use PyObject(*Reference)")]
protected PyObject()
{
#if TRACE_ALLOC
Expand Down
12 changes: 6 additions & 6 deletions src/runtime/runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ internal static void Initialize(bool initSigs = false)
string rtdir = RuntimeEnvironment.GetRuntimeDirectory();
IntPtr path = PySys_GetObject("path");
IntPtr item = PyString_FromString(rtdir);
PyList_Append(path, item);
PyList_Append(new BorrowedReference(path), item);
XDecref(item);
AssemblyManager.UpdatePath();
}
Expand Down Expand Up @@ -1658,22 +1658,22 @@ internal static int PyList_SetItem(IntPtr pointer, long index, IntPtr value)
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
private static extern int PyList_SetItem(IntPtr pointer, IntPtr index, IntPtr value);

internal static int PyList_Insert(IntPtr pointer, long index, IntPtr value)
internal static int PyList_Insert(BorrowedReference pointer, long index, IntPtr value)
{
return PyList_Insert(pointer, new IntPtr(index), value);
}

[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
private static extern int PyList_Insert(IntPtr pointer, IntPtr index, IntPtr value);
private static extern int PyList_Insert(BorrowedReference pointer, IntPtr index, IntPtr value);

[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_Append(IntPtr pointer, IntPtr value);
internal static extern int PyList_Append(BorrowedReference pointer, IntPtr value);

[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_Reverse(IntPtr pointer);
internal static extern int PyList_Reverse(BorrowedReference pointer);

[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyList_Sort(IntPtr pointer);
internal static extern int PyList_Sort(BorrowedReference pointer);

internal static IntPtr PyList_GetSlice(IntPtr pointer, long start, long end)
{
Expand Down