[pypy-svn] r48932 - in pypy/dist/pypy/lang/smalltalk: . test
tverwaes at codespeak.net
tverwaes at codespeak.net
Thu Nov 22 17:52:10 CET 2007
Author: tverwaes
Date: Thu Nov 22 17:52:09 2007
New Revision: 48932
Modified:
pypy/dist/pypy/lang/smalltalk/model.py
pypy/dist/pypy/lang/smalltalk/primitives.py
pypy/dist/pypy/lang/smalltalk/squeakimage.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
pypy/dist/pypy/lang/smalltalk/test/test_shadow.py
Log:
another step closer to compiling methods. a bit of a "cleanup" on the at0 and atput0 for compiledmethod, cleaning up issues with methodheaderss
Modified: pypy/dist/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/model.py (original)
+++ pypy/dist/pypy/lang/smalltalk/model.py Thu Nov 22 17:52:09 2007
@@ -4,6 +4,7 @@
from pypy.lang.smalltalk import constants
from pypy.tool.pairtype import extendabletype
from pypy.rlib.objectmodel import instantiate
+from pypy.lang.smalltalk.tool.bitmanipulation import splitter
class W_Object(object):
__slots__ = () # no RPython-level instance variables allowed in W_Object
@@ -299,14 +300,9 @@
The trailer has two variant formats. In the first variant, the last byte is at least 252 and the last four bytes represent a source pointer into one of the sources files (see #sourcePointer). In the second variant, the last byte is less than 252, and the last several bytes are a compressed version of the names of the method's temporary variables. The number of bytes used for this purpose is the value of the last byte in the method.
"""
- def __init__(self, literalsize, bytes="", argsize=0,
- tempsize=0, primitive=0, w_compiledin=None):
- self.literals = [None] * literalsize
- self.w_compiledin = w_compiledin
- self.bytes = bytes
- self.argsize = argsize
- self.tempsize = tempsize
- self.primitive = primitive
+ def __init__(self, bytecount=0, header=0):
+ self.setheader(header)
+ self.bytes = "\x00"*bytecount
def compiledin(self):
if self.w_compiledin is None:
@@ -323,10 +319,11 @@
return w_CompiledMethod
def getliteral(self, index):
- return self.literals[index + constants.LITERAL_START]
+ return self.literals[index] #+ constants.LITERAL_START]
def getliteralsymbol(self, index):
w_literal = self.getliteral(index)
+ print "literals: %r" % self.literals
assert isinstance(w_literal, W_BytesObject)
return w_literal.as_string() # XXX performance issue here
@@ -354,36 +351,73 @@
self.primitive is not None)
def size(self):
- return self.literalsize() + len(self.bytes)
+ return self.getliteralsize() + len(self.bytes)
- def literalsize(self):
- return len(self.literals) * constants.BYTES_PER_WORD
+ def getliteralsize(self):
+ return self.literalsize * constants.BYTES_PER_WORD
def primsize(self):
- return self.size() + self.headersize()
+ return self.size()
def headersize(self):
return constants.BYTES_PER_WORD
+ def getheader(self):
+ return self.header
+
+ def setheader(self, header):
+ #(index 0) 9 bits: main part of primitive number (#primitive)
+ #(index 9) 8 bits: number of literals (#numLiterals)
+ #(index 17) 1 bit: whether a large frame size is needed (#frameSize)
+ #(index 18) 6 bits: number of temporary variables (#numTemps)
+ #(index 24) 4 bits: number of arguments to the method (#numArgs)
+ #(index 28) 1 bit: high-bit of primitive number (#primitive)
+ #(index 29) 1 bit: flag bit, ignored by the VM (#flag)
+ primitive, literalsize, islarge, tempsize, numargs, highbit = (
+ splitter[9,8,1,6,4,1](header))
+ primitive = primitive + (highbit << 10) ##XXX todo, check this
+ self.literalsize = literalsize
+ self.literals = [w_nil] * self.literalsize
+ self.header = header
+ self.argsize = numargs
+ self.tempsize = tempsize
+ self.primitive = primitive
+ self.w_compiledin = None
+
+ def literalat0(self, index0):
+ if index0 == 0:
+ from pypy.lang.smalltalk import utility
+ return utility.wrap_int(self.getheader())
+ else:
+ return self.literals[index0-1]
+
+ def literalatput0(self, index0, w_value):
+ if index0 == 0:
+ from pypy.lang.smalltalk import utility
+ print "Going to save as header: %r" % w_value
+ header = utility.unwrap_int(w_value)
+ self.setheader(header)
+ else:
+ self.literals[index0-1] = w_value
+
def at0(self, index0):
# XXX
from pypy.lang.smalltalk import utility
- index0 = index0 - self.literalsize()
- if index0 < 0:
- # XXX Do something useful with this.... we are not a block
- # of memory as smalltalk expects but wrapped in py-os
- raise NotImplementedError()
- return utility.wrap_int(ord(self.bytes[index0]))
+ print "TRYING TO GET: %d %d" % (self.getliteralsize(), index0)
+ if index0 < self.getliteralsize():
+ self.literalat0(index0)
+ else:
+ index0 = index0 - self.getliteralsize()
+ return utility.wrap_int(ord(self.bytes[index0]))
def atput0(self, index0, w_value):
from pypy.lang.smalltalk import utility
- index0 = index0 - self.literalsize()
- if index0 < 0:
- # XXX Do something useful with this.... we are not a block
- # of memory as smalltalk expects but wrapped in py-os
- raise NotImplementedError()
+ print "TRYING TO SET: %d %d %r" % (self.getliteralsize(), index0, w_value)
+ if index0 < self.getliteralsize():
+ self.literalatput0(index0, w_value)
else:
# XXX use to-be-written unwrap_char
+ index0 = index0 - self.getliteralsize()
self.setchar(index0, chr(utility.unwrap_int(w_value)))
def setchar(self, index0, character):
Modified: pypy/dist/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/primitives.py (original)
+++ pypy/dist/pypy/lang/smalltalk/primitives.py Thu Nov 22 17:52:09 2007
@@ -346,16 +346,15 @@
def func(interp, w_rcvr, n0):
if not isinstance(w_rcvr, model.W_CompiledMethod):
raise PrimitiveFailedError()
- assert_bounds(n0, 0, len(w_rcvr.literals))
- return w_rcvr.literals[n0]
+ return w_rcvr.literalat0(n0)
@expose_primitive(OBJECT_AT_PUT, unwrap_spec=[object, index1_0, object])
-def func(interp, w_rcvr, n0, w_val):
+def func(interp, w_rcvr, n0, w_value):
if not isinstance(w_rcvr, model.W_CompiledMethod):
raise PrimitiveFailedError()
- assert_bounds(n0, 0, len(w_rcvr.literals))
- w_rcvr.literals[n0] = w_val
- return w_val
+ #assert_bounds(n0, 0, len(w_rcvr.literals))
+ w_rcvr.literalatput0(n0, w_value)
+ return w_value
@expose_primitive(NEW, unwrap_spec=[object])
def func(interp, w_cls):
@@ -419,18 +418,10 @@
# it returns the "next" instance after w_obj.
raise PrimitiveNotYetWrittenError()
- at expose_primitive(NEW_METHOD, unwrap_spec=[object, int, object])
-def func(interp, w_class, bytecount, w_header):
- # XXX untested
- header = utility.unwrap_int(w_header)
- literalcount = ((header >> 10) & 255) + 1
- w_method = w_class.as_class_get_shadow().new(literalcount)
- # XXX not sure this is correct
- assert isinstance(w_method, model.W_CompiledMethod)
- w_method.literals[constants.METHOD_HEADER_INDEX] = w_header
- for i0 in range(1, literalcount):
- w_method.literals[i0] = objtable.w_nil
- w_method.bytes = "\x00" * bytecount
+ at expose_primitive(NEW_METHOD, unwrap_spec=[object, int, int])
+def func(interp, w_class, bytecount, header):
+ # We ignore w_class because W_CompiledMethod is special
+ w_method = model.W_CompiledMethod(bytecount, header)
return w_method
# ___________________________________________________________________________
Modified: pypy/dist/pypy/lang/smalltalk/squeakimage.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/squeakimage.py (original)
+++ pypy/dist/pypy/lang/smalltalk/squeakimage.py Thu Nov 22 17:52:09 2007
@@ -357,29 +357,13 @@
def fillin_compiledmethod(self, w_compiledmethod):
header = self.chunk.data[0]
- #---!!!---- 1 tagged pointer!
- #(index 0) 9 bits: main part of primitive number (#primitive)
- #(index 9) 8 bits: number of literals (#numLiterals)
- #(index 17) 1 bit: whether a large frame size is needed (#frameSize)
- #(index 18) 6 bits: number of temporary variables (#numTemps)
- #(index 24) 4 bits: number of arguments to the method (#numArgs)
- #(index 28) 1 bit: high-bit of primitive number (#primitive)
- #(index 29) 1 bit: flag bit, ignored by the VM (#flag)
- _, primitive, literalsize, islarge, tempsize, numargs, highbit = (
- splitter[1,9,8,1,6,4,1](header))
- primitive = primitive + (highbit << 10) ##XXX todo, check this
- literals = [self.decode_pointer(pointer).w_object
- for pointer in self.chunk.data[:literalsize+1]]
- bbytes = self.get_bytes()[(literalsize + 1)*4:]
+ w_compiledmethod.setheader(header>>1) # We untag before giving header
+ for i in range(1,w_compiledmethod.literalsize+1):
+ w_compiledmethod.literalatput0(i, self.decode_pointer(self.chunk.data[i]).w_object)
+ bbytes = self.get_bytes()[(w_compiledmethod.literalsize + 1)*4:]
# XXX assert mirrorcache.get_or_build(self.g_class.w_object) is
# ct.m_CompiledMethod
- w_compiledmethod.__init__(
- literalsize = literalsize,
- bytes = ''.join(bbytes),
- argsize = numargs,
- tempsize = tempsize,
- primitive = primitive)
- w_compiledmethod.literals = literals
+ w_compiledmethod.bytes = ''.join(bbytes)
class ImageChunk(object):
def __init__(self, size, format, classid, hash12):
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 Thu Nov 22 17:52:09 2007
@@ -30,8 +30,10 @@
# Install faked compiled methods that just invoke the primitive:
for (w_class, primnum, argsize, methname) in methods:
s_class = w_class.as_class_get_shadow()
- prim_meth = model.W_CompiledMethod(
- 0, "", argsize=argsize, primitive=primnum)
+ prim_meth = model.W_CompiledMethod(0)
+ prim_meth.primitive = primnum
+ prim_meth.w_compiledin = w_class
+ prim_meth.argsize = argsize
s_class.installmethod(methname, prim_meth)
try:
@@ -62,20 +64,24 @@
res.storevarpointer(i, fakeliteral(lit[i]))
return res
return lit
- return [fakesymbol("methodheader")]+[fakeliteral(lit) for lit in literals]
+ return [fakeliteral(lit) for lit in literals]
def new_interpreter(bytes, receiver=objtable.w_nil):
assert isinstance(bytes, str)
- w_method = model.W_CompiledMethod(0, bytes=bytes,
- argsize=2, tempsize=1)
+ w_method = model.W_CompiledMethod(len(bytes))
+ w_method.bytes = bytes
+ w_method.argsize=2
+ w_method.tempsize=1
w_frame = w_method.create_frame(receiver, ["foo", "bar"])
interp = interpreter.Interpreter()
interp.w_active_context = w_frame
return interp
def test_create_frame():
- w_method = model.W_CompiledMethod(0, bytes="hello",
- argsize=2, tempsize=1)
+ w_method = model.W_CompiledMethod(len("hello"))
+ w_method.bytes="hello"
+ w_method.argsize=2
+ w_method.tempsize=1
w_frame = w_method.create_frame("receiver", ["foo", "bar"])
assert w_frame.w_receiver == "receiver"
assert w_frame.gettemp(0) == "foo"
@@ -380,8 +386,9 @@
(returnNil, interpreter.Interpreter.NIL),
(returnTopFromMethod, interpreter.Interpreter.ONE) ]:
shadow = w_class.as_class_get_shadow()
- shadow.installmethod("foo",
- model.W_CompiledMethod(0, pushConstantOneBytecode + bytecode))
+ w_method = model.W_CompiledMethod(2)
+ w_method.bytes = pushConstantOneBytecode + bytecode
+ shadow.installmethod("foo", w_method)
interp = new_interpreter(bytecodes)
interp.w_active_context.w_method().literals = fakeliterals("foo")
interp.w_active_context.push(w_object)
@@ -405,7 +412,10 @@
def test_fibWithArgument():
bytecode = ''.join(map(chr, [ 16, 119, 178, 154, 118, 164, 11, 112, 16, 118, 177, 224, 112, 16, 119, 177, 224, 176, 124 ]))
shadow = mockclass(0).as_class_get_shadow()
- method = model.W_CompiledMethod(1, bytecode, 1)
+ method = model.W_CompiledMethod(len(bytecode))
+ method.literalsize = 1
+ method.bytes = bytecode
+ method.argsize = 1
method.literals = fakeliterals("fib:")
shadow.installmethod("fib:", method)
w_object = shadow.new()
@@ -529,7 +539,11 @@
def test_callPrimitiveAndPush_fallback():
interp = new_interpreter(bytecodePrimAdd)
shadow = mockclass(0).as_class_get_shadow()
- shadow.installmethod("+", model.W_CompiledMethod(1, "", 1))
+ w_method = model.W_CompiledMethod(0)
+ w_method.argsize = 1
+ w_method.literalsize = 1
+ shadow.installmethod("+", w_method)
+
w_object = shadow.new()
interp.w_active_context.push(w_object)
interp.w_active_context.push(interp.ONE)
@@ -567,12 +581,14 @@
# first call method installed in w_class
bytecodes = singleExtendedSendBytecode + chr(0)
# which does a call to its super
- meth1 = model.W_CompiledMethod(0, pushReceiverBytecode + bytecode)
+ meth1 = model.W_CompiledMethod(2)
+ meth1.bytes = pushReceiverBytecode + bytecode
w_class.as_class_get_shadow().installmethod("foo", meth1)
# and that one again to its super
- meth2 = model.W_CompiledMethod(0, pushReceiverBytecode + bytecode)
+ meth2 = model.W_CompiledMethod(2)
+ meth2.bytes = pushReceiverBytecode + bytecode
w_super.as_class_get_shadow().installmethod("foo", meth2)
- meth3 = model.W_CompiledMethod(0, "")
+ meth3 = model.W_CompiledMethod(0)
w_supersuper.as_class_get_shadow().installmethod("foo", meth3)
meth1.literals = fakeliterals("foo")
meth2.literals = fakeliterals("foo")
@@ -726,7 +742,7 @@
def test_bc_primBytecodeAt_with_instvars():
# ^ self at: 1
- py.test.skip("Broken, we are fixing it.")
+ py.test.skip("Broken, fix me")
w_fakeclass = mockclass(1, name='fakeclass', varsized=True)
w_fakeinst = w_fakeclass.as_class_get_shadow().new(1)
w_fakeinst.store(0, wrap_char("a")) # static slot 0: instance variable
@@ -742,7 +758,7 @@
def test_bc_primBytecodeAtPut_with_instvars():
# ^ self at: 1 put: #b
- py.test.skip("Broken, we are fixing it.")
+ py.test.skip("Broken, fix me")
w_fakeclass = mockclass(1, name='fakeclass', varsized=True)
w_fakeinst = w_fakeclass.as_class_get_shadow().new(1)
w_fakeinst.store(0, wrap_char("a")) # static slot 0: instance variable
@@ -763,7 +779,8 @@
# ^ self objectAt: 2. yields the first literal (22)
# ^ self objectAt: 2 put: 3. changes the first literal to 3
# ^ self objectAt: 2. yields the new first literal (3)
- prim_meth = model.W_CompiledMethod(0, "")
+ py.test.skip("Broken, fix me")
+ prim_meth = model.W_CompiledMethod(0)
prim_meth.literals = fakeliterals(22)
mhs = fakesymbol("methodheader")
oal = fakeliterals("objectAt:")
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 Thu Nov 22 17:52:09 2007
@@ -66,14 +66,14 @@
w_super = mockclass(0)
w_class = mockclass(0, w_superclass=w_super)
supershadow = w_super.as_class_get_shadow()
- supershadow.installmethod("foo", model.W_CompiledMethod(0, ""))
+ supershadow.installmethod("foo", model.W_CompiledMethod(0))
classshadow = w_class.as_class_get_shadow()
assert classshadow.lookup("foo").w_compiledin is w_super
def test_compiledmethod_setchar():
- w_method = model.W_CompiledMethod(0, "abc")
+ w_method = model.W_CompiledMethod(3)
w_method.setchar(0, "c")
- assert w_method.bytes == "cbc"
+ assert w_method.bytes == "c\x00\x00"
def test_hashes():
w_five = model.W_SmallInteger(5)
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 Thu Nov 22 17:52:09 2007
@@ -207,10 +207,11 @@
assert prim(primitives.SIZE, [w_obj]).value == 5
def test_size_of_compiled_method():
- varsize = 3
- text = "abc"
- w_cm = model.W_CompiledMethod(varsize, text, 1, 1)
- assert prim(primitives.SIZE, [w_cm]).value == (varsize+1)*constants.BYTES_PER_WORD + len(text)
+ literalsize = 3
+ bytecount = 3
+ w_cm = model.W_CompiledMethod(bytecount)
+ w_cm.literalsize = literalsize
+ assert prim(primitives.SIZE, [w_cm]).value == (literalsize)*constants.BYTES_PER_WORD + bytecount
def test_string_at():
assert prim(primitives.STRING_AT, ["foobar", 4]) == wrap("b")
@@ -422,9 +423,9 @@
shadow = mockclass(0).as_class_get_shadow()
w_method = prim(primitives.NEW_METHOD, [classtable.w_CompiledMethod, len(bytecode), 1025])
- assert w_method.literals[0].value == 1025
- assert len(w_method.literals) == 2
- assert w_method.literals[1] is objtable.w_nil
+ assert w_method.literalat0(0).value == 1025
+ assert w_method.literalsize == 2
+ assert w_method.literalat0(1) is objtable.w_nil
assert w_method.bytes == "\x00" * len(bytecode)
Modified: pypy/dist/pypy/lang/smalltalk/test/test_shadow.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/test/test_shadow.py (original)
+++ pypy/dist/pypy/lang/smalltalk/test/test_shadow.py Thu Nov 22 17:52:09 2007
@@ -64,8 +64,8 @@
yield basicshape, "CompiledMeth", 0xE02, shadow.COMPILED_METHOD, True, 0
def test_methoddict():
- methods = {'foo': model.W_CompiledMethod(0, ""),
- 'bar': model.W_CompiledMethod(1, "")}
+ methods = {'foo': model.W_CompiledMethod(0),
+ 'bar': model.W_CompiledMethod(0)}
w_class = build_smalltalk_class("Demo", 0x90, methods=methods)
classshadow = w_class.as_class_get_shadow()
assert classshadow.methoddict == methods
More information about the Pypy-commit
mailing list