[pypy-commit] lang-smalltalk default: Switched from saving w_superclass to s_superclass
lwassermann
noreply at buildbot.pypy.org
Sun Mar 10 20:25:29 CET 2013
Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch:
Changeset: r159:3c05ce8c677c
Date: 2013-03-10 20:25 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/3c05ce8c677c/
Log: Switched from saving w_superclass to s_superclass Patched
W_PointerObject#become and test to ensure that the backlink w_self
also points to the correct object refactored patching of
ProtoObjectClass shadow of objspace
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -259,9 +259,9 @@
class W_PointersObject(W_AbstractObjectWithClassReference):
"""Common object."""
_attrs_ = ['_shadow', '_vars']
+
+ _shadow = None # Default value
- _shadow = None # Default value
-
@jit.unroll_safe
def __init__(self, w_class, size):
"""Create new object with size = fixed + variable size."""
@@ -269,7 +269,7 @@
vars = self._vars = [None] * size
for i in range(size): # do it by hand for the JIT's sake
vars[i] = w_nil
- self._shadow = None
+ self._shadow = None # Default value
def at0(self, space, index0):
# To test, at0 = in varsize part
@@ -382,7 +382,11 @@
if not isinstance(w_other, W_PointersObject):
return False
self._vars, w_other._vars = w_other._vars, self._vars
+ # switching means also switching shadows
self._shadow, w_other._shadow = w_other._shadow, self._shadow
+ # shadow links are in both directions -> also update shadows
+ if self.has_shadow(): self._shadow._w_self = self
+ if w_other.has_shadow(): w_other._shadow._w_self = w_other
W_AbstractObjectWithClassReference._become(self, w_other)
return True
@@ -499,10 +503,11 @@
### variables. The number of bytes used for this purpose is the value of
### the last byte in the method.
- _shadow = None
+ _shadow = None # Default value
_likely_methodname = "<unknown>"
def __init__(self, bytecount=0, header=0):
+ self._shadow = None
self.setheader(header)
self.bytes = ["\x00"] * bytecount
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -53,13 +53,8 @@
w_Class = self.classtable["w_Class"]
w_Metaclass = self.classtable["w_Metaclass"]
# XXX
- proto_shadow = instantiate(shadow.ClassShadow)
- proto_shadow.space = self
- proto_shadow.name = ''
- proto_shadow.w_superclass = w_Class
- proto_shadow.version = shadow.Version()
- w_ProtoObjectClass._shadow = None
- w_ProtoObjectClass.store_shadow(proto_shadow)
+ proto_shadow = w_ProtoObjectClass._shadow
+ proto_shadow.store_w_superclass(w_Class)
# at this point, all classes that still lack a w_class are themselves
# metaclasses
for nm, w_cls_obj in self.classtable.items():
@@ -299,7 +294,7 @@
s = instantiate(shadow.ClassShadow)
s.space = space
s._w_self = w_class
- s.w_superclass = w_superclass
+ s.store_w_superclass(w_superclass)
s.name = name
s.version = shadow.Version()
s.instance_size = instsize
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -74,7 +74,7 @@
(i.e. used as the class of another Smalltalk object).
"""
- _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "w_superclass"]
+ _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "_s_superclass"]
def __init__(self, space, w_self):
# fields added here should also be in objspace.py:60ff, 300ff
@@ -141,10 +141,10 @@
w_superclass = w_self._fetch(constants.CLASS_SUPERCLASS_INDEX)
if w_superclass.is_same_object(self.space.w_nil):
- self.w_superclass = None
+ self._s_superclass = None
else:
assert isinstance(w_superclass, model.W_PointersObject)
- self.w_superclass = w_superclass
+ self._s_superclass = w_superclass.as_class_get_shadow(self.space)
self.version = Version()
def guess_class_name(self):
@@ -194,9 +194,9 @@
return jit.promote(self.w_methoddict.as_methoddict_get_shadow(self.space))
def s_superclass(self):
- if self.w_superclass is None:
+ if self._s_superclass is None:
return None
- return self.w_superclass.as_class_get_shadow(self.space)
+ return self._s_superclass
# _______________________________________________________________
# Methods for querying the format word, taken from the blue book:
@@ -226,23 +226,37 @@
" Number of named instance variables for each instance of this class "
return self.instance_size
+ def store_w_superclass(self, w_class):
+ if w_class is None:
+ self._s_superclass = None
+ else:
+ self._s_superclass = w_class.as_class_get_shadow(self.space)
+
# _______________________________________________________________
# Methods for querying the format word, taken from the blue book:
def __repr__(self):
return "<ClassShadow %s>" % (self.name or '?',)
+ def lookup(self, w_selector):
+ jit.promote(self)
+ version = self.version
+ jit.promote(version)
+ return self.safe_lookup(w_selector, version)
+
@jit.unroll_safe
- def lookup(self, w_selector):
+ def safe_lookup(self, w_selector, version):
+ assert version is self.version
look_in_shadow = self
jit.promote(w_selector)
while look_in_shadow is not None:
w_method = look_in_shadow.s_methoddict().find_selector(w_selector)
if w_method is not None:
return w_method.as_compiledmethod_get_shadow(self.space)
- look_in_shadow = look_in_shadow.s_superclass()
+ look_in_shadow = look_in_shadow._s_superclass
raise MethodNotFound(self, w_selector)
+
# _______________________________________________________________
# Methods used only in testing
diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py
--- a/spyvm/test/test_model.py
+++ b/spyvm/test/test_model.py
@@ -213,7 +213,9 @@
res = w_clsa.become(w_clsb)
assert res
assert w_clsa.as_class_get_shadow(space) is s_clsb
+ assert s_clsa._w_self is w_clsb
assert w_clsb.as_class_get_shadow(space) is s_clsa
+ assert s_clsb._w_self is w_clsa
def test_word_atput():
i = model.W_SmallInteger(100)
More information about the pypy-commit
mailing list