[pypy-svn] r59451 - in pypy/trunk/pypy/interpreter/astcompiler: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Oct 27 17:17:46 CET 2008
Author: arigo
Date: Mon Oct 27 17:17:45 2008
New Revision: 59451
Modified:
pypy/trunk/pypy/interpreter/astcompiler/pyassem.py
pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py
Log:
Test and fix for sharing in co_const.
Modified: pypy/trunk/pypy/interpreter/astcompiler/pyassem.py
==============================================================================
--- pypy/trunk/pypy/interpreter/astcompiler/pyassem.py (original)
+++ pypy/trunk/pypy/interpreter/astcompiler/pyassem.py Mon Oct 27 17:17:45 2008
@@ -28,8 +28,8 @@
if newlocals:
self.flags |= CO_NEWLOCALS
- # we need to build an app-level dict here
- self.w_consts = space.newdict()
+ self.w_const2index = space.newdict() # {w_key: wrap(index in consts_w)}
+ self.consts_w = []
self.names = []
# Free variables found by the symbol table scan, including
# variables used only in nested scopes, are included here.
@@ -95,27 +95,41 @@
# Instructions with an object argument (LOAD_CONST)
def emitop_obj(self, opname, w_obj):
- index = self._lookupConst(w_obj, self.w_consts)
+ index = self._lookupConst(w_obj)
self.emitop_int(opname, index)
- def _lookupConst(self, w_obj, w_dict):
- space = self.space
+ def _lookupConst(self, w_obj):
# insert the docstring first, if necessary
- if not space.is_true(w_dict):
- w_obj_type = space.type(self.w_docstring)
- w_key = space.newtuple([self.w_docstring, w_obj_type])
- space.setitem(w_dict, w_key, space.wrap(0))
- # normal logic follows
- w_obj_type = space.type(w_obj)
- w_key = space.newtuple([w_obj, w_obj_type])
- try:
- w_result = space.getitem(w_dict, w_key)
- except OperationError, operr:
- if not operr.match(space, space.w_KeyError):
- raise
- w_result = space.len(w_dict)
- space.setitem(w_dict, w_key, w_result)
- return space.int_w(w_result)
+ if len(self.consts_w) == 0:
+ index = self._lookupConstInternal(self.w_docstring)
+ assert index == 0
+ return self._lookupConstInternal(w_obj)
+
+ def _lookupConstInternal(self, w_obj):
+ # Some types of object can be shared if equal values appear
+ # several times in the consts_w.
+ space = self.space
+ if (space.is_w(w_obj, space.w_None) or
+ space.is_w(w_obj, space.w_Ellipsis)):
+ is_atomic_type = True
+ else:
+ w_type = space.type(w_obj)
+ is_atomic_type = (space.is_w(w_type, space.w_int) or
+ space.is_w(w_type, space.w_bool) or
+ space.is_w(w_type, space.w_long) or
+ space.is_w(w_type, space.w_float) or
+ space.is_w(w_type, space.w_complex) or
+ space.is_w(w_type, space.w_str) or
+ space.is_w(w_type, space.w_unicode))
+ if is_atomic_type:
+ w_index = space.finditem(self.w_const2index, w_obj)
+ if w_index is not None:
+ return space.int_w(w_index)
+ result = len(self.consts_w)
+ self.consts_w.append(w_obj)
+ if is_atomic_type:
+ space.setitem(self.w_const2index, w_obj, space.wrap(result))
+ return result
# ____________________________________________________________
# Instructions with a name argument
@@ -365,17 +379,10 @@
"""Return a tuple for the const slot of the code object
"""
# sanity-check
- index = self._lookupConst(self.w_docstring, self.w_consts)
+ index = self._lookupConst(self.w_docstring)
if index != 0:
raise InternalCompilerError("setDocstring() called too late")
- space = self.space
- keys_w = space.unpackiterable(self.w_consts)
- l_w = [None] * len(keys_w)
- for w_key in keys_w:
- index = space.int_w(space.getitem(self.w_consts, w_key))
- w_v = space.viewiterable(w_key)[0]
- l_w[index] = w_v
- return l_w
+ return self.consts_w[:]
# ____________________________________________________________
Modified: pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py
==============================================================================
--- pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py (original)
+++ pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py Mon Oct 27 17:17:45 2008
@@ -443,6 +443,10 @@
x = [lineno for addr, lineno in dis.findlinestarts(co)]
""", 'x', [3, 4]
+ def test_type_of_constants(self):
+ yield self.simple_test, "x=[(1,0), (1,0L)]", 'type(x[1][1])', long
+ yield self.simple_test, "x=['2?-', '2?-']", 'id(x[0])==id(x[1])', True
+
def test_pprint(self):
# a larger example that showed a bug with jumps
# over more than 256 bytes
More information about the Pypy-commit
mailing list