GitHub Viewer
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Text;
namespace Python.Runtime
{
///
/// This file defines objects to support binary interop with the Python
/// runtime. Generally, the definitions here need to be kept up to date
/// when moving to new Python versions.
///
[Serializable]
[AttributeUsage(AttributeTargets.All)]
public class DocStringAttribute : Attribute
{
public DocStringAttribute(string docStr)
{
DocString = docStr;
}
public string DocString
{
get { return docStr; }
set { docStr = value; }
}
private string docStr;
}
[Serializable]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)]
internal class PythonMethodAttribute : Attribute
{
public PythonMethodAttribute()
{
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)]
internal class ModuleFunctionAttribute : Attribute
{
public ModuleFunctionAttribute()
{
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate)]
internal class ForbidPythonThreadsAttribute : Attribute
{
public ForbidPythonThreadsAttribute()
{
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Property)]
internal class ModulePropertyAttribute : Attribute
{
public ModulePropertyAttribute()
{
}
}
internal static partial class TypeOffset
{
public static int magic() => ManagedDataOffsets.Magic;
}
internal static class ManagedDataOffsets
{
public static int Magic { get; internal set; }
public static readonly Dictionary NameMapping = new Dictionary();
static class DataOffsets
{
public static readonly int ob_data = 0;
public static readonly int ob_dict = 0;
static DataOffsets()
{
FieldInfo[] fields = typeof(DataOffsets).GetFields(BindingFlags.Static | BindingFlags.Public);
for (int i = 0; i < fields.Length; i++)
{
fields[i].SetValue(null, -(i * IntPtr.Size) - IntPtr.Size);
}
}
}
static ManagedDataOffsets()
{
NameMapping = TypeOffset.GetOffsets();
FieldInfo[] fields = typeof(DataOffsets).GetFields(BindingFlags.Static | BindingFlags.Public);
size = fields.Length * IntPtr.Size;
}
public static int GetSlotOffset(string name)
{
return NameMapping[name];
}
private static int BaseOffset(IntPtr type)
{
Debug.Assert(type != IntPtr.Zero);
int typeSize = Marshal.ReadInt32(type, TypeOffset.tp_basicsize);
Debug.Assert(typeSize > 0);
return typeSize;
}
public static int DataOffset(IntPtr type)
{
return BaseOffset(type) + DataOffsets.ob_data;
}
public static int DictOffset(IntPtr type)
{
return BaseOffset(type) + DataOffsets.ob_dict;
}
public static int ob_data => DataOffsets.ob_data;
public static int ob_dict => DataOffsets.ob_dict;
public static int Size { get { return size; } }
private static readonly int size;
}
internal static class OriginalObjectOffsets
{
static OriginalObjectOffsets()
{
int size = IntPtr.Size;
var n = 0; // Py_TRACE_REFS add two pointers to PyObject_HEAD
#if PYTHON_WITH_PYDEBUG
_ob_next = 0;
_ob_prev = 1 * size;
n = 2;
#endif
ob_refcnt = (n + 0) * size;
ob_type = (n + 1) * size;
}
public static int Size { get { return size; } }
private static readonly int size =
#if PYTHON_WITH_PYDEBUG
4 * IntPtr.Size;
#else
2 * IntPtr.Size;
#endif
#if PYTHON_WITH_PYDEBUG
public static int _ob_next;
public static int _ob_prev;
#endif
public static int ob_refcnt;
public static int ob_type;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class ObjectOffset
{
static ObjectOffset()
{
#if PYTHON_WITH_PYDEBUG
_ob_next = OriginalObjectOffsets._ob_next;
_ob_prev = OriginalObjectOffsets._ob_prev;
#endif
ob_refcnt = OriginalObjectOffsets.ob_refcnt;
ob_type = OriginalObjectOffsets.ob_type;
size = OriginalObjectOffsets.Size + ManagedDataOffsets.Size;
}
public static int magic(IntPtr type)
{
return ManagedDataOffsets.DataOffset(type);
}
public static int TypeDictOffset(IntPtr type)
{
return ManagedDataOffsets.DictOffset(type);
}
public static int Size(IntPtr pyType)
{
if (IsException(pyType))
{
return ExceptionOffset.Size();
}
return size;
}
#if PYTHON_WITH_PYDEBUG
public static int _ob_next;
public static int _ob_prev;
#endif
public static int ob_refcnt;
public static int ob_type;
private static readonly int size;
private static bool IsException(IntPtr pyObject)
{
var type = Runtime.PyObject_TYPE(pyObject);
return Runtime.PyType_IsSameAsOrSubtype(type, ofType: Exceptions.BaseException)
|| Runtime.PyType_IsSameAsOrSubtype(type, ofType: Runtime.PyTypeType)
&& Runtime.PyType_IsSubtype(pyObject, Exceptions.BaseException);
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class ExceptionOffset
{
static ExceptionOffset()
{
Type type = typeof(ExceptionOffset);
FieldInfo[] fi = type.GetFields(BindingFlags.Static | BindingFlags.Public);
for (int i = 0; i < fi.Length; i++)
{
fi[i].SetValue(null, (i * IntPtr.Size) + OriginalObjectOffsets.Size);
}
size = fi.Length * IntPtr.Size + OriginalObjectOffsets.Size + ManagedDataOffsets.Size;
}
public static int Size() { return size; }
// PyException_HEAD
// (start after PyObject_HEAD)
public static int dict = 0;
public static int args = 0;
public static int traceback = 0;
public static int context = 0;
public static int cause = 0;
public static int suppress_context = 0;
private static readonly int size;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class BytesOffset
{
static BytesOffset()
{
Type type = typeof(BytesOffset);
FieldInfo[] fi = type.GetFields();
int size = IntPtr.Size;
for (int i = 0; i < fi.Length; i++)
{
fi[i].SetValue(null, i * size);
}
}
/* The *real* layout of a type object when allocated on the heap */
//typedef struct _heaptypeobject {
#if PYTHON_WITH_PYDEBUG
/* _PyObject_HEAD_EXTRA defines pointers to support a doubly-linked list of all live heap objects. */
public static int _ob_next = 0;
public static int _ob_prev = 0;
#endif
// PyObject_VAR_HEAD {
// PyObject_HEAD {
public static int ob_refcnt = 0;
public static int ob_type = 0;
// }
public static int ob_size = 0; /* Number of items in _VAR_iable part */
// }
public static int ob_shash = 0;
public static int ob_sval = 0; /* start of data */
/* Invariants:
* ob_sval contains space for 'ob_size+1' elements.
* ob_sval[ob_size] == 0.
* ob_shash is the hash of the string or -1 if not computed yet.
*/
//} PyBytesObject;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class ModuleDefOffset
{
static ModuleDefOffset()
{
Type type = typeof(ModuleDefOffset);
FieldInfo[] fi = type.GetFields();
int size = IntPtr.Size;
for (int i = 0; i < fi.Length; i++)
{
fi[i].SetValue(null, (i * size) + TypeOffset.ob_size);
}
}
public static IntPtr AllocModuleDef(string modulename)
{
byte[] ascii = Encoding.ASCII.GetBytes(modulename);
int size = name + ascii.Length + 1;
IntPtr ptr = Marshal.AllocHGlobal(size);
for (int i = 0; i