[pypy-svn] r17435 - in pypy/dist/pypy: annotation module/thread/rpython rpython/test

pedronis at codespeak.net pedronis at codespeak.net
Sat Sep 10 00:45:28 CEST 2005


Author: pedronis
Date: Sat Sep 10 00:45:25 2005
New Revision: 17435

Modified:
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/dictdef.py
   pypy/dist/pypy/module/thread/rpython/exttable.py
   pypy/dist/pypy/rpython/test/test_objectmodel.py
Log:
extend emulate_pbc_call such that it can work with methods.

in the general case the pbc itself cannot be used as key for the emulated_pbc_calls table, let the 
callers of the helpers specify a suitable unique key (and possibly whether the new information is also
replacing that for some previous/other set of keys)



Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Sat Sep 10 00:45:25 2005
@@ -229,8 +229,7 @@
             self.consider_pbc_call(pbc, shape, spaceop)
         self.pbc_call_sites = {}
 
-        for fn, shape in self.emulated_pbc_calls.iteritems():
-            pbc = SomePBC({fn: True})
+        for pbc, shape in self.emulated_pbc_calls.itervalues():
             self.consider_pbc_call(pbc, shape)
         self.emulated_pbc_calls = {}
 
@@ -546,16 +545,19 @@
 
         return unionof(*results) 
 
-    def emulate_pbc_call(self, pbc, args_s):
+    def emulate_pbc_call(self, unique_key, pbc, args_s, replace=[]):
         args = self.build_args("simple_call", args_s)
         shape = args.rawshape()
-        for func, classdef in pbc.prebuiltinstances.items():
-            if func is not None:
-                assert not isclassdef(classdef)
-                if func in self.emulated_pbc_calls:
-                    assert shape == self.emulated_pbc_calls[func]
-                else:
-                    self.emulated_pbc_calls[func] = shape
+        emulated_pbc_calls = self.emulated_pbc_calls
+        prev = [unique_key]
+        prev.extend(replace)
+        for other_key in prev:
+            if other_key in emulated_pbc_calls:
+                pbc, old_shape = emulated_pbc_calls[other_key]
+                assert shape == old_shape
+                del emulated_pbc_calls[other_key]
+        emulated_pbc_calls[unique_key] = pbc, shape
+
         return self.pbc_call(pbc, args, True)
 
     # decide_callable(position, func, args, mono) -> callb, key

Modified: pypy/dist/pypy/annotation/dictdef.py
==============================================================================
--- pypy/dist/pypy/annotation/dictdef.py	(original)
+++ pypy/dist/pypy/annotation/dictdef.py	Sat Sep 10 00:45:25 2005
@@ -17,7 +17,8 @@
             ListItem.merge(self, other)
             if self.custom_eq_hash:
                 self.update_rdict_annotations(other.s_rdict_eqfn,
-                                              other.s_rdict_hashfn)
+                                              other.s_rdict_hashfn,
+                                              other=other)
 
     def generalize(self, s_other_value):
         updated = ListItem.generalize(self, s_other_value)
@@ -25,7 +26,7 @@
             self.emulate_rdict_calls()
         return updated
 
-    def update_rdict_annotations(self, s_eqfn, s_hashfn):
+    def update_rdict_annotations(self, s_eqfn, s_hashfn, other=None):
         if not self.custom_eq_hash:
             self.custom_eq_hash = True
         else:
@@ -33,15 +34,25 @@
             s_hashfn = unionof(s_hashfn, self.s_rdict_hashfn)
         self.s_rdict_eqfn = s_eqfn
         self.s_rdict_hashfn = s_hashfn
-        self.emulate_rdict_calls()
+        self.emulate_rdict_calls(other=other)
+
+    def emulate_rdict_calls(self, other=None):
+        myeq = (self, 'eq')
+        myhash = (self, 'hash')
+        if other:
+            replace_othereq = [(other, 'eq')]
+            replace_otherhash = [(other, 'hash')]
+        else:
+            replace_othereq = replace_otherhash = ()
 
-    def emulate_rdict_calls(self):
         s_key = self.s_value
