[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