[Pyrex] Pyrex generates broken code when calling a function
immediately on the result of a C function call
Stefan Behnel
behnel_ml at gkec.informatik.tu-darmstadt.de
Mon Mar 27 12:43:41 CEST 2006
Hi,
Pyrex 0.9.3.1 generates broken code for the following statement:
-----------------------------
return _parseMemoryDocument(text, __DEFAULT_HTML_PARSER).getroot()
-----------------------------
_parseMemoryDocument is a C function, the type of getroot seems to be
unimportant (C or Python). The resulting C code is
-----------------------------
__pyx_1 = ((PyObject
*)__pyx_f_5etree__parseMemoryDocument(__pyx_v_text,((PyObject
*)__pyx_v_5etree___DEFAULT_HTML_PARSER))); if (!__pyx_1) {__pyx_filename =
__pyx_f[0]; __pyx_lineno = 1203; goto __pyx_L1;}
__pyx_2 = ((struct __pyx_vtabstruct_5etree__Document
*)__pyx_f_5etree__parseMemoryDocument(__pyx_v_text,((PyObject
*)__pyx_v_5etree___DEFAULT_HTML_PARSER))->__pyx_vtab)->getroot(__pyx_f_5etree__parseMemoryDocument(__pyx_v_text,((PyObject
*)__pyx_v_5etree___DEFAULT_HTML_PARSER))); if (!__pyx_2) {__pyx_filename =
__pyx_f[0]; __pyx_lineno = 1203; goto __pyx_L1;}
-----------------------------
As this shows, the C function is called three times. The work-around is to
separate the two function calls and to store the intermediate result in a
variable. This generates the following (expected) code:
-----------------------------
__pyx_1 = ((PyObject
*)__pyx_f_5etree__parseMemoryDocument(__pyx_v_text,((PyObject
*)__pyx_v_5etree___DEFAULT_HTML_PARSER))); if (!__pyx_1) {__pyx_filename =
__pyx_f[0]; __pyx_lineno = 1203; goto __pyx_L1;}
Py_DECREF(((PyObject *)__pyx_v_doc));
__pyx_v_doc = __pyx_1;
__pyx_1 = 0;
__pyx_1 = ((struct __pyx_vtabstruct_5etree__Document
*)__pyx_v_doc->__pyx_vtab)->getroot(__pyx_v_doc); if (!__pyx_1)
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 1204; goto __pyx_L1;}
__pyx_r = __pyx_1;
-----------------------------
The fix would be to replace the second and third call by __pyx_1, which is
correctly calculated in the first line.
Stefan
More information about the Pyrex
mailing list