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

niko at codespeak.net niko at codespeak.net
Wed Oct 24 16:18:35 CEST 2007


Author: niko
Date: Wed Oct 24 16:18:35 2007
New Revision: 47833

Modified:
   pypy/dist/pypy/lang/smalltalk/primitives.py
   pypy/dist/pypy/lang/smalltalk/test/test_primitives.py
Log:
define the "quick push constant" primitives



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 16:18:35 2007
@@ -18,9 +18,6 @@
     elif isinstance(w_v, model.W_SmallInteger): return float(w_v.value)
     raise PrimitiveFailedError()
 
-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)
@@ -30,13 +27,20 @@
         return fimg.wrap_int(w_obj.getbyte(idx))
     raise PrimitiveFailedError()
 
+def assert_bounds(idx, minb, maxb):
+    if idx < minb or idx >= maxb:
+        raise PrimitiveFailedError()
+
+def assert_valid_index(idx, w_obj):
+    assert_bounds(idx, 0, w_obj.size())
+
 # ___________________________________________________________________________
 # Primitive table: it is filled in at initialization time with the
 # primitive functions.  Each primitive function takes a single argument,
 # the frame (a W_ContextFrame object); the function either completes, and
 # returns a result, or throws a PrimitiveFailedError.
 
-prim_table = [None] * 127
+prim_table = [None] * 576 # Squeak has primitives all the way up to 575
 
 def primitive(code):
     def decorator(func):
@@ -121,25 +125,17 @@
 SIZE = 62
 STRING_AT = 63
 STRING_AT_PUT = 64
-OBJECT_AT = 68
-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
     idx = unwrap_int(w_idx)
-    if not is_valid_index(idx, w_obj):
-        raise PrimitiveFailedError()
+    assert_valid_index(idx, w_obj)
     return idx, w_obj
 
 def common_at_put(stack):
     [w_val, w_idx, w_obj] = stack
     idx = unwrap_int(w_idx)
-    if not is_valid_index(idx, w_obj):
-        raise PrimitiveFailedError()
+    assert_valid_index(idx, w_obj)
     return w_val, idx, w_obj
 
 @primitive(AT)
@@ -179,13 +175,27 @@
     w_obj.setbyte(idx, fimg.ord_w_char(w_val))
     return w_val
 
+# ___________________________________________________________________________
+# Storage Management Primitives
+
+OBJECT_AT = 68
+OBJECT_AT_PUT = 69
+NEW = 70
+NEW_WITH_ARG = 71
+ARRAY_BECOME_ONE_WAY = 72     # Blue Book: primitiveBecome
+INST_VAR_AT = 73
+INST_VAR_AT_PUT = 74
+AS_OOP = 75                  
+STORE_STACKP = 76             # Blue Book: primitiveAsObject
+SOME_INSTANCE = 77
+NEXT_INSTANCE = 78
+
 @primitive(OBJECT_AT)
 @stack(2)
 def func(stack):
     [w_idx, w_rcvr] = stack
     idx = unwrap_int(w_idx)
-    if idx < 0 or idx >= w_rcvr.w_class.instvarsize:
-        raise PrimitiveFailedError()
+    assert_bounds(idx, 0, w_rcvr.w_class.instvarsize)
     return w_rcvr.getnamedvar(idx)
 
 @primitive(OBJECT_AT_PUT)
@@ -193,12 +203,10 @@
 def func(stack):
     [w_val, w_idx, w_rcvr] = stack
     idx = unwrap_int(w_idx)
-    if idx < 0 or idx >= w_rcvr.w_class.instvarsize:
-        raise PrimitiveFailedError()
+    assert_bounds(idx, 0, w_rcvr.w_class.instvarsize)
     w_rcvr.setnamedvar(idx, w_val)
     return w_val
 
-
 @primitive(NEW)
 @stack(1)
 def func(stack):
@@ -216,6 +224,10 @@
     size = unwrap_int(w_size)
     return w_cls.new(size)
 
