// ==========================================================================
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.
// ==========================================================================
using System;
using System.Collections;
using System.Collections.Specialized;
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() {}
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
internal class ObjectOffset {
static ObjectOffset() {
int size = IntPtr.Size;
int n = 0; // Py_TRACE_REFS add two pointers to PyObject_HEAD
#if (Py_DEBUG)
_ob_next = 0;
_ob_prev = 1 * size;
n = 2;
#endif
ob_refcnt = (n+0) * size;
ob_type = (n+1) * size;
ob_dict = (n+2) * size;
ob_data = (n+3) * size;
}
public static int magic(IntPtr ob) {
#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
if ((Runtime.PyObject_TypeCheck(ob, Exceptions.BaseException) ||
(Runtime.PyType_Check(ob) && Runtime.PyType_IsSubtype(ob, Exceptions.BaseException))))
{
return ExceptionOffset.ob_data;
}
#endif
return ob_data;
}
public static int DictOffset(IntPtr ob)
{
#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
if ((Runtime.PyObject_TypeCheck(ob, Exceptions.BaseException) ||
(Runtime.PyType_Check(ob) && Runtime.PyType_IsSubtype(ob, Exceptions.BaseException))))
{
return ExceptionOffset.ob_dict;
}
#endif
return ob_dict;
}
public static int Size(IntPtr ob) {
#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
if ((Runtime.PyObject_TypeCheck(ob, Exceptions.BaseException) ||
(Runtime.PyType_Check(ob) && Runtime.PyType_IsSubtype(ob, Exceptions.BaseException))))
{
return ExceptionOffset.Size();
}
#endif
#if (Py_DEBUG)
return 6 * IntPtr.Size;
#else
return 4 * IntPtr.Size;
#endif
}
#if (Py_DEBUG)
public static int _ob_next;
public static int _ob_prev;
#endif
public static int ob_refcnt;
public static int ob_type;
private static int ob_dict;
private static int ob_data;
}
#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class ExceptionOffset
{
static ExceptionOffset()
{
Type type = typeof(ExceptionOffset);
FieldInfo[] fi = type.GetFields();
int size = IntPtr.Size;
for (int i = 0; i < fi.Length; i++)
{
fi[i].SetValue(null, (i * size) + ObjectOffset.ob_type + size);
}
}
public static int Size()
{
return ob_data + IntPtr.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;
// extra c# data
public static int ob_dict;
public static int ob_data;
}
#endif
#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
[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 (Py_DEBUG) // #ifdef Py_TRACE_REFS
/* _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