[pypy-commit] lang-smalltalk default: added fieldtypes tests for testing correctnes of neighbour finding

lwassermann noreply at buildbot.pypy.org
Fri Apr 12 00:12:37 CEST 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r258:4d577f6b6b0c
Date: 2013-04-11 22:25 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/4d577f6b6b0c/

Log:	added fieldtypes tests for testing correctnes of neighbour finding
	changed fieldtypes tags to enable translating added quicksort
	implementation for changes sorting

diff --git a/spyvm/fieldtypes.py b/spyvm/fieldtypes.py
--- a/spyvm/fieldtypes.py
+++ b/spyvm/fieldtypes.py
@@ -1,14 +1,16 @@
 from spyvm import model, shadow
 
-from rpython.rlib import jit, signature
+from rpython.rlib import objectmodel, jit, signature
 
-LPI = object()
-int
-float
+class TypeTag():
+    pass
 
-object
+LPI = TypeTag()
+SInt = TypeTag()
+flt = TypeTag()
+obj = TypeTag()
 
-maps = dict()
+maps = {}
 
 class VarSizedFieldTypes():
     _immutable_fields_ = []
@@ -33,23 +35,24 @@
     _attrs_ = ['types', 'parent', 'siblings', 'diff']
     _settled_ = True
 
-    def __init__(self, types, parent=None, change=(-1, object)):
+    def __init__(self, types, parent=None, change=(-1, obj)):
         self.types = types
         self.parent = parent
         if parent is not None:
-            assert change != (-1, object)
+            assert change != (-1, obj)
         self.diff = change
 
-        self.siblings = dict()
+        self.siblings = {}
 
     def fetch(self, w_object, n0):
         w_result = w_object._vars[n0]
+        assert w_result is not None
         types = self.types
-        if types[n0] is int:
+        if types[n0] is SInt:
             jit.record_known_class(w_result, model.W_SmallInteger)
         elif types[n0] is LPI:
             jit.record_known_class(w_result, model.W_LargePositiveInteger1Word)
-        elif types[n0] is float:
+        elif types[n0] is flt:
             jit.record_known_class(w_result, model.W_Float)
         return w_result
 
@@ -72,14 +75,16 @@
             return self.descent([change])
         else:
             new_fieldtype = parent.ascent([change, self.diff])
-            assert new_fieldtype.types == self.types[0:n0] + [changed_type] + self.types[n0+1:]
+            if not objectmodel.we_are_translated():
+                assert new_fieldtype.types == self.types[0:n0] + [changed_type] + self.types[n0+1:]
             siblings[change] = new_fieldtype
             return new_fieldtype
 
     def ascent(self, changes):
         parent = self.parent
         if parent is None:
-            return self.descent(sorted(changes))
+            sort(changes)
+            return self.descent(changes)
         else:
             change = self.diff
             if changes[0][0] != change[0]:
@@ -105,7 +110,7 @@
     @staticmethod
     def of_length(n):
         if n not in maps:
-            maps[n] = FieldTypes([object] * n)
+            maps[n] = FieldTypes([obj] * n)
         return maps[n]
 
 
@@ -126,8 +131,37 @@
             typer = FieldTypes.of_length(size)
             for i, w_val in enumerate(vars):
                 changed_type = w_val.fieldtype()
-                if changed_type is not object:
+                if changed_type is not obj:
                     typer = typer.sibling(i, changed_type)
             return typer
     except AttributeError:
-        return nilTyper
\ No newline at end of file
+        return nilTyper
+
+def sort(an_array):
+    end = len(an_array) - 1
+    sort_quick_inplace(an_array, 0, end)
+
+
+def sort_quick_inplace(an_array, start, end):
+    assert start >= 0 and end < len(an_array)
+
+    def partition(an_array, start, end):
+        key = an_array[start][0]
+        i = start - 1
+        j = end + 1
+        while True:
+            i += 1
+            j -= 1
+            while not an_array[j][0] <= key:
+                j -= 1
+            while not an_array[i][0] >= key:
+                i += 1
+            if j <= i:
+                return j
+            else:
+                an_array[i], an_array[j] = an_array[j], an_array[i]
+
+    if start < end:
+        mid = partition(an_array, start, end)
+        sort_quick_inplace(an_array, start, mid)
+        sort_quick_inplace(an_array, mid + 1, end)
\ No newline at end of file
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -131,7 +131,8 @@
         raise error.UnwrappingError("Got unexpected class in unwrap_uint")
 
     def fieldtype(self):
-        return object
+        from spyvm.fieldtypes import obj
+        return obj
 
 class W_SmallInteger(W_Object):
     """Boxed integer value"""
@@ -204,7 +205,8 @@
         return self
 
     def fieldtype(self):
-        return int
+        from spyvm.fieldtypes import SInt
+        return SInt
 
 class W_AbstractObjectWithIdentityHash(W_Object):
     """Object with explicit hash (ie all except small
@@ -310,7 +312,7 @@
         return isinstance(self.value, int)
 
     def fieldtype(self):
-        from spyvm.fieldtype import LPI
+        from spyvm.fieldtypes import LPI
         return LPI
 
 class W_Float(W_AbstractObjectWithIdentityHash):
@@ -399,7 +401,8 @@
         return 2
 
     def fieldtype(self):
-        return float
+        from spyvm.fieldtypes import flt
+        return flt
 
 @signature.finishsigs
 class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash):
@@ -631,8 +634,8 @@
                                 additionalInformation='len=%d' % self.size())
 
     def fieldtype(self):
-        # from spyvm.fieldtype import
-        return object
+        from spyvm.fieldtypes import obj
+        return obj
 
 class W_BytesObject(W_AbstractObjectWithClassReference):
     _attrs_ = ['bytes']
diff --git a/spyvm/test/test_fieldtypes.py b/spyvm/test/test_fieldtypes.py
new file mode 100644
--- /dev/null
+++ b/spyvm/test/test_fieldtypes.py
@@ -0,0 +1,33 @@
+import py
+from spyvm import model, fieldtypes
+from spyvm import objspace
+
+from spyvm.fieldtypes import obj, SInt
+
+def test_simple_changes():
+	a = fieldtypes.FieldTypes.of_length(3)
+	assert a.types == [obj, obj, obj]
+	b = a.sibling(1, SInt)
+	assert b.types == [obj, SInt, obj]
+	c = a.sibling(1, SInt)
+	assert b is c
+
+def test_two_level_changes_identity():
+	a = fieldtypes.FieldTypes.of_length(3)
+	b = a.sibling(1, SInt)
+	c = a.sibling(0, SInt)
+	d = b.sibling(0, SInt)
+	assert d.types == [SInt, SInt, obj]
+	e = c.sibling(1, SInt)
+	assert d is e
+
+def test_numberOfElements():
+	a = fieldtypes.FieldTypes.of_length(3)
+	a.sibling(0, SInt).sibling(1, SInt).sibling(2, SInt)
+	a.sibling(1, SInt).sibling(2, SInt)
+	a.sibling(2, SInt).sibling(0, SInt)
+	assert a.sibling(2, SInt).sibling(0, SInt).parent is a.sibling(0, SInt)
+	assert len(a.siblings) == 3
+	assert len(a.sibling(0, SInt).siblings) == 2
+	assert len(a.sibling(1, SInt).siblings) == 2
+	assert len(a.sibling(2, SInt).siblings) == 1 # link to [o, i, i] not created
\ No newline at end of file


More information about the pypy-commit mailing list