+ at primitive(ARRAY_BECOME_ONE_WAY)
+def func(frame):
+    raise PrimitiveNotYetWrittenError
+
 @primitive(INST_VAR_AT)
 @stack(2)
 def func(stack):
@@ -233,6 +245,10 @@
         return subscript(idx, w_rcvr)
     raise PrimitiveFailedError()
 
+ at primitive(INST_VAR_AT_PUT)
+def func(frame):
+    raise PrimitiveNotYetWrittenError()
+
 @primitive(AS_OOP)
 @stack(1)
 def func(stack):
@@ -241,6 +257,30 @@
         raise PrimitiveFailedError()
     return w_rcvr.w_hash
 
+ at primitive(STORE_STACKP)
+ at stack(2)
+def func(stack):
+    # This primitive seems to resize the stack.  I don't think this is
+    # really relevant in our implementation.
+    raise PrimitiveNotYetWrittenError()
+
+ at primitive(SOME_INSTANCE)
+ at stack(1)
+def func(stack):
+    # This primitive returns some instance of the class on the stack.
+    # Not sure quite how to do this; maintain a weak list of all
+    # existing instances or something?
+    [w_class] = stack
+    raise PrimitiveNotYetWrittenError()
+
+ at primitive(NEXT_INSTANCE)
+ at stack(1)
+def func(stack):
+    # This primitive is used to iterate through all instances of a class:
+    # it returns the "next" instance after w_obj.
+    [w_obj] = stack
+    raise PrimitiveNotYetWrittenError()
+
 # ___________________________________________________________________________
 # Boolean Primitives
 
@@ -287,3 +327,38 @@
         res = op(v1, v2)
         w_res = fimg.wrap_bool(res)
         return w_res
+    
+# ___________________________________________________________________________
+# Quick Push Const Primitives
+
+PUSH_SELF = 256
+PUSH_TRUE = 257
+PUSH_FALSE = 258
+PUSH_NIL = 259
+PUSH_MINUS_ONE = 260
+PUSH_ZERO = 261
+PUSH_ONE = 262
+PUSH_TWO = 263
+
+ at primitive(PUSH_SELF)
+ at stack(1)
+def func(stack):
+    [w_self] = stack
+    return w_self
+
+def define_const_primitives():
+    for (code, const) in [
+        (PUSH_TRUE, fimg.w_true),
+        (PUSH_FALSE, fimg.w_false),
+        (PUSH_NIL, fimg.w_nil),
+        (PUSH_MINUS_ONE, fimg.w_mone),
+        (PUSH_ZERO, fimg.w_zero),
+        (PUSH_ONE, fimg.w_one),
+        (PUSH_TWO, fimg.w_two),
+        ]:
+        @primitive(code)
+        @stack(1)
+        def func(stack, const=const):  # n.b.: capture const
+            return const
+define_const_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 16:18:35 2007
@@ -133,6 +133,20 @@
 def test_as_oop_not_applicable_to_int():
     prim_fails(p.AS_OOP, [22])
 
+def test_const_primitives():
+    for (code, const) in [
+        (p.PUSH_TRUE, fimg.w_true),
+        (p.PUSH_FALSE, fimg.w_false),
+        (p.PUSH_NIL, fimg.w_nil),
+        (p.PUSH_MINUS_ONE, fimg.w_mone),
+        (p.PUSH_ZERO, fimg.w_zero),
+        (p.PUSH_ONE, fimg.w_one),
+        (p.PUSH_TWO, fimg.w_two),
+        ]:
+        assert prim(code, [fimg.w_nil]) is const
+    assert prim(p.PUSH_SELF, [fimg.w_nil]) is fimg.w_nil
+    assert prim(p.PUSH_SELF, ["a"]) is wrap("a")
+
 def test_boolean():
     assert prim(p.LESSTHAN, [1,2]) == fimg.w_true
     assert prim(p.GREATERTHAN, [3,4]) == fimg.w_false



More information about the Pypy-commit mailing list