Author: Carl Friedrich Bolz <[email protected]>
Branch: type-specialized-instances
Changeset: r60080:e66173bbd88b
Date: 2013-01-15 12:01 +0100
http://bitbucket.org/pypy/pypy/changeset/e66173bbd88b/
Log: also add a unicode specialization
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -8,6 +8,7 @@
from pypy.objspace.std.dictmultiobject import BaseKeyIterator,
BaseValueIterator, BaseItemIterator
from pypy.objspace.std.dictmultiobject import _never_equal_to_string
from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.unicodeobject import W_UnicodeObject
from pypy.objspace.std.objectobject import W_ObjectObject
from pypy.objspace.std.typeobject import TypeCell
@@ -140,10 +141,14 @@
attr = cache.get(key, None)
if attr is None:
# XXX not so nice that the classes have to be listed
+ # it's necessary because instantiate inside an elidable function
+ # confuses the JIT
if attrclass_key == PlainAttribute.attrclass_key:
attr = PlainAttribute((name, index), self)
elif attrclass_key == StrAttribute.attrclass_key:
attr = StrAttribute((name, index), self)
+ elif attrclass_key == UnicodeAttribute.attrclass_key:
+ attr = UnicodeAttribute((name, index), self)
else:
assert attrclass_key == IntAttribute.attrclass_key
attr = IntAttribute((name, index), self)
@@ -394,6 +399,26 @@
erased = self.erase_item(self.space.str_w(w_value))
obj._mapdict_write_storage(self.position, erased)
+class UnicodeAttribute(AbstractStoredAttribute):
+ attrclass_key = 3
+
+ erase_item, unerase_item = rerased.new_erasing_pair("mapdict storage
unicode item")
+ erase_item = staticmethod(erase_item)
+ unerase_item = staticmethod(unerase_item)
+
+ def read_attr(self, obj):
+ erased = obj._mapdict_read_storage(self.position)
+ value = self.unerase_item(erased)
+ return self.space.wrap(value)
+
+ def write_attr(self, obj, w_value):
+ if type(w_value) is not W_UnicodeObject:
+ self._replace(obj, self.selector, w_value)
+ return
+ erased = self.erase_item(self.space.unicode_w(w_value))
+ obj._mapdict_write_storage(self.position, erased)
+
+
def is_taggable_int(space, w_value):
from pypy.objspace.std.intobject import W_IntObject
@@ -411,6 +436,8 @@
attrclass = IntAttribute
elif type(w_value) is W_StringObject:
attrclass = StrAttribute
+ elif type(w_value) is W_UnicodeObject:
+ attrclass = UnicodeAttribute
return attrclass
def _become(w_obj, new_obj):
diff --git a/pypy/objspace/std/test/test_mapdict.py
b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -467,6 +467,67 @@
# check if 'y' is still reachable
assert isinstance(obj1.map.back, StrAttribute)
assert space.eq_w(obj1.getdictvalue(space, "y"), space.wrap("b"))
+
+ def test_unicode_attributes(self):
+ space = self.space
+ cls = Class(sp=space)
+ obj1 = cls.instantiate()
+ obj1.setdictvalue(space, "x", space.wrap(u"a"))
+ assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap(u"a"))
+
+ obj2 = cls.instantiate()
+ w1 = W_Root()
+ obj2.setdictvalue(space, "x", w1)
+ assert obj2.getdictvalue(space, "x") is w1
+
+ assert obj1.map is not obj2.map
+ assert isinstance(obj1.map, UnicodeAttribute)
+
+ obj3 = cls.instantiate()
+ obj3.setdictvalue(space, "x", space.wrap(u"a"))
+ assert space.eq_w(obj3.getdictvalue(space, "x"), space.wrap(u"a"))
+
+ assert obj1.map is obj3.map
+
+ assert UnicodeAttribute.unerase_item(obj1.storage[0]) == "a"
+ assert PlainAttribute.unerase_item(obj2.storage[0]) == w1
+
+ def test_overwrite_unicode_attribute_with_another_type(self):
+ space = self.space
+ cls = Class(sp=space)
+ obj1 = cls.instantiate()
+
+ obj1.setdictvalue(space, "x", space.wrap(u"a"))
+ assert isinstance(obj1.map, UnicodeAttribute)
+ assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap(u"a"))
+
+ w1 = W_Root()
+ obj1.setdictvalue(space, "x", w1)
+ assert isinstance(obj1.map, PlainAttribute)
+ assert obj1.getdictvalue(space, "x") is w1
+
+ def test_overwrite_unicode_attribute_with_another_type2(self):
+ space = self.space
+ cls = Class(sp=space)
+ obj1 = cls.instantiate()
+
+ obj1.setdictvalue(space, "x", space.wrap(u"a"))
+ assert isinstance(obj1.map, UnicodeAttribute)
+ assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap(u"a"))
+
+ obj1.setdictvalue(space, "y", space.wrap(u"b"))
+ assert isinstance(obj1.map.back, UnicodeAttribute)
+ assert space.eq_w(obj1.getdictvalue(space, "y"), space.wrap(u"b"))
+
+ # overwrite 'x' with new type
+ w1 = W_Root()
+ obj1.setdictvalue(space, "x", w1)
+ assert isinstance(obj1.map, PlainAttribute)
+ assert obj1.getdictvalue(space, "x") is w1
+
+ # check if 'y' is still reachable
+ assert isinstance(obj1.map.back, UnicodeAttribute)
+ assert space.eq_w(obj1.getdictvalue(space, "y"), space.wrap(u"b"))
# ___________________________________________________________
# dict tests
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit