PageRenderTime 25ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/nodebox/ext/psyco/src/c/Objects/pmethodobject.c

https://github.com/nodebox/nodebox-opengl
C | 141 lines | 109 code | 21 blank | 11 comment | 21 complexity | 6f741efbd05f4ffc6430e8b63514ce52 MD5 | raw file
  1. #include "pmethodobject.h"
  2. #include "ptupleobject.h"
  3. static bool compute_cfunction(PsycoObject* po, vinfo_t* methobj)
  4. {
  5. vinfo_t* newobj;
  6. vinfo_t* m_self;
  7. vinfo_t* m_ml;
  8. /* get the fields from the Python object 'methobj' */
  9. m_self = vinfo_getitem(methobj, iCFUNC_M_SELF);
  10. if (m_self == NULL)
  11. return false;
  12. m_ml = vinfo_getitem(methobj, iCFUNC_M_ML);
  13. if (m_ml == NULL)
  14. return false;
  15. /* call PyCFunction_New() */
  16. #ifdef PyCFunction_New /* Python >= 2.3 introduced PyCFunction_NewEx() */
  17. newobj = psyco_generic_call(po, PyCFunction_NewEx,
  18. CfPure|CfReturnRef|CfPyErrIfNull,
  19. "vvl", m_ml, m_self, NULL);
  20. #else
  21. newobj = psyco_generic_call(po, PyCFunction_New,
  22. CfPure|CfReturnRef|CfPyErrIfNull,
  23. "vv", m_ml, m_self);
  24. #endif
  25. if (newobj == NULL)
  26. return false;
  27. /* move the resulting non-virtual Python object back into 'methobj' */
  28. vinfo_move(po, methobj, newobj);
  29. return true;
  30. }
  31. static PyObject* direct_compute_cfunction(vinfo_t* methobj, char* data)
  32. {
  33. PyObject* m_self;
  34. long m_ml;
  35. PyObject* result = NULL;
  36. m_self = direct_xobj_vinfo(
  37. vinfo_getitem(methobj, iCFUNC_M_SELF), data);
  38. m_ml = direct_read_vinfo(
  39. vinfo_getitem(methobj, iCFUNC_M_ML), data);
  40. if (!PyErr_Occurred())
  41. result = PyCFunction_New((PyMethodDef*) m_ml, m_self);
  42. Py_XDECREF(m_self);
  43. return result;
  44. }
  45. DEFINEVAR source_virtual_t psyco_computed_cfunction;
  46. /***************************************************************/
  47. /*** C method objects meta-implementation ***/
  48. DEFINEFN
  49. vinfo_t* PsycoCFunction_Call(PsycoObject* po, vinfo_t* func,
  50. vinfo_t* tuple, vinfo_t* kw)
  51. {
  52. long mllong;
  53. vinfo_t* vml = psyco_get_const(po, func, CFUNC_m_ml);
  54. if (vml == NULL)
  55. return NULL;
  56. /* promote to compile-time the function if we do not know which one
  57. it is yet */
  58. mllong = psyco_atcompiletime(po, vml);
  59. if (mllong == -1) {
  60. /* -1 is not a valid pointer */
  61. extra_assert(PycException_Occurred(po));
  62. return NULL;
  63. }
  64. else {
  65. PyMethodDef* ml = (PyMethodDef*) \
  66. CompileTime_Get(vml->source)->value;
  67. int flags = ml->ml_flags;
  68. int tuplesize;
  69. vinfo_t* carg;
  70. char* argumentlist = "vv";
  71. vinfo_t* vself = psyco_get_const(po, func, CFUNC_m_self);
  72. if (vself == NULL)
  73. return NULL;
  74. if (flags & METH_KEYWORDS) {
  75. return Psyco_META3(po, ml->ml_meth,
  76. CfReturnRef|CfPyErrIfNull,
  77. "vvv", vself, tuple, kw);
  78. }
  79. if (!psyco_knowntobe(kw, (long) NULL))
  80. goto use_proxy;
  81. switch (flags) {
  82. case METH_VARARGS:
  83. carg = tuple;
  84. break;
  85. case METH_NOARGS:
  86. tuplesize = PsycoTuple_Load(tuple);
  87. if (tuplesize != 0)
  88. /* if size unknown or known to be != 0 */
  89. goto use_proxy;
  90. carg = NULL;
  91. argumentlist = "vl";
  92. break;
  93. case METH_O:
  94. tuplesize = PsycoTuple_Load(tuple);
  95. if (tuplesize != 1)
  96. /* if size unknown or known to be != 1 */
  97. goto use_proxy;
  98. carg = PsycoTuple_GET_ITEM(tuple, 0);
  99. break;
  100. default:
  101. goto use_proxy;
  102. }
  103. return Psyco_META2(po, ml->ml_meth, CfReturnRef|CfPyErrIfNull,
  104. argumentlist, vself, carg);
  105. }
  106. /* default, slow version */
  107. use_proxy:
  108. return psyco_generic_call(po, PyCFunction_Call,
  109. CfReturnRef|CfPyErrIfNull,
  110. "vvv", func, tuple, kw);
  111. }
  112. INITIALIZATIONFN
  113. void psy_methodobject_init(void)
  114. {
  115. Psyco_DefineMeta(PyCFunction_Type.tp_call, PsycoCFunction_Call);
  116. INIT_SVIRTUAL(psyco_computed_cfunction, compute_cfunction,
  117. direct_compute_cfunction,
  118. (1 << iCFUNC_M_SELF),
  119. 1, 1);
  120. }