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

niko at codespeak.net niko at codespeak.net
Wed Oct 24 15:46:01 CEST 2007


Author: niko
Date: Wed Oct 24 15:46:00 2007
New Revision: 47831

Modified:
   pypy/dist/pypy/lang/smalltalk/fakeimage.py
   pypy/dist/pypy/lang/smalltalk/model.py
   pypy/dist/pypy/lang/smalltalk/primitives.py
   pypy/dist/pypy/lang/smalltalk/test/test_primitives.py
Log:
1. add w_hash to the model
2. add as_oop, inst_var_at primitive
3. rename make_XXX to wrap_XXX for consistency



Modified: pypy/dist/pypy/lang/smalltalk/fakeimage.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/fakeimage.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/fakeimage.py	Wed Oct 24 15:46:00 2007
@@ -4,19 +4,21 @@
 # ___________________________________________________________________________
 # Utility Methods
 
-def small_int(i):
-    return model.W_SmallInteger(ct.w_SmallInteger, i)
+def wrap_int(i):
+    if i <= 0x3FFFFFFF and i >= -0x40000000:
+        return model.W_SmallInteger(ct.w_SmallInteger, i)
+    raise NotImplementedError
 
 def wrap_float(i):
     return model.W_Float(ct.w_Float,i)
 
-def make_string(str):
+def wrap_string(str):
     w_inst = ct.w_ByteString.new(len(str))
     for i in range(len(str)):
         w_inst.setbyte(i, ord(str[i]))
     return w_inst
 
-def make_char(c):
+def wrap_char(c):
     return CharacterTable[ord(c)]
 
 def ord_w_char(w_c):
@@ -45,19 +47,19 @@
 # ___________________________________________________________________________
 # Global Data
 
-def make_char_table():
+def wrap_char_table():
     global CharacterTable
     def bld_char(i):
         w_cinst = ct.w_Character.new()
-        w_cinst.setnamedvar(CHARACTER_VALUE_INDEX, small_int(i))
+        w_cinst.setnamedvar(CHARACTER_VALUE_INDEX, wrap_int(i))
         return w_cinst
     CharacterTable = [bld_char(i) for i in range(256)]
-make_char_table()
+wrap_char_table()
 
 w_true  = ct.w_True.new()
 w_false = ct.w_False.new()
 w_nil = ct.w_UndefinedObject.new()
-w_mone = small_int(-1)
-w_zero = small_int(0)
-w_one = small_int(1)
-w_two = small_int(2)
+w_mone = wrap_int(-1)
+w_zero = wrap_int(0)
+w_one = wrap_int(1)
+w_two = wrap_int(2)

Modified: pypy/dist/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/model.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/model.py	Wed Oct 24 15:46:00 2007
@@ -2,10 +2,11 @@
 class W_Object:
     def __init__(self, w_class):
         self.w_class = w_class
-        
+        self.w_hash = None # XXX initial value?
+
     def size(self):
         return 0
-        
+
     def instvarsize(self):
         return self.w_class.instvarsize        
 
@@ -126,12 +127,38 @@
         self.instvarsize = instvarsize
         self.format = format
 
-    def isindexable(self):
+    # _______________________________________________________________
+    # Methods for querying the format word, taken from the blue book:
+    #
+    # included so that we can reproduce code from the reference impl
+    # more easily
+
+    def ispointers(self):
+        " True if instances of this class have data stored as pointers "
+        return self.format in (POINTERS, VAR_POINTERS)
+
+    def iswords(self):
+        " True if instances of this class have data stored as numerical words "
+        return self.format in (POINTERS, VAR_POINTERS, WORDS)
+
+    def isbytes(self):
+        " True if instances of this class have data stored as numerical bytes "
+        return self.format == BYTES
+
+    def isvariable(self):
+        " True if instances of this class have indexed inst variables "
         return self.format in (VAR_POINTERS, WORDS, BYTES)
 
+    def instsize(self):
+        " Number of named instance variables for each instance of this class "
+        return self.instvarsize
+
     def ismetaclass(self):
         return False
 
+    # _______________________________________________________________
+    # Methods for querying the format word, taken from the blue book:
+
     def new(self, size=0):
         if self.format == POINTERS:
             assert size == 0

Modified: pypy/dist/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/primitives.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/primitives.py	Wed Oct 24 15:46:00 2007
@@ -21,6 +21,15 @@
 def is_valid_index(idx, w_obj):
     return idx >= 0 and idx < w_obj.size()
 
