From: Armin R. <ar...@us...> - 2001-12-28 12:35:40
|
Update of /cvsroot/psyco/psyco/c/Objects In directory usw-pr-cvs1:/tmp/cvs-serv24457 Modified Files: pdescrobject.c pfuncobject.c plistobject.h pmethodobject.c pmethodobject.h pobject.c pobject.h pstringobject.h psycofuncobject.c Added Files: pclassobject.c pclassobject.h Log Message: support for C methods and instance methods --- NEW FILE: pclassobject.c --- #include "pclassobject.h" #include "ptupleobject.h" DEFINEFN vinfo_t* PsycoMethod_New(PyObject* func, vinfo_t* self, PyObject* cls) { vinfo_t* result = vinfo_new(VirtualTime_New(&psyco_computed_method)); extra_assert(METHOD_SIZE > METHOD_IM_FUNC); extra_assert(METHOD_SIZE > METHOD_IM_SELF); extra_assert(METHOD_SIZE > METHOD_IM_CLASS); result->array = array_new(METHOD_SIZE); result->array->items[OB_TYPE] = vinfo_new(CompileTime_New((long)(&PyMethod_Type))); Py_INCREF(func); result->array->items[METHOD_IM_FUNC] = vinfo_new(CompileTime_NewSk(sk_new((long) func, SkFlagPyObj))); vinfo_incref(self); result->array->items[METHOD_IM_SELF] = self; Py_INCREF(cls); result->array->items[METHOD_IM_CLASS] = vinfo_new(CompileTime_NewSk(sk_new((long) cls, SkFlagPyObj))); return result; } static bool compute_method(PsycoObject* po, vinfo_t* methobj) { vinfo_t* newobj; vinfo_t* im_func; vinfo_t* im_self; vinfo_t* im_class; /* get the fields from the Python object 'methobj' */ im_func = get_array_item(po, methobj, METHOD_IM_FUNC); if (im_func == NULL) return false; im_self = get_array_item(po, methobj, METHOD_IM_SELF); if (im_self == NULL) return false; im_class = get_array_item(po, methobj, METHOD_IM_CLASS); if (im_class == NULL) return false; /* call PyMethod_New() */ newobj = psyco_generic_call(po, PyMethod_New, CfPure|CfReturnRef|CfPyErrIfNull, "vvv", im_func, im_self, im_class); if (newobj == NULL) return false; /* move the resulting non-virtual Python object back into 'methobj' */ vinfo_move(po, methobj, newobj); return true; } DEFINEVAR source_virtual_t psyco_computed_method; /***************************************************************/ /*** instance method objects meta-implementation ***/ static vinfo_t* pinstancemethod_call(PsycoObject* po, vinfo_t* methobj, vinfo_t* arg, vinfo_t* kw) { vinfo_t* im_func; vinfo_t* im_self; vinfo_t* result; /* get the 'im_self' field from the Python object 'methobj' */ im_self = get_array_item(po, methobj, METHOD_IM_SELF); if (im_self == NULL) return NULL; if (psyco_knowntobe(im_self, (long) NULL)) { /* Unbound methods, XXX implement me */ goto fallback; } else { int argcount = PsycoTuple_Load(arg); int i; vinfo_t* newarg; if (argcount < 0) goto fallback; newarg = PsycoTuple_New(argcount+1, NULL); vinfo_incref(im_self); PsycoTuple_GET_ITEM(newarg, 0) = im_self; for (i = 0; i < argcount; i++) { vinfo_t* v = PsycoTuple_GET_ITEM(arg, i); vinfo_incref(v); PsycoTuple_GET_ITEM(newarg, i+1) = v; } arg = newarg; } im_func = get_array_item(po, methobj, METHOD_IM_FUNC); if (im_func == NULL) result = NULL; else result = PsycoObject_Call(po, im_func, arg, kw); vinfo_decref(arg, po); return result; fallback: return psyco_generic_call(po, PyMethod_Type.tp_call, CfReturnRef|CfPyErrIfNull, "vvv", methobj, arg, kw); } DEFINEFN void psy_classobject_init() { Psyco_DefineMeta(PyMethod_Type.tp_call, pinstancemethod_call); psyco_computed_method.compute_fn = &compute_method; } --- NEW FILE: pclassobject.h --- /***************************************************************/ /*** Psyco equivalent of classobject.h ***/ /***************************************************************/ #ifndef _PSY_CLASSOBJECT_H #define _PSY_CLASSOBJECT_H #include "pobject.h" #include "pabstract.h" /* Instance methods */ #define METHOD_IM_FUNC QUARTER(offsetof(PyMethodObject, im_func)) #define METHOD_IM_SELF QUARTER(offsetof(PyMethodObject, im_self)) #define METHOD_IM_CLASS QUARTER(offsetof(PyMethodObject, im_class)) #define METHOD_SIZE (METHOD_IM_CLASS+1) /***************************************************************/ /*** Virtual-time object builder ***/ /* not-yet-computed instance method objects. Usually not computed at all, but if it needs be, will call PyMethod_New(). */ EXTERNVAR source_virtual_t psyco_computed_method; EXTERNFN vinfo_t* PsycoMethod_New(PyObject* func, vinfo_t* self, PyObject* cls); EXTERNFN void psy_classobject_init(void); #endif /* _PSY_CLASSOBJECT_H */ Index: pdescrobject.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pdescrobject.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pdescrobject.c 2001/12/27 21:51:48 1.1 --- pdescrobject.c 2001/12/28 12:35:37 1.2 *************** *** 1,3 **** --- 1,5 ---- #include "pdescrobject.h" + #include "pstructmember.h" + #include "pmethodobject.h" *************** *** 10,17 **** immediate values for the other two arguments. */ ! /* We assume that 'obj' is a valid instance of 'type'. */ return PsycoMember_GetOne(po, obj, descr->d_member); } DEFINEFN --- 12,27 ---- immediate values for the other two arguments. */ ! /* XXX We assume that 'obj' is a valid instance of 'type'. */ return PsycoMember_GetOne(po, obj, descr->d_member); } + static vinfo_t* pmethod_get(PsycoObject* po, PyMethodDescrObject* descr, + vinfo_t* obj, PyTypeObject *type) + { + /* a meta-implementation for method_get() of descrobject.c. + Same remarks as for pmember_get(). */ + return PsycoCFunction_New(po, descr->d_method, obj); + } + DEFINEFN *************** *** 20,24 **** --- 30,36 ---- PyObject* dummy; PyTypeObject* PyMemberDescr_Type; + PyTypeObject* PyMethodDescr_Type; PyMemberDef dummydef; + PyMethodDef dummydef2; /* Member descriptors */ *************** *** 32,34 **** --- 44,57 ---- Psyco_DefineMeta(PyMemberDescr_Type->tp_descr_get, pmember_get); + + /* C Method descriptors */ + /* any better way to get a pointer to PyMethodDescr_Type? */ + memset(&dummydef2, 0, sizeof(dummydef2)); + dummydef2.ml_name = "dummy"; + dummy = PyDescr_NewMethod(&PsycoFunction_Type, &dummydef2); + PyMethodDescr_Type = dummy->ob_type; + Py_DECREF(dummy); + + Psyco_DefineMeta(PyMethodDescr_Type->tp_descr_get, + pmethod_get); } Index: pfuncobject.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pfuncobject.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pfuncobject.c 2001/12/13 13:16:35 1.2 --- pfuncobject.c 2001/12/28 12:35:37 1.3 *************** *** 1,3 **** --- 1,4 ---- #include "pfuncobject.h" + #include "pclassobject.h" *************** *** 22,28 **** --- 23,42 ---- + static vinfo_t* pfunc_descr_get(PsycoObject* po, PyObject* func, + vinfo_t* obj, PyObject* type) + { + /* see comments of pmember_get() in pdescrobject.c. */ + + /* XXX obj is never Py_None here in the current implementation, + but could be if called by other routines than + PsycoObject_GenericGetAttr(). */ + return PsycoMethod_New(func, obj, type); + } + + DEFINEFN void psy_funcobject_init() { Psyco_DefineMeta(PyFunction_Type.tp_call, pfunction_call); + Psyco_DefineMeta(PyFunction_Type.tp_descr_get, pfunc_descr_get); } Index: plistobject.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/plistobject.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** plistobject.h 2001/12/06 15:48:25 1.2 --- plistobject.h 2001/12/28 12:35:37 1.3 *************** *** 17,21 **** ! EXTERNFN void psy_listobject_init(void); /* nothing */ #endif /* _PSY_LISTOBJECT_H */ --- 17,21 ---- ! EXTERNFN void psy_listobject_init(void); #endif /* _PSY_LISTOBJECT_H */ Index: pmethodobject.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pmethodobject.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pmethodobject.c 2001/12/04 16:12:07 1.1 --- pmethodobject.c 2001/12/28 12:35:37 1.2 *************** *** 3,6 **** --- 3,39 ---- + static bool compute_cfunction(PsycoObject* po, vinfo_t* methobj) + { + vinfo_t* newobj; + vinfo_t* m_self; + vinfo_t* m_ml; + + /* get the fields from the Python object 'methobj' */ + m_self = get_array_item(po, methobj, CFUNC_M_SELF); + if (m_self == NULL) + return false; + m_ml = get_array_item(po, methobj, CFUNC_M_ML); + if (m_ml == NULL) + return false; + + /* call PyCFunction_New() */ + newobj = psyco_generic_call(po, PyCFunction_New, + CfPure|CfReturnRef|CfPyErrIfNull, + "vv", m_ml, m_self); + if (newobj == NULL) + return false; + + /* move the resulting non-virtual Python object back into 'methobj' */ + vinfo_move(po, methobj, newobj); + return true; + } + + + DEFINEVAR source_virtual_t psyco_computed_cfunction; + + + /***************************************************************/ + /*** C method objects meta-implementation ***/ + static vinfo_t* PsycoCFunction_Call(PsycoObject* po, vinfo_t* func, vinfo_t* tuple, vinfo_t* kw) *************** *** 67,69 **** --- 100,104 ---- { Psyco_DefineMeta(PyCFunction_Type.tp_call, PsycoCFunction_Call); + + psyco_computed_cfunction.compute_fn = &compute_cfunction; } Index: pmethodobject.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pmethodobject.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pmethodobject.h 2001/12/06 15:48:25 1.2 --- pmethodobject.h 2001/12/28 12:35:37 1.3 *************** *** 13,16 **** --- 13,40 ---- #define CFUNC_M_ML QUARTER(offsetof(PyCFunctionObject, m_ml)) #define CFUNC_M_SELF QUARTER(offsetof(PyCFunctionObject, m_self)) + #define CFUNC_SIZE (CFUNC_M_SELF+1) + + + /***************************************************************/ + /*** Virtual-time object builder ***/ + + /* not-yet-computed C method objects, with a m_ml and m_self field. + Usually not computed at all, but if it needs be, will call + PyCFunction_New(). */ + EXTERNVAR source_virtual_t psyco_computed_cfunction; + + inline vinfo_t* PsycoCFunction_New(PsycoObject* po, PyMethodDef* ml, + vinfo_t* self) + { + vinfo_t* result = vinfo_new(VirtualTime_New(&psyco_computed_cfunction)); + result->array = array_new(CFUNC_SIZE); + result->array->items[OB_TYPE] = + vinfo_new(CompileTime_New((long)(&PyCFunction_Type))); + result->array->items[CFUNC_M_ML] = + vinfo_new(CompileTime_New((long) ml)); + vinfo_incref(self); + result->array->items[CFUNC_M_SELF] = self; + return result; + } Index: pobject.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pobject.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pobject.c 2001/12/26 16:59:50 1.3 --- pobject.c 2001/12/28 12:35:37 1.4 *************** *** 8,11 **** --- 8,12 ---- DEFINEVAR fixed_switch_t psyfs_tuple_list; DEFINEVAR fixed_switch_t psyfs_string_unicode; + DEFINEVAR fixed_switch_t psyfs_none; *************** *** 251,282 **** if (dictofsbase == -1) { if (PycException_Occurred(po)) ! return NULL; /* no __dict__ slot */ } else { int cond; vinfo_t* dict; if (dictofs == NULL) ! dict = read_array_item(po, obj, dictofsbase); else dict = read_array_item_var(po, obj, ! dictofsbase, dictofs, false); if (dict == NULL) ! return NULL; ! cond = runtime_condition_t(po, integer_non_null(po, dict)); ! vinfo_decref(dict, po); ! if (cond) { /* the __dict__ slot contains a non-NULL value */ res = psyco_generic_call(po, PyDict_GetItem, CfReturnNormal, "vl", dict, name); if (res == NULL) ! return NULL; Py_INCREF(name); /* XXX ref hold by the code buf */ ! if (runtime_condition_t(po, integer_non_null(po, res))) { need_reference(po, res); goto done; } } } --- 252,299 ---- if (dictofsbase == -1) { if (PycException_Occurred(po)) ! goto done; /* no __dict__ slot */ } else { int cond; + condition_code_t cc; vinfo_t* dict; if (dictofs == NULL) ! dict = read_array_item(po, obj, QUARTER(dictofsbase)); else dict = read_array_item_var(po, obj, ! QUARTER(dictofsbase), ! dictofs, false); if (dict == NULL) ! goto done; ! if (runtime_condition_t(po, integer_non_null(po, dict))) { /* the __dict__ slot contains a non-NULL value */ res = psyco_generic_call(po, PyDict_GetItem, CfReturnNormal, "vl", dict, name); + vinfo_decref(dict, po); if (res == NULL) ! goto done; Py_INCREF(name); /* XXX ref hold by the code buf */ ! ! /* if there is a method descriptor of the same name, ! then it is likely that we don't find an attribute ! with that name; otherwise, it is likely that we ! do find it. */ ! cc = integer_non_null(po, res); ! if (f != NULL) ! cond = runtime_condition_f(po, cc); ! else ! cond = runtime_condition_t(po, cc); ! ! if (cond) { need_reference(po, res); goto done; } + vinfo_decref(res, po); + res = NULL; } + else + vinfo_decref(dict, po); } Index: pobject.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pobject.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pobject.h 2001/12/26 16:59:50 1.3 --- pobject.h 2001/12/28 12:35:37 1.4 *************** *** 122,127 **** --- 122,135 ---- EXTERNVAR fixed_switch_t psyfs_tuple_list; EXTERNVAR fixed_switch_t psyfs_string_unicode; + EXTERNVAR fixed_switch_t psyfs_none; + /* To check whether an object is Py_None. Return 0 if it is, + and -1 otherwise (use PycException_Occurred() to check for exceptions) */ + inline int Psyco_IsNone(PsycoObject* po, vinfo_t* vi) { + return Psyco_TypeSwitch(po, vi, &psyfs_none); + } + + inline void psy_object_init(void) { *************** *** 149,152 **** --- 157,163 ---- psyco_build_run_time_switch(&psyfs_string_unicode, SkFlagFixed, values, cnt); + + values[0] = (long)(Py_None->ob_type); + psyco_build_run_time_switch(&psyfs_none, SkFlagFixed, values, 1); /* associate the Python implementation of some functions with Index: pstringobject.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/pstringobject.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pstringobject.h 2001/12/06 15:48:25 1.2 --- pstringobject.h 2001/12/28 12:35:37 1.3 *************** *** 35,39 **** ! EXTERNFN void psy_stringobject_init(void); /* nothing */ #endif /* _PSY_STRINGOBJECT_H */ --- 35,39 ---- ! EXTERNFN void psy_stringobject_init(void); #endif /* _PSY_STRINGOBJECT_H */ Index: psycofuncobject.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Objects/psycofuncobject.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** psycofuncobject.c 2001/12/04 16:12:07 1.1 --- psycofuncobject.c 2001/12/28 12:35:37 1.2 *************** *** 22,28 **** --- 22,37 ---- + static vinfo_t* meta_psy_descr_get(PsycoObject* po, PyObject* func, + vinfo_t* obj, PyObject* type) + { + /* see comments of pmember_get() in pdescrobject.c. */ + return PsycoMethod_New(func, obj, type); + } + + DEFINEFN void psy_psycofuncobject_init() { Psyco_DefineMeta(PsycoFunction_Type.tp_call, meta_psycofunction_call); + Psyco_DefineMeta(PsycoFunction_Type.tp_descr_get, meta_psy_descr_get); } |