This commit is contained in:
Victor Nova 2021-10-18 22:54:05 -07:00
Родитель 7a9e411917
Коммит 9a9ed3bef7
2 изменённых файлов: 20 добавлений и 29 удалений

Просмотреть файл

@ -36,8 +36,8 @@ namespace Python.Runtime.Native
static unsafe int GetRefCountOffset()
{
IntPtr tempObject = Runtime.PyList_New(0);
IntPtr* tempPtr = (IntPtr*)tempObject;
using var tempObject = Runtime.PyList_New(0);
IntPtr* tempPtr = (IntPtr*)tempObject.DangerousGetAddress();
int offset = 0;
while(tempPtr[offset] != (IntPtr)1)
{
@ -45,7 +45,6 @@ namespace Python.Runtime.Native
if (offset > 100)
throw new InvalidProgramException("PyObject_HEAD could not be found withing reasonable distance from the start of PyObject");
}
Runtime.XDecref(tempObject);
return offset * IntPtr.Size;
}
}

Просмотреть файл

@ -15,7 +15,7 @@ namespace Python.Runtime
{
_view = new Py_buffer();
if (Runtime.PyObject_GetBuffer(exporter.Handle, ref _view, (int)flags) < 0)
if (Runtime.PyObject_GetBuffer(exporter, out _view, (int)flags) < 0)
{
throw PythonException.ThrowLastAsClrException();
}
@ -46,25 +46,25 @@ namespace Python.Runtime
public int Dimensions => _view.ndim;
public bool ReadOnly => _view._readonly;
public IntPtr Buffer => _view.buf;
public string Format => _view.format;
public string? Format => _view.format;
/// <summary>
/// An array of length <see cref="Dimensions"/> indicating the shape of the memory as an n-dimensional array.
/// </summary>
public long[] Shape { get; private set; }
public long[]? Shape { get; private set; }
/// <summary>
/// An array of length <see cref="Dimensions"/> giving the number of bytes to skip to get to a new element in each dimension.
/// Will be null except when PyBUF_STRIDES or PyBUF_INDIRECT flags in GetBuffer/>.
/// </summary>
public long[] Strides { get; private set; }
public long[]? Strides { get; private set; }
/// <summary>
/// An array of Py_ssize_t of length ndim. If suboffsets[n] >= 0,
/// the values stored along the nth dimension are pointers and the suboffset value dictates how many bytes to add to each pointer after de-referencing.
/// A suboffset value that is negative indicates that no de-referencing should occur (striding in a contiguous memory block).
/// </summary>
public long[] SubOffsets { get; private set; }
public long[]? SubOffsets { get; private set; }
private static char OrderStyleToChar(BufferOrderStyle order, bool eitherOneValid)
{
@ -162,7 +162,7 @@ namespace Python.Runtime
/// If this function is used as part of a getbufferproc, exporter MUST be set to the exporting object and flags must be passed unmodified.Otherwise, exporter MUST be NULL.
/// </remarks>
/// <returns>On success, set view->obj to a new reference to exporter and return 0. Otherwise, raise PyExc_BufferError, set view->obj to NULL and return -1;</returns>
internal void FillInfo(IntPtr exporter, IntPtr buf, long len, bool _readonly, int flags)
internal void FillInfo(BorrowedReference exporter, IntPtr buf, long len, bool _readonly, int flags)
{
if (disposedValue)
throw new ObjectDisposedException(nameof(PyBuffer));
@ -213,9 +213,19 @@ namespace Python.Runtime
return copylen;
}
~PyBuffer()
{
this.Dispose();
Finalizer.Instance.AddFinalizedObject(ref _view.obj);
}
private bool disposedValue = false; // To detect redundant calls
private void Dispose(bool disposing)
/// <summary>
/// Release the buffer view and decrement the reference count for view->obj. This function MUST be called when the buffer is no longer being used, otherwise reference leaks may occur.
/// It is an error to call this function on a buffer that was not obtained via <see cref="PyObject.GetBuffer"/>.
/// </summary>
public void Dispose()
{
if (!disposedValue)
{
@ -225,31 +235,13 @@ namespace Python.Runtime
// this also decrements ref count for _view->obj
Runtime.PyBuffer_Release(ref _view);
_exporter = null;
_exporter = null!;
Shape = null;
Strides = null;
SubOffsets = null;
disposedValue = true;
}
}
~PyBuffer()
{
if (disposedValue)
{
return;
}
Finalizer.Instance.AddFinalizedObject(ref _view.obj);
}
/// <summary>
/// Release the buffer view and decrement the reference count for view->obj. This function MUST be called when the buffer is no longer being used, otherwise reference leaks may occur.
/// It is an error to call this function on a buffer that was not obtained via <see cref="PyObject.GetBuffer"/>.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}