-        s1 = self.bookkeeper.emulate_pbc_call(self.s_rdict_eqfn, [s_key, s_key])
+        s1 = self.bookkeeper.emulate_pbc_call(myeq, self.s_rdict_eqfn, [s_key, s_key],
+                                              replace=replace_othereq)
         assert SomeBool().contains(s1), (
             "the custom eq function of an r_dict must return a boolean"
             " (got %r)" % (s1,))
-        s2 = self.bookkeeper.emulate_pbc_call(self.s_rdict_hashfn, [s_key])
+        s2 = self.bookkeeper.emulate_pbc_call(myhash, self.s_rdict_hashfn, [s_key],
+                                              replace=replace_otherhash)
         assert SomeInteger().contains(s2), (
             "the custom hash function of an r_dict must return an integer"
             " (got %r)" % (s2,))

Modified: pypy/dist/pypy/module/thread/rpython/exttable.py
==============================================================================
--- pypy/dist/pypy/module/thread/rpython/exttable.py	(original)
+++ pypy/dist/pypy/module/thread/rpython/exttable.py	Sat Sep 10 00:45:25 2005
@@ -29,7 +29,7 @@
            length 1 for arg""")
     s_arg, = s_argument_tuple.items
     # XXX hack hack hack: emulate a call to s_bootstrap_function
-    s_result = bookkeeper.emulate_pbc_call(s_bootstrap_function, [s_arg])
+    s_result = bookkeeper.emulate_pbc_call(bookkeeper.position_key, s_bootstrap_function, [s_arg])
     assert bookkeeper.getpbc(None).contains(s_result), (
         """thread.start_new_thread(f, arg): f() should return None""")
     return annmodel.SomeInteger()

Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_objectmodel.py	(original)
+++ pypy/dist/pypy/rpython/test/test_objectmodel.py	Sat Sep 10 00:45:25 2005
@@ -17,9 +17,7 @@
 def strange_key_hash(key):
     return ord(key[0])
 
-def test_r_dict():
-    # NB. this test function is also annotated/rtyped by the next tests
-    d = r_dict(strange_key_eq, strange_key_hash)
+def play_with_r_dict(d):
     d['hello'] = 42
     assert d['hi there'] == 42
     try:
@@ -47,6 +45,24 @@
     assert d.keys() == []
     return True   # for the tests below
 
+
+def test_r_dict():
+    # NB. this test function is also annotated/rtyped by the next tests
+    d = r_dict(strange_key_eq, strange_key_hash)
+    return play_with_r_dict(d)
+
+class Strange:
+    def key_eq(strange, key1, key2):
+        return key1[0] == key2[0]   # only the 1st character is relevant
+    def key_hash(strange, key):
+        return ord(key[0])
+
+def test_r_dict_bm():
+    # NB. this test function is also annotated by the next tests
+    strange = Strange()
+    d = r_dict(strange.key_eq, strange.key_hash)
+    return play_with_r_dict(d)
+
 def test_annotate_r_dict():
     t = Translator(test_r_dict)
     a = t.annotate([])
@@ -59,6 +75,23 @@
     graph = t.flowgraphs[strange_key_hash]
     assert a.binding(graph.getargs()[0]).knowntype == str
 
+def test_annotate_r_dict_bm():
+    t = Translator(test_r_dict_bm)
+    a = t.annotate([])
+    #t.view()
+    strange_key_eq = Strange.key_eq.im_func
+    strange_key_hash = Strange.key_hash.im_func
+
+    assert strange_key_eq in t.flowgraphs
+    assert strange_key_hash in t.flowgraphs
+    graph = t.flowgraphs[strange_key_eq]
+    assert a.binding(graph.getargs()[0]).knowntype == Strange
+    assert a.binding(graph.getargs()[1]).knowntype == str
+    assert a.binding(graph.getargs()[2]).knowntype == str
+    graph = t.flowgraphs[strange_key_hash]
+    assert a.binding(graph.getargs()[0]).knowntype == Strange
+    assert a.binding(graph.getargs()[1]).knowntype == str
+
 def INPROGRESS_test_rtype_r_dict():
     res = interpret(test_r_dict, [])
     assert res is True



More information about the Pypy-commit mailing list