[pypy-dev] genpyrex -> genc ?

Armin Rigo arigo at tunes.org
Tue Aug 17 21:21:45 CEST 2004


Hello,

Perhaps generating Pyrex code isn't such a great idea.  The great idea was to
use CPython as an intermediate target.  But writing C extension modules in C  
instead of in Pyrex is quite possibly much cleaner, because: 
 
* very basic C code is sufficient; 
 
* removing yet another intermediate step might not be a bad idea for clarity;
  
* reference counting is easy because we know exactly when variables get out of
  scope: when they reach the end of a basic block and are not sent to the next
  block;
  
* we don't have to work around various Pyrex restrictions (or hack Pyrex to
  lift them);
  
* most importantly, the whole mess with the "class Op" in genpyrex.py can 
  probably be completely omitted, because we can use C macros and generate
  just a succession of OP_XXX(a,b,c) where XXX is the operation name and
  a,b,c are the arguments.  Mapping the operations to actual C code is done
  once and for all in a C header file with macro definitions.

A quick-test (borring from genpyrex.py) is checked in a branch in
http://www.codespeak.net/svn/pypy/branch/pypy-genc/ producing (not yet
compilable) C code that looks like the attached example. It looks much like
assembler code.  It's quite readable and easy to map to the original flow
graph, too.

Not sure what to do now.  Does this look like a good idea?


A bientôt,

Armin.
-------------- next part --------------

/************************************************************/
 /***  Generic C header section                            ***/

#include <Python.h>

#define FREE(x)  Py_DECREF(x)


/************************************************************/
 /***  The rest is produced by genc.py                     ***/

/* forward declarations */
static PyObject* is_perfect_number__e653614(PyObject* v1);

/************************************************************/

PyObject* is_perfect_number__e653614(PyObject* v1)
{
	PyObject* v1;
	PyObject* v3;
	PyObject* v26;
	PyObject* v27;
	PyObject* v66;
	PyObject* v67;
	PyObject* v68;
	PyObject* v69;
	PyObject* v70;
	PyObject* v107;
	PyObject* v108;
	PyObject* v109;
	PyObject* v110;
	PyObject* v111;
	PyObject* v73;
	PyObject* v74;
	PyObject* v75;
	PyObject* v76;
	PyObject* v77;
	PyObject* v78;
	PyObject* v79;
	PyObject* v80;
	PyObject* v2;
	PyObject* v112;
	PyObject* v113;
	PyObject* v114;
	PyObject* v115;
	PyObject* v116;
	PyObject* v83;
	PyObject* v84;
	PyObject* v85;
	PyObject* v117;
	PyObject* v118;
	PyObject* v119;
	PyObject* v120;
	PyObject* v121;
	PyObject* v122;
	PyObject* v123;
	PyObject* v124;
	PyObject* v91;
	PyObject* v92;
	PyObject* v93;
	PyObject* v94;
	PyObject* v62;
	PyObject* v63;
	PyObject* v64;
	PyObject* v65;
	PyObject* v125;
	PyObject* v126;
	PyObject* v127;
	PyObject* v128;
	PyObject* v129;
	PyObject* v130;
	PyObject* v131;
	PyObject* v132;
	PyObject* v103;

  block0:
	v3 = v1;
	goto block1;

  block1:
	v26 = v3;
	v27 = (1);
	goto block2;

  block2:
	v66 = v26;
	v67 = v27;
	v68 = (0);
	goto block3;

  block3:
	OP_LT(v67, v66, v69)
	OP_IS_TRUE(v69, v70)
	CASE(v70, False) {
		v107 = v66;
		v108 = v67;
		v109 = v68;
		v110 = v69;
		v111 = v70;
		goto block4;
	}
	ELSE(v70, True) {
		v112 = v66;
		v113 = v67;
		v114 = v68;
		v115 = v69;
		v116 = v70;
		goto block8;
	}
  block4:
	FREE(v111)
	v73 = v107;
	v74 = v108;
	v75 = v109;
	v76 = v110;
	goto block5;

  block5:
	FREE(v76)
	v77 = v73;
	v78 = v74;
	v79 = v75;
	goto block6;

  block6:
	OP_EQ(v77, v79, v80)
	FREE(v77)
	FREE(v78)
	FREE(v79)
	v2 = v80;
	goto block7;

  block7:
	return v2;

  block8:
	OP_MOD(v112, v113, v83)
	OP_EQ(v83, (0), v84)
	OP_IS_TRUE(v84, v85)
	CASE(v85, False) {
		v117 = v112;
		v118 = v113;
		v119 = v114;
		v120 = v115;
		v121 = v116;
		v122 = v83;
		v123 = v84;
		v124 = v85;
		goto block9;
	}
	ELSE(v85, True) {
		v125 = v112;
		v126 = v113;
		v127 = v114;
		v128 = v115;
		v129 = v116;
		v130 = v83;
		v131 = v84;
		v132 = v85;
		goto block12;
	}
  block9:
	FREE(v120)
	FREE(v121)
	FREE(v122)
	FREE(v124)
	v91 = v117;
	v92 = v118;
	v93 = v119;
	v94 = v123;
	goto block10;

  block10:
	FREE(v94)
	v62 = v91;
	v63 = v92;
	v64 = v93;
	goto block11;

  block11:
	OP_INPLACE_ADD(v63, (1), v65)
	FREE(v63)
	v66 = v62;
	v67 = v65;
	v68 = v64;
	goto block3;

  block12:
	OP_INPLACE_ADD(v127, v126, v103)
	FREE(v127)
	FREE(v128)
	FREE(v129)
	FREE(v130)
	FREE(v131)
	FREE(v132)
	v62 = v125;
	v63 = v126;
	v64 = v103;
	goto block11;

}

/************************************************************/

static PyObject* c_is_perfect_number(PyObject* self, PyObject* args)
{

	PyObject* a0;
	if (!PyArg_ParseTuple(args, "O", &a0))
		return NULL;
	return is_perfect_number__e653614(a0);

}


static PyMethodDef is_perfect_numberMethods[] = {
	{"is_perfect_number", (PyCFunction)c_is_perfect_number, METH_VARARGS},
	{NULL, NULL}
};


void initis_perfect_number(void)
{
	Py_InitModule("is_perfect_number", is_perfect_numberMethods);
}



More information about the Pypy-dev mailing list