[pypy-svn] r6390 - pypy/trunk/src/pypy/translator
arigo at codespeak.net
arigo at codespeak.net
Sat Sep 11 12:33:51 CEST 2004
Author: arigo
Date: Sat Sep 11 12:33:50 2004
New Revision: 6390
Modified:
pypy/trunk/src/pypy/translator/genc.h
pypy/trunk/src/pypy/translator/genc_op.py
pypy/trunk/src/pypy/translator/genc_typeset.py
pypy/trunk/src/pypy/translator/typer.py
Log:
Uniformly generates macro calls in the function bodies. It simplifies a bit
genc_op.py and more importantly it produces more readable C files. (suggested
by Holger)
Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h (original)
+++ pypy/trunk/src/pypy/translator/genc.h Sat Sep 11 12:33:50 2004
@@ -61,9 +61,9 @@
/*** conversions ***/
-#define convert_io(x,r,err) if (!(r=PyInt_FromLong(x))) goto err;
-#define convert_so(c,l,r,err) if (!(r=PyString_FromStringAndSize(c,l)))goto err;
-#define convert_vo(r) r = Py_None; Py_INCREF(r);
+#define CONVERT_io(x,r,err) if (!(r=PyInt_FromLong(x))) goto err;
+#define CONVERT_so(c,l,r,err) if (!(r=PyString_FromStringAndSize(c,l)))goto err;
+#define CONVERT_vo(r) r = Py_None; Py_INCREF(r);
/*#define convert_oi(x,r,err) if ((r=PyInt_AsLong(x)) == -1 \
* && PyErr_Occurred()) goto err;
@@ -71,15 +71,15 @@
/*** tests ***/
-#define caseFalse_i(n, err) if (n) goto err;
-#define caseTrue_i(n, err) if (!n) goto err;
-#define case0_i(n, err) if (n != 0) goto err;
-#define case1_i(n, err) if (n != 1) goto err;
-
-#define caseFalse_o(o, err) if (!(PyInt_Check(o) && !PyInt_AS_LONG(o))) goto err;
-#define caseTrue_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o))) goto err;
-#define case0_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==0)) goto err;
-#define case1_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==1)) goto err;
+#define CASE_False_i(n, err) if (n) goto err;
+#define CASE_True_i(n, err) if (!n) goto err;
+#define CASE_0_i(n, err) if (n != 0) goto err;
+#define CASE_1_i(n, err) if (n != 1) goto err;
+
+#define CASE_False_o(o, err) if (!(PyInt_Check(o) && !PyInt_AS_LONG(o))) goto err;
+#define CASE_True_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o))) goto err;
+#define CASE_0_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==0)) goto err;
+#define CASE_1_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==1)) goto err;
/*** misc ***/
@@ -95,25 +95,51 @@
} \
}
-#define INSTANTIATE(cls, r, err) if (!(r=cls##_new())) goto err;
+/* a few built-in functions */
+
+#define CALL_len_oi(o,r,err) if ((r=PyObject_Size(o))<0) goto err;
+#define CALL_pow_iii(x,y,r) { int i=y; r=1; while (--i>=0) r*=x; } /*slow*/
+
+
+/*** macros used directly by genc_op.py ***/
+
+#define OP_NEWLIST(len, r, err) if (!(r=PyList_New(len))) goto err;
+#define OP_NEWLIST_SET(r, i, o) PyList_SET_ITEM(r, i, o); Py_INCREF(o);
+#define OP_NEWTUPLE(len, r, err) if (!(r=PyTuple_New(len))) goto err;
+#define OP_NEWTUPLE_SET(r, i, o) PyTuple_SET_ITEM(r, i, o); Py_INCREF(o);
+
+#define OP_CALL_PYOBJ(args, r, err) if (!(r=PyObject_CallFunction args)) \
+ goto err;
+
+#define OP_INSTANTIATE(cls, r, err) if (!(r=cls##_new())) goto err;
#define ALLOC_INSTANCE(cls, r, err) \
if (!(r=PyType_GenericAlloc(&cls##_Type.type, 0))) goto err;
#define SETUP_TYPE(cls) \
PyType_Ready(&cls##_Type.type); \
cls##_typenew();
-#define GET_ATTR_py(fld, r) r=fld; Py_INCREF(r);
-#define SET_ATTR_py(fld, v) { PyObject* o=fld; fld=v; \
- Py_INCREF(v); Py_XDECREF(o); }
-
-#define GET_ATTR_cls(fld, r) r=fld; Py_INCREF(r);
-#define SET_ATTR_cls(fld, v) fld=v; Py_INCREF(v); /* initialization only */
-
-/* a few built-in functions */
-
-#define CALL_len_oi(o,r,err) if ((r=PyObject_Size(o))<0) goto err;
-#define CALL_pow_iii(x,y,r) { int i=y; r=1; while (--i>=0) r*=x; } /*slow*/
-
+#define OP_GETINSTATTR(cls, o, f, r) r=((cls##_Object*) o)->f;
+#define OP_GETINSTATTR_o(cls, o, f, r) r=((cls##_Object*) o)->f; Py_INCREF(r);
+#define OP_GETCLASSATTR(cls, o, f, r) r=((cls##_TypeObject*)(o->ob_type))->f;
+#define OP_GETCLASSATTR_o(cls, o, f, r) r=((cls##_TypeObject*)(o->ob_type))->f;\
+ Py_INCREF(r);
+#define OP_SETINSTATTR(cls, o, f, v) ((cls##_Object*) o)->f=v;
+#define OP_SETINSTATTR_o(cls, o, f, v) { PyObject* tmp; \
+ OP_GETINSTATTR(cls, o, f, tmp) \
+ OP_SETINSTATTR(cls, o, f, v) \
+ Py_INCREF(v); Py_XDECREF(tmp); \
+ }
+#define OP_INITCLASSATTR(cls, f, v) cls##_Type.f=v;
+#define OP_INITCLASSATTR_o(cls, f, v) cls##_Type.f=v; Py_INCREF(v);
+
+#define OP_DUMMYREF(r) r = Py_None; Py_INCREF(r);
+
+#define MOVE(x, y) y = x;
+
+#define OP_CCALL_v(fn, args, err) if (fn args < 0) goto err;
+#define OP_CCALL(fn, args, r, err) if ((r=fn args) == NULL) goto err;
+#define OP_CCALL_i(fn, args, r, err) if ((r=fn args) == -1 && \
+ PyErr_Occurred()) goto err;
/************************************************************/
/*** The rest is produced by genc.py ***/
Modified: pypy/trunk/src/pypy/translator/genc_op.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc_op.py (original)
+++ pypy/trunk/src/pypy/translator/genc_op.py Sat Sep 11 12:33:50 2004
@@ -81,21 +81,6 @@
def optimized_result(self, typer):
return self.known_answer
-class LoNewList(LoC):
- can_fail = True
- cost = 3
- # self.args: [input PyObjects.., output PyObject]
- def writestr(self, *stuff):
- content = stuff[:-2]
- result = stuff[-2]
- err = stuff[-1]
- ls = ['if (!(%s = PyList_New(%d))) goto %s;' % (
- result, len(content), err)]
- for i in range(len(content)):
- ls.append('PyList_SET_ITEM(%s, %d, %s); Py_INCREF(%s);' % (
- result, i, content[i], content[i]))
- return '\n'.join(ls)
-
class LoCallFunction(LoC):
can_fail = True
cost = 3
@@ -106,24 +91,21 @@
err = stuff[-1]
format = '"' + 'O' * len(args) + '"'
args = (func, format) + args
- return ('if (!(%s = PyObject_CallFunction(%s)))'
- ' goto %s;' % (result, ', '.join(args), err))
+ return ('OP_CALL_PYOBJ((%s), %s, %s)' % (', '.join(args), result, err))
class LoInstantiate(LoC):
can_fail = True
llclass = PARAMETER
# self.args: [output PyObject instance]
def writestr(self, res, err):
- return 'INSTANTIATE(%s, %s, %s)' % (
- self.llclass.name, res, err)
+ return 'OP_INSTANTIATE(%s, %s, %s)' % (self.llclass.name, res, err)
class LoAllocInstance(LoC):
can_fail = True
llclass = PARAMETER
# self.args: [output PyObject instance]
def writestr(self, res, err):
- return 'ALLOC_INSTANCE(%s, %s, %s)' % (
- self.llclass.name, res, err)
+ return 'ALLOC_INSTANCE(%s, %s, %s)' % (self.llclass.name, res, err)
class LoConvertTupleItem(LoOptimized):
source_r = PARAMETER # tuple-of-hltypes, one per item of the input tuple
@@ -159,41 +141,39 @@
class LoNewTuple(LoC):
can_fail = True
cost = 3
+ macro = 'OP_NEWTUPLE'
# self.args: [input PyObjects.., output PyObject]
def writestr(self, *stuff):
args = stuff[:-2]
result = stuff[-2]
err = stuff[-1]
- ls = ['if (!(%s = PyTuple_New(%d))) goto %s;' %
- (result, len(args), err)]
- for i, a in zip(range(len(args)), args):
- ls.append('PyTuple_SET_ITEM(%s, %d, %s); Py_INCREF(%s);' %
- (result, i, a, a))
+ ls = ['%s(%d, %s, %s)' % (self.macro, len(args), result, err)]
+ for i in range(len(args)):
+ ls.append('%s_SET(%s, %d, %s)' % (self.macro, result, i, args[i]))
return '\n'.join(ls)
+class LoNewList(LoNewTuple):
+ macro = 'OP_NEWLIST'
+ # self.args: [input PyObjects.., output PyObject]
+
class LoGetAttr(LoC):
cost = 1
fld = PARAMETER
# self.args: [PyObject instance, result..]
def writestr(self, inst, *result):
ls = []
- llclass = self.fld.llclass
if self.fld.is_class_attr:
- for src, dstname in zip(self.fld.llvars, result):
- fldexpr = '((%s_TypeObject*)(%s->ob_type))->%s' % (
- llclass.name, inst, src.name)
- if src.type == 'PyObject*':
- ls.append('GET_ATTR_cls(%s, %s)' % (fldexpr, dstname))
- else:
- ls.append('%s = %s;' % (dstname, fldexpr))
+ macro = 'OP_GETCLASSATTR'
else:
- for src, dstname in zip(self.fld.llvars, result):
- fldexpr = '((%s_Object*) %s)->%s' % (llclass.name, inst,
- src.name)
- if src.type == 'PyObject*':
- ls.append('GET_ATTR_py(%s, %s)' % (fldexpr, dstname))
- else:
- ls.append('%s = %s;' % (dstname, fldexpr))
+ macro = 'OP_GETINSTATTR'
+ llclass = self.fld.llclass
+ for src, dstname in zip(self.fld.llvars, result):
+ if src.type == 'PyObject*':
+ typecode = '_o'
+ else:
+ typecode = ''
+ ls.append('%s%s(%s, %s, %s, %s)' % (
+ macro, typecode, llclass.name, inst, src.name, dstname))
return '\n'.join(ls)
class LoGetAttrMethod(LoGetAttr):
@@ -215,12 +195,12 @@
assert len(value) == len(self.fld.llvars)
ls = []
for srcname, dst in zip(value, self.fld.llvars):
- fldexpr = '((%s_Object*) %s)->%s' % (self.llclass.name, inst,
- dst.name)
if dst.type == 'PyObject*':
- ls.append('SET_ATTR_py(%s, %s)' % (fldexpr, srcname))
+ typecode = '_o'
else:
- ls.append('%s = %s;' % (fldexpr, srcname))
+ typecode = ''
+ ls.append('OP_SETINSTATTR%s(%s, %s, %s, %s)' % (
+ typecode, self.llclass.name, inst, dst.name, srcname))
return '\n'.join(ls)
class LoInitClassAttr(LoC):
@@ -233,11 +213,12 @@
ls = []
# setting class attributes is only used for initialization
for srcname, dst in zip(value, self.fld.llvars):
- fldexpr = '%s_Type.%s' % (self.llclass.name, dst.name)
if dst.type == 'PyObject*':
- ls.append('SET_ATTR_cls(%s, %s)' % (fldexpr, srcname))
+ typecode = '_o'
else:
- ls.append('%s = %s;' % (fldexpr, srcname))
+ typecode = ''
+ ls.append('OP_INITCLASSATTR%s(%s, %s, %s)' % (
+ typecode, self.llclass.name, dst.name, srcname))
return '\n'.join(ls)
class LoConvertBoundMethod(LoOptimized):
@@ -277,8 +258,7 @@
ls = []
for a in self.args:
if a.type == 'PyObject*':
- ls.append('%s = Py_None; Py_INCREF(%s); /* dummy */' % (
- a.name, a.name))
+ ls.append('OP_DUMMYREF(%s)' % a.name)
return '\n'.join(ls)
# ____________________________________________________________
@@ -287,7 +267,7 @@
cost = 1
# self.args: [input LLVar, output LLVar]
def writestr(self, x, y):
- return '%s = %s;' % (y, x)
+ return 'MOVE(%s, %s)' % (x, y)
class LoGoto(LoC):
cost = 0
@@ -335,11 +315,6 @@
'int': '-1',
}
-ERROR_CHECK = {
- None: '< 0',
- 'int': '== -1 && PyErr_Occurred()',
- }
-
class LoCallPyFunction(LoC):
can_fail = True
hlrettype = PARAMETER
@@ -351,17 +326,19 @@
args = [a.name for a in self.args[1:R]]
err = self.errtarget
if L == 0: # no return value
- return 'if (%s(%s) %s) goto %s;' % (
- funcptr, ', '.join(args), ERROR_CHECK[None], err)
+ return 'OP_CCALL_v(%s, (%s), %s)' % (funcptr, ', '.join(args), err)
else:
# the return value is the first return LLVar:
retvar = self.args[R]
# if there are several return LLVars, the extra ones are passed
# in by reference as output arguments
args += ['&%s' % a.name for a in self.args[R+1:]]
- return ('if ((%s = %s(%s)) %s) goto %s;' % (
- retvar.name, funcptr, ', '.join(args),
- ERROR_CHECK.get(retvar.type, '== NULL'), err))
+ if retvar.type == 'int':
+ typecode = '_i'
+ else:
+ typecode = ''
+ return 'OP_CCALL%s(%s, (%s), %s, %s)' % (
+ typecode, funcptr, ', '.join(args), retvar.name, err)
class LoReturn(LoC):
cost = 1
Modified: pypy/trunk/src/pypy/translator/genc_typeset.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc_typeset.py (original)
+++ pypy/trunk/src/pypy/translator/genc_typeset.py Sat Sep 11 12:33:50 2004
@@ -39,7 +39,7 @@
self.bindings = bindings
self.conversion_cache = {}
self.conversion_errors = {}
- self.lloperations = {'convert': self.conversion_cache}
+ self.lloperations = {'CONVERT': self.conversion_cache}
self.parse_operation_templates()
# __________ methods required by LLFunction __________
Modified: pypy/trunk/src/pypy/translator/typer.py
==============================================================================
--- pypy/trunk/src/pypy/translator/typer.py (original)
+++ pypy/trunk/src/pypy/translator/typer.py Sat Sep 11 12:33:50 2004
@@ -59,7 +59,7 @@
# ...}
# This dict contains the known signatures of each space operation.
# Special opnames:
-# 'caseXXX' v : fails (i.e. jump to errlabel) if v is not XXX
+# 'CASE_XXX' v : fails (i.e. jump to errlabel) if v is not XXX
#
# rawoperations = {
# 'opname': subclass-of-LLOp,
@@ -189,12 +189,12 @@
# exits
if block.exits:
for exit in block.exits[:-1]:
- # generate | caseXXX v elselabel
+ # generate | CASE_XXX v elselabel
# | copy output vars to next block's input vars
# | jump to next block
# | elselabel:
elselabel = '%s_not%s' % (self.blockname[block], exit.exitcase)
- self.operation('case%s' % exit.exitcase,
+ self.operation('CASE_%s' % exit.exitcase,
[block.exitswitch],
errlabel = elselabel)
self.goto(exit)
More information about the Pypy-commit
mailing list