[pypy-svn] r6299 - in pypy/branch/pypy-genc/translator: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Sep 6 15:53:14 CEST 2004
Author: arigo
Date: Mon Sep 6 15:53:14 2004
New Revision: 6299
Modified:
pypy/branch/pypy-genc/translator/test/test_ctrans.py
pypy/branch/pypy-genc/translator/typer.py
Log:
Some more tweaking reference counters. The resulting C code looks reasonable
now -- it tries hard to minimize the Py_{INC,DEC}REF().
Moved a couple of private tests to test_ctrans.py. I'll try to figure out
later why you cannot call two test functions 'fn' without the two Translator
instances getting confused.
--This line, and those below, will be ignored--
M translator/test/test_ctrans.py
M translator/typer.py
Modified: pypy/branch/pypy-genc/translator/test/test_ctrans.py
==============================================================================
--- pypy/branch/pypy-genc/translator/test/test_ctrans.py (original)
+++ pypy/branch/pypy-genc/translator/test/test_ctrans.py Mon Sep 6 15:53:14 2004
@@ -131,5 +131,24 @@
call_five = self.getcompiled(snippet.call_five)
self.assertEquals(call_five(), [5])
+ def test_class_defaultattr(self):
+ class K:
+ n = "hello"
+ def class_defaultattr():
+ k = K()
+ k.n += " world"
+ return k.n
+ fn = self.getcompiled(class_defaultattr)
+ self.assertEquals(fn(), "hello world")
+
+ def test_tuple_repr(self):
+ def tuple_repr(x=int, y=object):
+ z = x, y
+ while x:
+ x = x-1
+ return z
+ fn = self.getcompiled(tuple_repr)
+ self.assertEquals(fn(6,'a'), (6,'a'))
+
if __name__ == '__main__':
testit.main()
Modified: pypy/branch/pypy-genc/translator/typer.py
==============================================================================
--- pypy/branch/pypy-genc/translator/typer.py (original)
+++ pypy/branch/pypy-genc/translator/typer.py Mon Sep 6 15:53:14 2004
@@ -220,8 +220,7 @@
if to == hltype:
yield frm
- def operation(self, opname, args, result=None, errlabel=None,
- resulttype=None):
+ def operation(self, opname, args, result=None, errlabel=None):
"Helper to build the LLOps for a single high-level operation."
# get the hltypes of the input arguments
for v in args:
@@ -230,7 +229,7 @@
directions = [self.convert_from] * len(args)
# append the hltype of the result
if result:
- self.makevar(result, resulttype)
+ self.makevar(result)
args_t.append(self.hltypes[result])
directions.append(self.convert_to)
# enumerate possible signatures until we get a match
@@ -246,13 +245,15 @@
# correctly extend 'lloperations'.
if retry:
try:
- self.operation(opname, args, result, errlabel, resulttype)
+ self.operation(opname, args, result, errlabel)
return
except RuntimeError: # infinite recursion
pass
raise TypingError([opname] + args_t)
- # check if the answer has an existing well-known answer
- if resulttype is not None: # if we are allowed to patch self.llreprs
+ # check for some operations that have an existing well-known answer
+ # that doesn't involve side-effects, so that we can just provide
+ # this answer and not generate any LLOp.
+ if result:
if llname == 'copy':
# patch self.llreprs and we're done
llrepr = []
@@ -270,7 +271,8 @@
for v, v_t, s_t in zip(args, args_t, sig):
if v_t != s_t:
tmp = Variable()
- self.operation('convert', [v], tmp, resulttype=s_t)
+ self.makevar(tmp, hltype=s_t)
+ self.operation('convert', [v], tmp)
v = tmp
llargs += self.llreprs[v]
# generate an error label if the operation can fail
@@ -299,39 +301,44 @@
# generate the exit.args -> target.inputargs copying operations
to_release_copy = self.to_release
try:
- # copy the data, performing any necessary conversion
+ # convert the exit.args to the type expected by the target.inputargs
+ exitargs = []
+ for v, w in zip(exit.args, exit.target.inputargs):
+ self.makevar(v)
+ if self.hltypes[v] != self.hltypes[w]:
+ tmp = Variable()
+ self.makevar(tmp, hltype=self.hltypes[w])
+ self.operation('convert', [v], tmp)
+ v = tmp
+ exitargs.append(v)
+ # move the data from exit.args to target.inputargs
# See also remove_direct_loops() for why we don't worry about
- # the order of the operations
+ # the order of the move operations
current_refcnt = {}
needed_refcnt = {}
- for v, w in zip(exit.args, exit.target.inputargs):
- self.makevar(v)
- if self.hltypes[v] == self.hltypes[w]: # fast case
- for x, y in zip(self.llreprs[v], self.llreprs[w]):
- self.blockops.append(LLOp('move', [x, y]))
- needed_refcnt.setdefault(v, 0)
- needed_refcnt[v] += 1
- else:
- self.operation('convert', [v], w)
- needed_refcnt.setdefault(w, 0)
- needed_refcnt[w] += 1
- # list all variables that go out of scope: as needing by default
- # no reference
+ for v, w in zip(exitargs, exit.target.inputargs):
+ for x, y in zip(self.llreprs[v], self.llreprs[w]):
+ self.blockops.append(LLOp('move', [x, y]))
+ needed_refcnt.setdefault(x, 0)
+ needed_refcnt[x] += 1
+ # list all variables that go out of scope: by default
+ # they need no reference, but have one reference.
for node in self.to_release.getbranch():
- current_refcnt[node.var] = 1
- needed_refcnt.setdefault(node.var, 0)
+ for x in self.llreprs[node.var]:
+ current_refcnt[x] = 1
+ needed_refcnt.setdefault(x, 0)
# now adjust all reference counters: first increfs, then decrefs
# (in case a variable to decref points to the same objects than
# another variable to incref).
- for v, needed in needed_refcnt.items():
- current_refcnt.setdefault(v, 0)
- while current_refcnt[v] < needed:
- self.blockops.append(LLOp('incref', self.llreprs[v]))
- current_refcnt[v] += 1
- for v, needed in needed_refcnt.items():
- while current_refcnt[v] > needed:
- self.blockops.append(LLOp('decref', self.llreprs[v]))
- current_refcnt[v] -= 1
+ for x, needed in needed_refcnt.items():
+ current_refcnt.setdefault(x, 0)
+ while current_refcnt[x] < needed:
+ self.blockops.append(LLOp('incref', [x]))
+ current_refcnt[x] += 1
+ for x, needed in needed_refcnt.items():
+ while current_refcnt[x] > needed:
+ self.blockops.append(LLOp('decref', [x]))
+ current_refcnt[x] -= 1
# finally jump to the target block
self.blockops.append(LLOp('goto', [], self.blockname[exit.target]))
finally:
More information about the Pypy-commit
mailing list