[pypy-svn] r48060 - in pypy/dist/pypy/lang/smalltalk: . test

niko at codespeak.net niko at codespeak.net
Fri Oct 26 15:07:57 CEST 2007


Author: niko
Date: Fri Oct 26 15:07:57 2007
New Revision: 48060

Modified:
   pypy/dist/pypy/lang/smalltalk/model.py
   pypy/dist/pypy/lang/smalltalk/objtable.py
   pypy/dist/pypy/lang/smalltalk/primitives.py
   pypy/dist/pypy/lang/smalltalk/test/test_interpreter.py
   pypy/dist/pypy/lang/smalltalk/test/test_model.py
   pypy/dist/pypy/lang/smalltalk/test/test_primitives.py
Log:
(niko, lukas, arigo)
1. initialize all object data to w_nil, not None
2. fix inst_var_at, inst_var_at_put and write better tests



Modified: pypy/dist/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/model.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/model.py	Fri Oct 26 15:07:57 2007
@@ -3,6 +3,7 @@
 from pypy.rlib.rarithmetic import intmask
 from pypy.lang.smalltalk import constants
 from pypy.tool.pairtype import extendabletype
+from pypy.rlib.objectmodel import instantiate
 
 class W_Object(object):
     __slots__ = ()    # no RPython-level instance variables allowed in W_Object
@@ -114,7 +115,7 @@
 
     def __init__(self, w_class, size):
         W_AbstractObjectWithClassReference.__init__(self, w_class)
-        self._vars = [None] * size
+        self._vars = [w_nil] * size
 
     def at(self, index0):
         return self.fetch(index0)
@@ -427,11 +428,10 @@
         return w_MethodContext
 
     def fetch(self, index):
-        from pypy.lang.smalltalk import objtable
         if index == constants.MTHDCTX_METHOD:
             return self.w_method()
         elif index == constants.MTHDCTX_RECEIVER_MAP: # what is this thing?
-            return objtable.w_nil
+            return w_nil
         elif index == constants.MTHDCTX_RECEIVER:
             return self.w_receiver
         elif index >= constants.MTHDCTX_TEMP_FRAME_START:
@@ -447,3 +447,8 @@
         else:
             return W_ContextPart.fetch(self, index)
 
+# Use black magic to create w_nil without running the constructor,
+# thus allowing it to be used even in the constructor of its own
+# class.  Note that we patch its class in objtable.
+w_nil = instantiate(W_PointersObject)
+w_nil._vars = []

Modified: pypy/dist/pypy/lang/smalltalk/objtable.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/objtable.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/objtable.py	Fri Oct 26 15:07:57 2007
@@ -49,12 +49,17 @@
 
 w_true  = ct.classtable['w_True'].as_class_get_shadow().new()
 w_false = ct.classtable['w_False'].as_class_get_shadow().new()
-w_nil = ct.classtable['w_UndefinedObject'].as_class_get_shadow().new()
 w_mone = wrap_int(-1)
 w_zero = wrap_int(0)
 w_one = wrap_int(1)
 w_two = wrap_int(2)
 
+# Very special nil hack: in order to allow W_PointersObject's to
+# initialize their fields to nil, we have to create it in the model
+# package, and then patch up its fields here:
+w_nil = model.w_nil
+w_nil.w_class = ct.classtable['w_UndefinedObject']
+
 objtable = {}
 
 for name in constants.objects_in_special_object_table:

Modified: pypy/dist/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/primitives.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/primitives.py	Fri Oct 26 15:07:57 2007
@@ -393,23 +393,22 @@
 
 @expose_primitive(INST_VAR_AT, unwrap_spec=[object, int])
 def func(interp, w_rcvr, idx):
-    # I *think* this is the correct behavior, but I'm not quite sure.
-    # Might be restricted to fixed length fields?
-    # XXX this doesn't look correct.  Our guess is that INST_VAR_AT
-    # is used to access *only* the fixed length fields.
+    "Fetches a fixed field from the object, and fails otherwise"
     shadow = w_rcvr.shadow_of_my_class()