+def subscript(idx, w_obj):
+    if isinstance(w_obj, model.W_PointersObject):
+        return w_obj.getindexedvar(idx)
+    elif isinstance(w_obj, model.W_WordsObject):
+        return fimg.wrap_int(w_obj.getword(idx))
+    elif isinstance(w_obj, model.W_BytesObject):
+        return fimg.wrap_int(w_obj.getbyte(idx))
+    raise PrimitiveFailedError()
+
 # ___________________________________________________________________________
 # Primitive table: it is filled in at initialization time with the
 # primitive functions.  Each primitive function takes a single argument,
@@ -68,7 +77,7 @@
         if res > 1073741823: raise PrimitiveFailedError()
         if res < -1073741824: raise PrimitiveFailedError()
         
-        w_res = fimg.small_int(res)
+        w_res = fimg.wrap_int(res)
         return w_res
     prim_table[code] = func
 
@@ -116,6 +125,8 @@
 OBJECT_AT_PUT = 69
 NEW = 70
 NEW_WITH_ARG = 71
+INST_VAR_AT = 73
+AS_OOP = 75
 
 def common_at(stack):
     [w_idx, w_obj] = stack
@@ -148,7 +159,7 @@
 @stack(1)
 def func(stack):
     [w_obj] = stack
-    if not w_obj.w_class.isindexable():
+    if not w_obj.w_class.isvariable():
         raise PrimitiveFailedError()
     return w_obj.size()
 
@@ -187,11 +198,12 @@
     w_rcvr.setnamedvar(idx, w_val)
     return w_val
 
+
 @primitive(NEW)
 @stack(1)
 def func(stack):
     [w_cls] = stack
-    if not isinstance(w_cls, model.W_Class) or w_cls.isindexable():
+    if not isinstance(w_cls, model.W_Class) or w_cls.isvariable():
         raise PrimitiveFailedError()
     return w_cls.new()
 
@@ -199,11 +211,36 @@
 @stack(2)
 def func(stack):
     [w_size, w_cls] = stack
-    if not isinstance(w_cls, model.W_Class) or not w_cls.isindexable():
+    if not isinstance(w_cls, model.W_Class) or not w_cls.isvariable():
         raise PrimitiveFailedError()
     size = unwrap_int(w_size)
     return w_cls.new(size)
 
+ at primitive(INST_VAR_AT)
+ at stack(2)
+def func(stack):
+    # I *think* this is the correct behavior, but I'm not quite sure.
+    # Might be restricted to fixed length fields?
+    [w_idx, w_rcvr] = stack
+    idx = unwrap_int(w_idx)
+    w_cls = w_rcvr.w_class
+    if idx < 0:
+        raise PrimitiveFailedError()
+    if idx < w_cls.instvarsize:
+        return w_rcvr.getnamedvar(idx)
+    idx -= w_cls.instvarsize
+    if idx < w_rcvr.size():
+        return subscript(idx, w_rcvr)
+    raise PrimitiveFailedError()
+
+ at primitive(AS_OOP)
+ at stack(1)
+def func(stack):
+    [w_rcvr] = stack
+    if isinstance(w_rcvr, model.W_SmallInteger):
+        raise PrimitiveFailedError()
+    return w_rcvr.w_hash
+
 # ___________________________________________________________________________
 # Boolean Primitives
 

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	Wed Oct 24 15:46:00 2007
@@ -11,11 +11,11 @@
         self.stack = stack
 
 def wrap(x):
-    if isinstance(x, int): return fimg.small_int(x)
+    if isinstance(x, int): return fimg.wrap_int(x)
     if isinstance(x, float): return fimg.wrap_float(x)
     if isinstance(x, model.W_Object): return x
-    if isinstance(x, str) and len(x) == 1: return fimg.make_char(x)
-    if isinstance(x, str): return fimg.make_string(x)
+    if isinstance(x, str) and len(x) == 1: return fimg.wrap_char(x)
+    if isinstance(x, str): return fimg.wrap_string(x)
     raise NotImplementedError
     
 def mock(stack):
@@ -116,6 +116,22 @@
 
 def test_invalid_new_with_arg():
     prim_fails(p.NEW_WITH_ARG, [ct.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(p.INST_VAR_AT, ["q", fimg.CHARACTER_VALUE_INDEX])
+    assert w_v.value == ord("q")
+    w_v = prim(p.INST_VAR_AT, ["abc", 1])
+    assert w_v.value == ord("b")
+
+def test_as_oop():
+    w_obj = model.W_Class(None, None, 0, format=model.POINTERS).new()
+    w_obj.w_hash = wrap(22)
+    assert prim(p.AS_OOP, [w_obj]).value == 22
+
+def test_as_oop_not_applicable_to_int():
+    prim_fails(p.AS_OOP, [22])
 
 def test_boolean():
     assert prim(p.LESSTHAN, [1,2]) == fimg.w_true



More information about the Pypy-commit mailing list