[Zope-CVS] CVS: PythonNet/src/runtime - ClassObject.cs:1.4 DelegateObject.cs:1.3 MetaType.cs:1.4 Runtime.cs:1.5 TypeManager.cs:1.5
Brian Lloyd
brian@zope.com
Sat Aug 2 22:56:07 EDT 2003
Update of /cvs-repository/PythonNet/src/runtime
In directory cvs.zope.org:/tmp/cvs-serv16324/src/runtime
Modified Files:
ClassObject.cs DelegateObject.cs MetaType.cs Runtime.cs
TypeManager.cs
Log Message:
various optimizations and cleanups
=== PythonNet/src/runtime/ClassObject.cs 1.3 => 1.4 ===
--- PythonNet/src/runtime/ClassObject.cs:1.3 Fri Aug 1 10:30:13 2003
+++ PythonNet/src/runtime/ClassObject.cs Sat Aug 2 17:55:30 2003
@@ -100,7 +100,7 @@
[CallConvCdecl()]
public static IntPtr mp_subscript(IntPtr ob, IntPtr idx) {
ManagedType self = GetManagedObject(ob);
- IntPtr tp = Runtime.PyObject_Type(ob);
+ IntPtr tp = Runtime.PyObject_TYPE(ob);
ClassBase cls = (ClassBase)GetManagedObject(tp);
if (cls.indexer == null || !cls.indexer.CanGet) {
@@ -141,7 +141,7 @@
[CallConvCdecl()]
public static int mp_ass_subscript(IntPtr ob, IntPtr idx, IntPtr v) {
ManagedType self = GetManagedObject(ob);
- IntPtr tp = Runtime.PyObject_Type(ob);
+ IntPtr tp = Runtime.PyObject_TYPE(ob);
ClassBase cls = (ClassBase)GetManagedObject(tp);
if (cls.indexer == null || !cls.indexer.CanSet) {
=== PythonNet/src/runtime/DelegateObject.cs 1.2 => 1.3 ===
--- PythonNet/src/runtime/DelegateObject.cs:1.2 Mon Jul 28 22:28:15 2003
+++ PythonNet/src/runtime/DelegateObject.cs Sat Aug 2 17:55:30 2003
@@ -98,7 +98,7 @@
[CallConvCdecl()]
public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) {
// todo: add fast type check!
- IntPtr pytype = Runtime.PyObject_Type(ob);
+ IntPtr pytype = Runtime.PyObject_TYPE(ob);
DelegateObject self = (DelegateObject)GetManagedObject(pytype);
CLRObject o = GetManagedObject(ob) as CLRObject;
=== PythonNet/src/runtime/MetaType.cs 1.3 => 1.4 ===
--- PythonNet/src/runtime/MetaType.cs:1.3 Fri Aug 1 19:56:10 2003
+++ PythonNet/src/runtime/MetaType.cs Sat Aug 2 17:55:30 2003
@@ -129,9 +129,8 @@
IntPtr descr = Runtime._PyType_Lookup(tp, name);
if (descr != IntPtr.Zero) {
- IntPtr dt = Runtime.PyObject_Type(descr);
+ IntPtr dt = Runtime.PyObject_TYPE(descr);
IntPtr fp = Marshal.ReadIntPtr(dt, (35 * IntPtr.Size));
- Runtime.Decref(dt);
if (fp != IntPtr.Zero) {
return NativeCall.Impl.Int_Call_3(fp, descr, name, value);
}
@@ -155,8 +154,7 @@
[CallConvCdecl()]
public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) {
-
- // check for non-subclassable type here.
+ // Note that this is still very incomplete!!!
int len = Runtime.PyTuple_Size(args);
if (len < 3) {
@@ -183,7 +181,7 @@
}
IntPtr basetype = Runtime.PyTuple_GetItem(bases, 0);
- if (Runtime.PyObject_Type(basetype) != PyCLRMetaType) {
+ if (Runtime.PyObject_TYPE(basetype) != PyCLRMetaType) {
Exceptions.SetError(Exceptions.TypeError,
"metatype is not managed metatype - should not happen!"
);
=== PythonNet/src/runtime/Runtime.cs 1.4 => 1.5 ===
--- PythonNet/src/runtime/Runtime.cs:1.4 Fri Aug 1 19:56:10 2003
+++ PythonNet/src/runtime/Runtime.cs Sat Aug 2 17:55:30 2003
@@ -24,9 +24,12 @@
/// </summary>
private static IntPtr MainThreadState;
+ private static bool Is32Bit;
internal static void Initialize() {
+ Is32Bit = IntPtr.Size == 4;
+
Runtime.Py_Initialize();
Runtime.PyEval_InitThreads();
@@ -37,6 +40,8 @@
IntPtr dict = Runtime.PyImport_GetModuleDict();
IntPtr op = Runtime.PyDict_GetItemString(dict, "__builtin__");
+
+
PyModuleType = Runtime.PyObject_Type(op);
PyNone = Runtime.PyObject_GetAttrString(op, "None");
PyNoneType = Runtime.PyObject_Type(PyNone);
@@ -74,20 +79,18 @@
PyFloatType = Runtime.PyObject_Type(op);
Runtime.Decref(op);
- IntPtr s = Runtime.PyString_FromString("__temp");
- IntPtr t = Runtime.PyTuple_New(0);
+ IntPtr s = Runtime.PyString_FromString("_temp");
IntPtr d = Runtime.PyDict_New();
- IntPtr c = Runtime.PyClass_New(t, d, s);
+ IntPtr c = Runtime.PyClass_New(IntPtr.Zero, d, s);
+ PyClassType = Runtime.PyObject_Type(c);
- PyClassType = Runtime.PyObject_Type(c);
- IntPtr i = Runtime.PyInstance_New(c, t, d);
+ IntPtr i = Runtime.PyInstance_New(c, IntPtr.Zero, IntPtr.Zero);
PyInstanceType = Runtime.PyObject_Type(i);
Runtime.Decref(s);
- Runtime.Decref(t);
- Runtime.Decref(d);
Runtime.Decref(i);
Runtime.Decref(c);
+ Runtime.Decref(d);
Error = new IntPtr(-1);
@@ -114,54 +117,6 @@
}
}
- internal unsafe static void Incref(IntPtr op) {
- if (op != IntPtr.Zero) {
- (*(int *)op)++;
- }
- }
-
-
- internal unsafe static void Decref(IntPtr op) {
-
- // Py_DECREF is not exposed as a true function from the Python
- // dll, so we do the moral equivalent with managed code. This
- // also means we need to call an arbitrary function pointer,
- // which is not fun from C# :( Note to self: remember to lobby
- // Guido or Tim for an exported alias in the runtime!
-
- if (op != IntPtr.Zero) {
- if (--(*(int *)op) == 0) {
- //string nn = PyObject_GetTypeName(op);
- //Console.WriteLine("decref: {0}", nn);
- IntPtr tp = Marshal.ReadIntPtr(op, (1 * IntPtr.Size));
- IntPtr fp = Marshal.ReadIntPtr(tp, (6 * IntPtr.Size));
- if (fp == IntPtr.Zero) {
- return;
- }
- NativeCall.Impl.Void_Call_1(fp, op);
- return;
- }
- }
-
- }
-
- internal unsafe static int GetRefCount(IntPtr op) {
- if (op == IntPtr.Zero)
- return 0;
- return *(int *)op;
- }
-
- // Utility to return the name of an object's type as a string.
-
- internal static string PyObject_GetTypeName(IntPtr op) {
- IntPtr pyType = Marshal.ReadIntPtr(op, IntPtr.Size);
- IntPtr ppName = Marshal.ReadIntPtr(pyType, (3 * IntPtr.Size));
- return Marshal.PtrToStringAnsi(ppName);
- }
-
-
-
-
internal static IntPtr PyModuleType;
internal static IntPtr PyClassType;
@@ -183,6 +138,43 @@
internal static IntPtr Error;
+
+
+ //===================================================================
+ // Managed exports of the Python C API. Where appropriate, we do
+ // some optimization to avoid managed <--> unmanaged transitions
+ // (mostly for heavily used methods).
+ //===================================================================
+
+ internal unsafe static void Incref(IntPtr op) {
+ void *p = (void *)op;
+ if ((void *)0 != p) {
+ if (Is32Bit) { (*(int *)p)++; }
+ else { (*(long *)p)++; }
+ }
+ }
+
+ internal unsafe static void Decref(IntPtr op) {
+ void *p = (void *)op;
+ if ((void *)0 != p) {
+ if (Is32Bit) { --(*(int *)p); }
+ else { --(*(long *)p); }
+ if ((*(int *)p) == 0) {
+ //string nn = PyObject_GetTypeName(op);
+ //Console.WriteLine("decref: {0}", nn);
+ void *t = Is32Bit ? (void *)(*((uint *)p + 1)) :
+ (void *)(*((ulong *)p + 1));
+ void *f = Is32Bit ? (void *)(*((uint *)t + 6)) :
+ (void *)(*((ulong *)t + 6));
+ if ((void *)0 == f) {
+ return;
+ }
+ NativeCall.Impl.Void_Call_1(new IntPtr(f), op);
+ return;
+ }
+ }
+ }
+
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern void
@@ -223,9 +215,6 @@
public unsafe static extern int
Py_Main(int argc, string[] argv);
-
- // Thread state operations
-
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern void
@@ -261,9 +250,6 @@
internal unsafe static extern void
PyEval_RestoreThread(IntPtr tstate);
-
- // Miscellaneous high-level runtime APIs
-
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern string
@@ -314,13 +300,69 @@
internal unsafe static extern int
PyRun_SimpleString(string code);
+ [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
+ ExactSpelling=true, CharSet=CharSet.Ansi)]
+ internal unsafe static extern IntPtr
+ PyCFunction_New(IntPtr ml, IntPtr self);
- // Python abstract object API
+ [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
+ ExactSpelling=true, CharSet=CharSet.Ansi)]
+ internal unsafe static extern IntPtr
+ PyCFunction_Call(IntPtr func, IntPtr args, IntPtr kw);
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
- internal unsafe static extern IntPtr
- PyObject_Type(IntPtr pointer);
+ internal unsafe static extern IntPtr
+ PyClass_New(IntPtr bases, IntPtr dict, IntPtr name);
+
+ [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
+ ExactSpelling=true, CharSet=CharSet.Ansi)]
+ internal unsafe static extern IntPtr
+ PyInstance_New(IntPtr cls, IntPtr args, IntPtr kw);
+
+ [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
+ ExactSpelling=true, CharSet=CharSet.Ansi)]
+ internal unsafe static extern IntPtr
+ PyMethod_New(IntPtr func, IntPtr self, IntPtr cls);
+
+
+ //====================================================================
+ // Python abstract object API
+ //====================================================================
+
+ // A macro-like method to get the type of a Python object. This is
+ // designed to be lean and mean and avoid managed <-> unmanaged
+ // transitions. Note that this does not incref the type object.
+
+ internal unsafe static IntPtr
+ PyObject_TYPE(IntPtr op) {
+ void *p = (void *)op;
+ if ((void *)0 == p) {
+ return IntPtr.Zero;
+ }
+ if (Is32Bit) {
+ return new IntPtr((void *)(*((uint *)p + 1)));
+ }
+ else {
+ return new IntPtr((void *)(*((ulong *)p + 1)));
+ }
+ }
+
+ // Managed version of the standard Python C API PyObject_Type call.
+ // This version avoids a managed <-> unmanaged transition.
+
+ internal unsafe static IntPtr
+ PyObject_Type(IntPtr op) {
+ IntPtr tp = PyObject_TYPE(op);
+ Runtime.Incref(tp);
+ return tp;
+ }
+
+ internal static string PyObject_GetTypeName(IntPtr op) {
+ IntPtr pyType = Marshal.ReadIntPtr(op, IntPtr.Size);
+ IntPtr ppName = Marshal.ReadIntPtr(pyType, (3 * IntPtr.Size));
+ return Marshal.PtrToStringAnsi(ppName);
+ }
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
@@ -377,8 +419,6 @@
internal unsafe static extern IntPtr
PyObject_CallObject(IntPtr pointer, IntPtr args);
-
-
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern int
@@ -425,7 +465,9 @@
PyObject_Str(IntPtr pointer);
- // Python numeric methods
+ //====================================================================
+ // Python number API
+ //====================================================================
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
@@ -443,9 +485,8 @@
PyNumber_Float(IntPtr ob);
-
internal static bool PyInt_Check(IntPtr ob) {
- return PyObject_Type(ob) == Runtime.PyIntType;
+ return PyObject_TYPE(ob) == Runtime.PyIntType;
}
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
@@ -470,7 +511,7 @@
internal static bool PyLong_Check(IntPtr ob) {
- return PyObject_Type(ob) == Runtime.PyLongType;
+ return PyObject_TYPE(ob) == Runtime.PyLongType;
}
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
@@ -498,7 +539,6 @@
internal unsafe static extern IntPtr
PyLong_FromUnsignedLongLong(ulong value);
-
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern IntPtr
@@ -524,8 +564,6 @@
internal unsafe static extern ulong
PyLong_AsUnsignedLongLong(IntPtr value);
-
-
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern IntPtr
@@ -542,12 +580,9 @@
PyFloat_AsDouble(IntPtr ob);
-
-
-
-
-
- // Python abstract sequence API
+ //====================================================================
+ // Python sequence API
+ //====================================================================
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
@@ -611,16 +646,17 @@
PySequence_List(IntPtr pointer);
-
- // Python string methods
+ //====================================================================
+ // Python string API
+ //====================================================================
internal static bool IsStringType(IntPtr op) {
- IntPtr t = PyObject_Type(op);
+ IntPtr t = PyObject_TYPE(op);
return (t == PyStringType) || (t == PyUnicodeType);
}
internal static bool PyString_Check(IntPtr ob) {
- return PyObject_Type(ob) == Runtime.PyStringType;
+ return PyObject_TYPE(ob) == Runtime.PyStringType;
}
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
@@ -650,10 +686,8 @@
PyString_Size(IntPtr pointer);
- // Python unicode methods. Note that these support UCS-2 only!
-
internal static bool PyUnicode_Check(IntPtr ob) {
- return PyObject_Type(ob) == Runtime.PyUnicodeType;
+ return PyObject_TYPE(ob) == Runtime.PyUnicodeType;
}
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
@@ -668,7 +702,6 @@
internal unsafe static extern IntPtr
PyUnicode_FromEncodedObject(IntPtr ob, IntPtr enc, IntPtr err);
-
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
EntryPoint="PyUnicodeUCS2_FromUnicode",
ExactSpelling=true, CharSet=CharSet.Unicode)]
@@ -679,9 +712,6 @@
return PyUnicode_FromUnicode(s, (s.Length));
}
-
-
-
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
EntryPoint="PyUnicodeUCS2_GetSize",
ExactSpelling=true, CharSet=CharSet.Ansi)]
@@ -706,7 +736,7 @@
PyUnicode_FromOrdinal(int c);
internal unsafe static string GetManagedString(IntPtr op) {
- IntPtr type = PyObject_Type(op);
+ IntPtr type = PyObject_TYPE(op);
if (type == Runtime.PyStringType) {
return Runtime.PyString_AsString(op);
}
@@ -716,14 +746,15 @@
return new String(p, 0, size);
}
return null;
-
}
- // Python dict methods
+ //====================================================================
+ // Python dictionary API
+ //====================================================================
internal static bool PyDict_Check(IntPtr ob) {
- return PyObject_Type(ob) == Runtime.PyDictType;
+ return PyObject_TYPE(ob) == Runtime.PyDictType;
}
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
@@ -802,10 +833,12 @@
PyDict_Size(IntPtr pointer);
- // Python list methods
+ //====================================================================
+ // Python list API
+ //====================================================================
internal static bool PyList_Check(IntPtr ob) {
- return PyObject_Type(ob) == Runtime.PyListType;
+ return PyObject_TYPE(ob) == Runtime.PyListType;
}
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
@@ -864,10 +897,12 @@
PyList_Size(IntPtr pointer);
- // Python tuple methods
+ //====================================================================
+ // Python tuple API
+ //====================================================================
internal static bool PyTuple_Check(IntPtr ob) {
- return PyObject_Type(ob) == Runtime.PyTupleType;
+ return PyObject_TYPE(ob) == Runtime.PyTupleType;
}
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
@@ -896,7 +931,9 @@
PyTuple_Size(IntPtr pointer);
- // Python module methods
+ //====================================================================
+ // Python module API
+ //====================================================================
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
@@ -913,9 +950,6 @@
internal unsafe static extern string
PyModule_GetFilename(IntPtr module);
-
-
-
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern IntPtr
@@ -958,9 +992,9 @@
PySys_SetObject(string name, IntPtr ob);
-
-
- // Type related methods
+ //====================================================================
+ // Python type object API
+ //====================================================================
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
@@ -968,7 +1002,7 @@
PyType_IsSubtype(IntPtr t1, IntPtr t2);
internal static bool PyObject_TypeCheck(IntPtr ob, IntPtr tp) {
- IntPtr t = PyObject_Type(ob);
+ IntPtr t = PyObject_TYPE(ob);
return (t == tp) || PyType_IsSubtype(t, tp);
}
@@ -1008,28 +1042,9 @@
_PyObject_GetDictPtr(IntPtr obj);
- [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
- ExactSpelling=true, CharSet=CharSet.Ansi)]
- internal unsafe static extern IntPtr
- PyCFunction_New(IntPtr ml, IntPtr self);
-
- [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
- ExactSpelling=true, CharSet=CharSet.Ansi)]
- internal unsafe static extern IntPtr
- PyCFunction_Call(IntPtr func, IntPtr args, IntPtr kw);
-
-
- [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
- ExactSpelling=true, CharSet=CharSet.Ansi)]
- internal unsafe static extern IntPtr
- PyClass_New(IntPtr bases, IntPtr dict, IntPtr name);
-
- [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
- ExactSpelling=true, CharSet=CharSet.Ansi)]
- internal unsafe static extern IntPtr
- PyInstance_New(IntPtr cls, IntPtr args, IntPtr kw);
-
-
+ //====================================================================
+ // Python memory API
+ //====================================================================
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
@@ -1046,15 +1061,10 @@
internal unsafe static extern void
PyMem_Free(IntPtr ptr);
- [DllImport("python22", CallingConvention=CallingConvention.Cdecl,
- ExactSpelling=true, CharSet=CharSet.Ansi)]
- internal unsafe static extern IntPtr
- PyMethod_New(IntPtr func, IntPtr self, IntPtr cls);
-
-
-
- // Exception APIs
+ //====================================================================
+ // Python exception API
+ //====================================================================
[DllImport("python22", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
=== PythonNet/src/runtime/TypeManager.cs 1.4 => 1.5 ===
--- PythonNet/src/runtime/TypeManager.cs:1.4 Wed Jul 30 09:55:50 2003
+++ PythonNet/src/runtime/TypeManager.cs Sat Aug 2 17:55:30 2003
@@ -185,32 +185,10 @@
IntPtr o = FinishType(pyTypeObj);
InitMethods(o, obType);
- unscrew(o);
return o;
}
- internal static void unscrew(IntPtr op) {
- IntPtr pname = Marshal.ReadIntPtr(op, (3 * IntPtr.Size));
- string name = Marshal.PtrToStringAnsi(pname);
-
- int flags = (int)Marshal.ReadIntPtr(op, (21 * IntPtr.Size));
- if ((flags & (1 << 14)) != 0) {
- Console.WriteLine("type {0} is GC!", name);
- }
-
- IntPtr mro = Marshal.ReadIntPtr(op, (43 * IntPtr.Size));
- if (mro == IntPtr.Zero) {
- Console.WriteLine("type {0} has null mro", name);
- }
- else {
- if (Runtime.PyObject_Type(mro) != Runtime.PyTupleType) {
- Console.WriteLine("type {0} non-tuple mro", name);
- }
- }
-
-
- }
// Initialize a new binary-compatible PyTypeObject for a Python
// type that reflects a managed type.
@@ -249,8 +227,6 @@
IntPtr op = FinishType(pyTypeObj);
obj.pyHandle = op;
-
- unscrew(op);
return op;
}
More information about the Zope-CVS
mailing list