Author: Armin Rigo <[email protected]>
Branch: rdict-experiments-3
Changeset: r67301:162eedd7917a
Date: 2013-10-11 08:15 +0200
http://bitbucket.org/pypy/pypy/changeset/162eedd7917a/

Log:    Cannot use llhelper() in case we want to translate the
        ll_dict_lookup() function

diff --git a/rpython/rtyper/lltypesystem/rdict.py 
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -43,7 +43,7 @@
 def get_ll_dict(DICTKEY, DICTVALUE, get_custom_eq_hash=None, DICT=None,
                 ll_fasthash_function=None, ll_hash_function=None,
                 ll_eq_function=None, method_cache={},
-                dummykeyobj=None, dummyvalueobj=None):
+                dummykeyobj=None, dummyvalueobj=None, rtyper=None):
     # get the actual DICT type. if DICT is None, it's created, otherwise
     # forward reference is becoming DICT
     if DICT is None:
@@ -141,6 +141,11 @@
     adtmeths['allocate'] = lltype.typeMethod(_ll_malloc_dict)
 
     family = LookupFamily()
+    adtmeths['lookup_family'] = family
+
+    DICT.become(lltype.GcStruct("dicttable", adtmeths=adtmeths,
+                                *fields))
+
     family.empty_array = DICTENTRYARRAY.allocate(0)
     for name, T in [('byte', rffi.UCHAR),
                     ('short', rffi.USHORT),
@@ -149,14 +154,17 @@
         if name == 'int' and not IS_64BIT:
             continue
         lookupfn, storecleanfn = new_lookup_functions(LOOKUP_FUNC,
-                                                      STORECLEAN_FUNC, T=T)
+                                                      STORECLEAN_FUNC, T=T,
+                                                      rtyper=rtyper)
         setattr(family, '%s_lookup_function' % name, lookupfn)
         setattr(family, '%s_insert_clean_function' % name, storecleanfn)
-    adtmeths['lookup_family'] = family
+    return DICT
 
-    DICT.become(lltype.GcStruct("dicttable", adtmeths=adtmeths,
-                                *fields))
-    return DICT
+def llhelper_or_compile(rtyper, FUNCPTR, ll_func):
+    if rtyper is None:
+        return llhelper(FUNCPTR, ll_func)
+    else:
+        return rtyper.annotate_helper(ll_func, FUNCPTR.TO.ARGS)
 
 class LookupFamily:
     def _freeze_(self):
@@ -219,7 +227,8 @@
             kwd['dummyvalueobj'] = self.value_repr.get_ll_dummyval_obj(
                 self.rtyper, s_value)
 
-            get_ll_dict(DICTKEY, DICTVALUE, DICT=self.DICT, **kwd)
+            get_ll_dict(DICTKEY, DICTVALUE, DICT=self.DICT,
+                        rtyper=self.rtyper, **kwd)
 
     def convert_const(self, dictobj):
         from rpython.rtyper.lltypesystem import llmemory
@@ -251,14 +260,16 @@
                 for dictkeycontainer, dictvalue in dictobj._dict.items():
                     llkey = r_key.convert_const(dictkeycontainer.key)
                     llvalue = r_value.convert_const(dictvalue)
-                    ll_dict_setitem(l_dict, llkey, llvalue)
+                    _ll_dict_insertclean(l_dict, llkey, llvalue,
+                                         dictkeycontainer.hash)
                 return l_dict
 
             else:
                 for dictkey, dictvalue in dictobj.items():
                     llkey = r_key.convert_const(dictkey)
                     llvalue = r_value.convert_const(dictvalue)
-                    ll_dict_setitem(l_dict, llkey, llvalue)
+                    _ll_dict_insertclean(l_dict, llkey, llvalue,
+                                         l_dict.keyhash(llkey))
                 return l_dict
 
     def rtype_len(self, hop):
@@ -530,6 +541,23 @@
             ll_assert(rc > 0, "ll_dict_resize failed?")
         d.resize_counter = rc
 
+def _ll_dict_insertclean(d, key, value, hash):
+    ENTRY = lltype.typeOf(d.entries).TO.OF
+    insertcleanfn = ll_pick_insert_clean_function(d)
+    insertcleanfn(d, hash, d.num_used_items)
+    entry = d.entries[d.num_used_items]
+    entry.key = key
+    entry.value = value
+    if hasattr(ENTRY, 'f_hash'):
+        entry.f_hash = hash
+    if hasattr(ENTRY, 'f_valid'):
+        entry.f_valid = True
+    d.num_used_items += 1
+    d.num_items += 1
+    rc = d.resize_counter - 3
+    ll_assert(rc > 0, "_ll_dict_insertclean: overflow")
+    d.resize_counter = rc
+
 def _ll_len_of_d_indexes(d):
     # xxx Haaaack: returns len(d.indexes).  Works independently of
     # the exact type pointed to by d, using a forced cast...
@@ -691,7 +719,7 @@
 FLAG_DELETE = 2
 FLAG_DELETE_TRY_HARD = 3
 
-def new_lookup_functions(LOOKUP_FUNC, STORECLEAN_FUNC, T):
+def new_lookup_functions(LOOKUP_FUNC, STORECLEAN_FUNC, T, rtyper=None):
     INDEXES = lltype.Ptr(lltype.GcArray(T))
 
     def ll_kill_something(d):
@@ -816,8 +844,8 @@
             perturb >>= PERTURB_SHIFT
         indexes[i] = rffi.cast(T, index + VALID_OFFSET)
 
-    return (llhelper(LOOKUP_FUNC, ll_dict_lookup),
-            llhelper(STORECLEAN_FUNC, ll_dict_store_clean))
+    return (llhelper_or_compile(rtyper, LOOKUP_FUNC, ll_dict_lookup),
+            llhelper_or_compile(rtyper, STORECLEAN_FUNC, ll_dict_store_clean))
 
 # ____________________________________________________________
 #
diff --git a/rpython/rtyper/test/test_rdict.py 
b/rpython/rtyper/test/test_rdict.py
--- a/rpython/rtyper/test/test_rdict.py
+++ b/rpython/rtyper/test/test_rdict.py
@@ -856,6 +856,23 @@
         res = self.interpret(f, [5])
         assert res == 25019999
 
+    def test_prebuilt_r_dict(self):
+        def myeq(n, m):
+            return n // 2 == m // 2
+        def myhash(n):
+            return n // 2
+        d = r_dict(myeq, myhash)
+        for i in range(10):
+            d[i] = i*i
+        def f(n):
+            assert len(d) == 5
+            return d[n]
+        assert f(6) == 49
+        res = self.interpret(f, [6])
+        assert res == 49
+        res = self.interpret(f, [5])
+        assert res == 25
+
     def test_resize_during_iteration(self):
         def func():
             d = {5: 1, 6: 2, 7: 3}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to