-    if idx < 0:
-        raise PrimitiveFailedError()
-    if idx < shadow.instsize():
-        return w_rcvr.fetch(idx)
-    idx -= shadow.instsize()
-    if idx < w_rcvr.size():
-        return w_subscript(w_rcvr, idx)
-    raise PrimitiveFailedError()
-
- at expose_primitive(INST_VAR_AT_PUT, unwrap_spec=[object])
-def func(interp, w_rcvr):
-    raise PrimitiveNotYetWrittenError()
+    assert_bounds(idx, 0, shadow.instsize())
+    # only pointers have non-0 size    
+    assert isinstance(w_rcvr, model.W_PointersObject)
+    return w_rcvr.fetch(idx)
+
+ at expose_primitive(INST_VAR_AT_PUT, unwrap_spec=[object, int, object])
+def func(interp, w_rcvr, idx, w_value):
+    "Stores a value into a fixed field from the object, and fails otherwise"
+    shadow = w_rcvr.shadow_of_my_class()
+    assert_bounds(idx, 0, shadow.instsize())
+    # only pointers have non-0 size    
+    assert isinstance(w_rcvr, model.W_PointersObject)
+    w_rcvr.store(idx, w_value)
+    return w_value
 
 @expose_primitive(AS_OOP, unwrap_spec=[object])
 def func(interp, w_rcvr):

Modified: pypy/dist/pypy/lang/smalltalk/test/test_interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/test/test_interpreter.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/test/test_interpreter.py	Fri Oct 26 15:07:57 2007
@@ -174,7 +174,7 @@
             if test_index == index:
                 assert w_object.fetch(test_index) == interp.TRUE
             else:
-                assert w_object.fetch(test_index) == None
+                assert w_object.fetch(test_index) is objtable.w_nil
 
 def test_storeAndPopTemporaryVariableBytecode(bytecode=storeAndPopTemporaryVariableBytecode):
     for index in range(8):

Modified: pypy/dist/pypy/lang/smalltalk/test/test_model.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/test/test_model.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/test/test_model.py	Fri Oct 26 15:07:57 2007
@@ -1,5 +1,5 @@
 import py
-from pypy.lang.smalltalk import model, shadow
+from pypy.lang.smalltalk import model, shadow, objtable
 from pypy.lang.smalltalk.shadow import MethodNotFound
 import pypy.lang.smalltalk.classtable as ct
 
@@ -17,7 +17,7 @@
     w_myinstance = w_mycls.as_class_get_shadow().new()
     assert isinstance(w_myinstance, model.W_PointersObject)
     assert w_myinstance.getclass() is w_mycls
-    assert w_myinstance.fetch(0) is None
+    assert w_myinstance.fetch(0) is objtable.w_nil
     py.test.raises(IndexError, lambda: w_myinstance.fetch(3))
     w_myinstance.store(1, w_myinstance)
     assert w_myinstance.fetch(1) is w_myinstance

Modified: pypy/dist/pypy/lang/smalltalk/test/test_primitives.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/test/test_primitives.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/test/test_primitives.py	Fri Oct 26 15:07:57 2007
@@ -242,12 +242,16 @@
     prim_fails(primitives.NEW_WITH_ARG, [w_Object, 20])
     
 def test_inst_var_at():
-    # I am not entirely sure if this is what this primitive is
-    # supposed to do, so the test may be bogus:
     w_v = prim(primitives.INST_VAR_AT, ["q", constants.CHARACTER_VALUE_INDEX])
     assert w_v.value == ord("q")
-    w_v = prim(primitives.INST_VAR_AT, ["abc", 1])
-    assert w_v.value == ord("b")
+
+def test_inst_var_at_put():
+    w_q = classtable.w_Character.as_class_get_shadow().new()
+    vidx = constants.CHARACTER_VALUE_INDEX
+    ordq = ord("q")
+    assert prim(primitives.INST_VAR_AT, [w_q, vidx]) == objtable.w_nil
+    assert prim(primitives.INST_VAR_AT_PUT, [w_q, vidx, ordq]).value == ordq
+    assert prim(primitives.INST_VAR_AT, [w_q, vidx]).value == ordq
 
 def test_class():
     assert prim(primitives.CLASS, ["string"]) == classtable.w_String



More information about the Pypy-commit mailing list