[pypy-svn] r51867 - in pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk: . test
tverwaes at codespeak.net
tverwaes at codespeak.net
Mon Feb 25 23:32:11 CET 2008
Author: tverwaes
Date: Mon Feb 25 23:32:10 2008
New Revision: 51867
Modified:
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_interpreter.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_primitives.py
pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_shadow.py
Log:
slowed down the implementaton but made it more flexible by removing
W_*Context* and fully going in the direction of shadows.
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py Mon Feb 25 23:32:10 2008
@@ -1,7 +1,6 @@
import py
from pypy.lang.smalltalk import model, constants, primitives
from pypy.lang.smalltalk import objtable
-from pypy.lang.smalltalk.model import W_ContextPart
from pypy.lang.smalltalk.shadow import ContextPartShadow
from pypy.lang.smalltalk.conftest import option
from pypy.rlib import objectmodel, unroll
@@ -68,7 +67,7 @@
self._last_indent,
self.s_active_context().pc(),
next, bytecodeimpl.__name__,)
- bytecodeimpl(self.w_active_context, self)
+ bytecodeimpl(self.s_active_context(), self)
else:
# this is a performance optimization: when translating the
# interpreter, the bytecode dispatching is not implemented as a
@@ -76,7 +75,7 @@
# below produces the switch (by being unrolled).
for code, bytecodeimpl in unrolling_bytecode_table:
if code == next:
- bytecodeimpl(self.w_active_context, self)
+ bytecodeimpl(self.s_active_context(), self)
break
@@ -87,10 +86,10 @@
# ___________________________________________________________________________
# Bytecode Implementations:
#
-# "self" is always a W_ContextPart instance.
+# "self" is always a ContextPartShadow instance.
-# __extend__ adds new methods to the W_ContextPart class
-class __extend__(W_ContextPart):
+# __extend__ adds new methods to the ContextPartShadow class
+class __extend__(ContextPartShadow):
# push bytecodes
def pushReceiverVariableBytecode(self, interp):
index = self.currentBytecode & 15
@@ -203,7 +202,7 @@
print "PRIMITIVE FAILED: %d %s" % (method.primitive, selector,)
pass # ignore this error and fall back to the Smalltalk version
arguments = self.pop_and_return_n(argcount)
- interp.w_active_context = method.create_frame(receiver, arguments, self)
+ interp.w_active_context = method.create_frame(receiver, arguments, self.w_self())
self.pop()
def _return(self, object, interp, w_return_to):
@@ -513,77 +512,77 @@
BYTECODE_RANGES = [
- ( 0, 15, W_ContextPart.pushReceiverVariableBytecode),
- ( 16, 31, W_ContextPart.pushTemporaryVariableBytecode),
- ( 32, 63, W_ContextPart.pushLiteralConstantBytecode),
- ( 64, 95, W_ContextPart.pushLiteralVariableBytecode),
- ( 96, 103, W_ContextPart.storeAndPopReceiverVariableBytecode),
- (104, 111, W_ContextPart.storeAndPopTemporaryVariableBytecode),
- (112, W_ContextPart.pushReceiverBytecode),
- (113, W_ContextPart.pushConstantTrueBytecode),
- (114, W_ContextPart.pushConstantFalseBytecode),
- (115, W_ContextPart.pushConstantNilBytecode),
- (116, W_ContextPart.pushConstantMinusOneBytecode),
- (117, W_ContextPart.pushConstantZeroBytecode),
- (118, W_ContextPart.pushConstantOneBytecode),
- (119, W_ContextPart.pushConstantTwoBytecode),
- (120, W_ContextPart.returnReceiver),
- (121, W_ContextPart.returnTrue),
- (122, W_ContextPart.returnFalse),
- (123, W_ContextPart.returnNil),
- (124, W_ContextPart.returnTopFromMethod),
- (125, W_ContextPart.returnTopFromBlock),
- (126, W_ContextPart.unknownBytecode),
- (127, W_ContextPart.unknownBytecode),
- (128, W_ContextPart.extendedPushBytecode),
- (129, W_ContextPart.extendedStoreBytecode),
- (130, W_ContextPart.extendedStoreAndPopBytecode),
- (131, W_ContextPart.singleExtendedSendBytecode),
- (132, W_ContextPart.doubleExtendedDoAnythingBytecode),
- (133, W_ContextPart.singleExtendedSuperBytecode),
- (134, W_ContextPart.secondExtendedSendBytecode),
- (135, W_ContextPart.popStackBytecode),
- (136, W_ContextPart.duplicateTopBytecode),
- (137, W_ContextPart.pushActiveContextBytecode),
- (138, 143, W_ContextPart.experimentalBytecode),
- (144, 151, W_ContextPart.shortUnconditionalJump),
- (152, 159, W_ContextPart.shortConditionalJump),
- (160, 167, W_ContextPart.longUnconditionalJump),
- (168, 171, W_ContextPart.longJumpIfTrue),
- (172, 175, W_ContextPart.longJumpIfFalse),
- (176, W_ContextPart.bytecodePrimAdd),
- (177, W_ContextPart.bytecodePrimSubtract),
- (178, W_ContextPart.bytecodePrimLessThan),
- (179, W_ContextPart.bytecodePrimGreaterThan),
- (180, W_ContextPart.bytecodePrimLessOrEqual),
- (181, W_ContextPart.bytecodePrimGreaterOrEqual),
- (182, W_ContextPart.bytecodePrimEqual),
- (183, W_ContextPart.bytecodePrimNotEqual),
- (184, W_ContextPart.bytecodePrimMultiply),
- (185, W_ContextPart.bytecodePrimDivide),
- (186, W_ContextPart.bytecodePrimMod),
- (187, W_ContextPart.bytecodePrimMakePoint),
- (188, W_ContextPart.bytecodePrimBitShift),
- (189, W_ContextPart.bytecodePrimDiv),
- (190, W_ContextPart.bytecodePrimBitAnd),
- (191, W_ContextPart.bytecodePrimBitOr),
- (192, W_ContextPart.bytecodePrimAt),
- (193, W_ContextPart.bytecodePrimAtPut),
- (194, W_ContextPart.bytecodePrimSize),
- (195, W_ContextPart.bytecodePrimNext),
- (196, W_ContextPart.bytecodePrimNextPut),
- (197, W_ContextPart.bytecodePrimAtEnd),
- (198, W_ContextPart.bytecodePrimEquivalent),
- (199, W_ContextPart.bytecodePrimClass),
- (200, W_ContextPart.bytecodePrimBlockCopy),
- (201, W_ContextPart.bytecodePrimValue),
- (202, W_ContextPart.bytecodePrimValueWithArg),
- (203, W_ContextPart.bytecodePrimDo),
- (204, W_ContextPart.bytecodePrimNew),
- (205, W_ContextPart.bytecodePrimNewWithArg),
- (206, W_ContextPart.bytecodePrimPointX),
- (207, W_ContextPart.bytecodePrimPointY),
- (208, 255, W_ContextPart.sendLiteralSelectorBytecode),
+ ( 0, 15, ContextPartShadow.pushReceiverVariableBytecode),
+ ( 16, 31, ContextPartShadow.pushTemporaryVariableBytecode),
+ ( 32, 63, ContextPartShadow.pushLiteralConstantBytecode),
+ ( 64, 95, ContextPartShadow.pushLiteralVariableBytecode),
+ ( 96, 103, ContextPartShadow.storeAndPopReceiverVariableBytecode),
+ (104, 111, ContextPartShadow.storeAndPopTemporaryVariableBytecode),
+ (112, ContextPartShadow.pushReceiverBytecode),
+ (113, ContextPartShadow.pushConstantTrueBytecode),
+ (114, ContextPartShadow.pushConstantFalseBytecode),
+ (115, ContextPartShadow.pushConstantNilBytecode),
+ (116, ContextPartShadow.pushConstantMinusOneBytecode),
+ (117, ContextPartShadow.pushConstantZeroBytecode),
+ (118, ContextPartShadow.pushConstantOneBytecode),
+ (119, ContextPartShadow.pushConstantTwoBytecode),
+ (120, ContextPartShadow.returnReceiver),
+ (121, ContextPartShadow.returnTrue),
+ (122, ContextPartShadow.returnFalse),
+ (123, ContextPartShadow.returnNil),
+ (124, ContextPartShadow.returnTopFromMethod),
+ (125, ContextPartShadow.returnTopFromBlock),
+ (126, ContextPartShadow.unknownBytecode),
+ (127, ContextPartShadow.unknownBytecode),
+ (128, ContextPartShadow.extendedPushBytecode),
+ (129, ContextPartShadow.extendedStoreBytecode),
+ (130, ContextPartShadow.extendedStoreAndPopBytecode),
+ (131, ContextPartShadow.singleExtendedSendBytecode),
+ (132, ContextPartShadow.doubleExtendedDoAnythingBytecode),
+ (133, ContextPartShadow.singleExtendedSuperBytecode),
+ (134, ContextPartShadow.secondExtendedSendBytecode),
+ (135, ContextPartShadow.popStackBytecode),
+ (136, ContextPartShadow.duplicateTopBytecode),
+ (137, ContextPartShadow.pushActiveContextBytecode),
+ (138, 143, ContextPartShadow.experimentalBytecode),
+ (144, 151, ContextPartShadow.shortUnconditionalJump),
+ (152, 159, ContextPartShadow.shortConditionalJump),
+ (160, 167, ContextPartShadow.longUnconditionalJump),
+ (168, 171, ContextPartShadow.longJumpIfTrue),
+ (172, 175, ContextPartShadow.longJumpIfFalse),
+ (176, ContextPartShadow.bytecodePrimAdd),
+ (177, ContextPartShadow.bytecodePrimSubtract),
+ (178, ContextPartShadow.bytecodePrimLessThan),
+ (179, ContextPartShadow.bytecodePrimGreaterThan),
+ (180, ContextPartShadow.bytecodePrimLessOrEqual),
+ (181, ContextPartShadow.bytecodePrimGreaterOrEqual),
+ (182, ContextPartShadow.bytecodePrimEqual),
+ (183, ContextPartShadow.bytecodePrimNotEqual),
+ (184, ContextPartShadow.bytecodePrimMultiply),
+ (185, ContextPartShadow.bytecodePrimDivide),
+ (186, ContextPartShadow.bytecodePrimMod),
+ (187, ContextPartShadow.bytecodePrimMakePoint),
+ (188, ContextPartShadow.bytecodePrimBitShift),
+ (189, ContextPartShadow.bytecodePrimDiv),
+ (190, ContextPartShadow.bytecodePrimBitAnd),
+ (191, ContextPartShadow.bytecodePrimBitOr),
+ (192, ContextPartShadow.bytecodePrimAt),
+ (193, ContextPartShadow.bytecodePrimAtPut),
+ (194, ContextPartShadow.bytecodePrimSize),
+ (195, ContextPartShadow.bytecodePrimNext),
+ (196, ContextPartShadow.bytecodePrimNextPut),
+ (197, ContextPartShadow.bytecodePrimAtEnd),
+ (198, ContextPartShadow.bytecodePrimEquivalent),
+ (199, ContextPartShadow.bytecodePrimClass),
+ (200, ContextPartShadow.bytecodePrimBlockCopy),
+ (201, ContextPartShadow.bytecodePrimValue),
+ (202, ContextPartShadow.bytecodePrimValueWithArg),
+ (203, ContextPartShadow.bytecodePrimDo),
+ (204, ContextPartShadow.bytecodePrimNew),
+ (205, ContextPartShadow.bytecodePrimNewWithArg),
+ (206, ContextPartShadow.bytecodePrimPointX),
+ (207, ContextPartShadow.bytecodePrimPointY),
+ (208, 255, ContextPartShadow.sendLiteralSelectorBytecode),
]
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py Mon Feb 25 23:32:10 2008
@@ -125,7 +125,7 @@
return self.w_class
def __repr__(self):
- return "<%s %s at %r>" % (self.__class__.__name__, self, self.gethash())
+ return "<%s %s>" % (self.__class__.__name__, self)
def __str__(self):
if isinstance(self, W_PointersObject) and self._shadow is not None:
@@ -380,7 +380,6 @@
from pypy.lang.smalltalk import objtable
assert len(arguments) == self.argsize
w_new = W_MethodContext(self, receiver, arguments, sender)
- objtable.objects += [w_new]
return w_new
def __str__(self):
@@ -432,6 +431,7 @@
self.tempsize = tempsize
self.primitive = primitive
self.w_compiledin = None
+ self.islarge = islarge
def literalat0(self, index0):
if index0 == 0:
@@ -486,313 +486,33 @@
self.bytes = (self.bytes[:index0] + character +
self.bytes[index0 + 1:])
-class W_ContextPart(W_AbstractObjectWithIdentityHash):
-
- __metaclass__ = extendabletype
-
- def __init__(self, w_home, w_sender):
- self._stack = []
- self._pc = 0
- #assert isinstance(s_home, W_MethodContext)
- self._w_home = w_home
- #assert w_sender is None or isinstance(w_sender, W_ContextPart)
- self._w_sender = w_sender
-
- def as_context_get_shadow(self):
- # Backward compatibility
- return self
-
- def w_self(self):
- # Backward compatibility
- return self
-
- def pc(self):
- return self._pc
-
- def stack(self):
- return self._stack
-
- def store_pc(self, pc):
- self._pc = pc
-
- def w_receiver(self):
- " Return self of the method, or the method that contains the block "
- return self.s_home().w_receiver()
-
- def w_home(self):
- return self._w_home
-
- def s_home(self):
- return self.w_home().as_methodcontext_get_shadow()
-
- def store_w_home(self, w_home):
- self._w_home = w_home
-
- def w_sender(self):
- if self._w_sender is not None:
- return self._w_sender
- else:
- from pypy.lang.smalltalk import objtable
- return objtable.w_nil
-
- def store_w_sender(self, w_sender):
- self._w_sender = w_sender
-
- def stackpointer(self):
- return len(self.stack()) + self.stackstart() - 1
- # ______________________________________________________________________
- # Imitate the primitive accessors
-
- def fetch(self, index):
- from pypy.lang.smalltalk import utility, objtable
- if index == constants.CTXPART_SENDER_INDEX:
- return self.w_sender()
- elif index == constants.CTXPART_PC_INDEX:
- return utility.wrap_int(self.pc())
- elif index == constants.CTXPART_STACKP_INDEX:
- return utility.wrap_int(self.stackpointer())
-
- # Invalid!
- raise IndexError
-
- def store(self, index, w_value):
- # XXX Untested code...
- from pypy.lang.smalltalk import utility, objtable
- if index == constants.CTXPART_SENDER_INDEX:
- if w_value != objtable.w_nil:
- self.store_w_sender(w_value)
- elif index == constants.CTXPART_PC_INDEX:
- self._pc = utility.unwrap_int(w_value)
- elif index == constants.CTXPART_STACKP_INDEX:
- size = utility.unwrap_int(w_value)
- size = 1 + size - self.stackstart()
- self._stack = [objtable.w_nil] * size
- else:
- # Invalid!
- raise IndexError
-
- def become(self, w_old, w_new):
- if self.w_sender() == w_old:
- self.store_w_sender(w_new)
- for i in range(len(self._stack)):
- if self._stack[i] == w_old:
- self._stack[i] = w_new
- if self.w_home() == w_old:
- self.store_w_home(w_new)
-
- def stackstart(self):
- return constants.MTHDCTX_TEMP_FRAME_START
-
- # ______________________________________________________________________
- # Method that contains the bytecode for this method/block context
-
- def w_method(self):
- return self.s_home().w_method()
-
- def getbytecode(self):
- pc = self.pc()
- bytecode = self.w_method().bytes[pc]
- currentBytecode = ord(bytecode)
- self.store_pc(pc + 1)
- return currentBytecode
-
- def getNextBytecode(self):
- self.currentBytecode = self.getbytecode()
- return self.currentBytecode
-
- # ______________________________________________________________________
- # Temporary Variables
- #
- # Are always fetched relative to the home method context.
-
- def gettemp(self, index):
- return self.s_home().gettemp(index)
-
- def settemp(self, index, w_value):
- self.s_home().settemp(index, w_value)
-
- # ______________________________________________________________________
- # Stack Manipulation
-
- def pop(self):
- return self.stack().pop()
-
- def push(self, w_v):
- assert w_v
- self.stack().append(w_v)
-
- def push_all(self, lst):
- " Equivalent to 'for x in lst: self.push(x)' where x is a lst "
- assert None not in lst
- self._stack += lst
-
- def top(self):
- return self.peek(0)
-
- def peek(self, idx):
- return self.stack()[-(idx+1)]
-
- def pop_n(self, n):
- assert n >= 0
- start = len(self.stack()) - n
- assert start >= 0 # XXX what if this fails?
- del self.stack()[start:]
-
- def pop_and_return_n(self, n):
- assert n >= 0
- start = len(self.stack()) - n
- assert start >= 0 # XXX what if this fails?
- res = self.stack()[start:]
- del self.stack()[start:]
- return res
-
-class W_BlockContext(W_ContextPart):
-
- def __init__(self, w_home, w_sender, argcnt, initialip):
- W_ContextPart.__init__(self, w_home, w_sender)
- self.argcnt = argcnt
- self._initialip = initialip
-
- def initialip(self):
- return self._initialip
-
- def expected_argument_count(self):
- return self.argcnt
-
- def getclass(self):
- from pypy.lang.smalltalk.classtable import w_BlockContext
- return w_BlockContext
-
- def as_blockcontext_get_shadow(self):
- # Backwards compatibility
- return self
-
- def fetch(self, index):
- from pypy.lang.smalltalk import utility
- if index == constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX:
- return utility.wrap_int(self.argcnt)
- elif index == constants.BLKCTX_INITIAL_IP_INDEX:
- return utility.wrap_int(self.initialip)
- elif index == constants.BLKCTX_HOME_INDEX:
- return self.w_home()
- elif index >= constants.BLKCTX_TEMP_FRAME_START:
- stack_index = len(self.stack()) - index - 1
- return self.stack()[stack_index]
- else:
- return W_ContextPart.fetch(self, index)
-
- def store(self, index, value):
- # THIS IS ALL UNTESTED CODE and we're a bit unhappy about it
- # because it crashd the translation N+4 times :-(
- from pypy.lang.smalltalk import utility
- if index == constants.BLKCTX_BLOCK_ARGUMENT_COUNT_INDEX:
- self.argcnt = utility.unwrap_int(value)
- elif index == constants.BLKCTX_INITIAL_IP_INDEX:
- self.pc = utility.unwrap_int(value)
- elif index == constants.BLKCTX_HOME_INDEX:
- self.store_w_home(value)
- elif index >= constants.BLKCTX_TEMP_FRAME_START:
- stack_index = len(self.stack()) - index - 1
- self.stack()[stack_index] = value
- else:
- W_ContextPart.store(self, index, value)
-
- def stackstart(self):
- return constants.BLKCTX_TEMP_FRAME_START
-
-class W_MethodContext(W_ContextPart):
- def __init__(self, w_method, w_receiver,
- arguments, w_sender=None):
- W_ContextPart.__init__(self, self, w_sender)
- self._w_method = w_method
- self._w_receiver = w_receiver
- self.temps = arguments + [w_nil] * w_method.tempsize
-
- def as_methodcontext_get_shadow(self):
- # Backwards compatibility
- return self
-
- def getclass(self):
- from pypy.lang.smalltalk.classtable import w_MethodContext
- return w_MethodContext
-
- def w_receiver(self):
- return self._w_receiver
-
- def store_w_receiver(self, w_receiver):
- self._w_receiver = w_receiver
-
- def become(self, w_old, w_new):
- W_ContextPart.become(self, w_old, w_new)
- for i in range(len(self.temps)):
- if self.temps[i] == w_old:
- self.temps[i] = w_new
- if w_old == self._w_receiver:
- self._w_receiver = w_new
- if w_old == self._w_method:
- self._w_method = w_new
-
- def at0(self, index0):
- # XXX to test
- # Fetches in temppart (variable size)
- return self.fetch(index0+constants.MTHDCTX_TEMP_FRAME_START)
-
- def atput0(self, index0, w_v):
- # XXX to test
- # Stores in temppart (variable size)
- return self.store(index0+constants.MTHDCTX_TEMP_FRAME_START, w_v)
-
- def fetch(self, index):
- if index == constants.MTHDCTX_METHOD:
- return self.w_method()
- elif index == constants.MTHDCTX_RECEIVER_MAP: # what is this thing?
- return w_nil
- elif index == constants.MTHDCTX_RECEIVER:
- return self.w_receiver()
- elif index >= constants.MTHDCTX_TEMP_FRAME_START:
- # First set of indices are temporary variables:
- offset = index - constants.MTHDCTX_TEMP_FRAME_START
- if offset < len(self.temps):
- return self.temps[offset]
-
- # After that comes the stack:
- offset -= len(self.temps)
- stack_index = len(self.stack()) - offset - 1
- return self.stack()[stack_index]
- else:
- return W_ContextPart.fetch(self, index)
-
- def store(self, index, w_object):
- if index == constants.MTHDCTX_METHOD:
- self._w_method = w_object
- elif index == constants.MTHDCTX_RECEIVER_MAP: # what is this thing?
- pass
- elif index == constants.MTHDCTX_RECEIVER:
- self.store_w_receiver(w_object)
- elif index >= constants.MTHDCTX_TEMP_FRAME_START:
- # First set of indices are temporary variables:
- offset = index - constants.MTHDCTX_TEMP_FRAME_START
- if offset < len(self.temps):
- self.temps[offset] = w_object
-
- # After that comes the stack:
- offset -= len(self.temps)
- stack_index = len(self.stack()) - offset - 1
- self.stack()[stack_index] = w_object
- else:
- W_ContextPart.store(self, index, w_object)
-
- def gettemp(self, idx):
- return self.temps[idx]
-
- def settemp(self, idx, w_value):
- self.temps[idx] = w_value
-
- def w_method(self):
- return self._w_method
-
- def size(self):
- return len(self.temps) + len(self.stack())
+def W_BlockContext(w_home, w_sender, argcnt, initialip):
+ from pypy.lang.smalltalk.classtable import w_BlockContext
+ w_result = W_PointersObject(w_BlockContext, w_home.size())
+ s_result = w_result.as_blockcontext_get_shadow()
+ s_result.store_expected_argument_count(argcnt)
+ s_result.store_initialip(initialip)
+ s_result.store_w_home(w_home)
+ s_result.store_stackpointer(s_result.stackstart())
+ return w_result
+
+def W_MethodContext(w_method, w_receiver,
+ arguments, w_sender=None):
+ from pypy.lang.smalltalk.classtable import w_MethodContext
+ # From blue book: normal mc have place for 12 temps+maxstack
+ # mc for methods with islarge flag turned on 32
+ size = 12 + w_method.islarge * 20 + w_method.argsize
+ w_result = w_MethodContext.as_class_get_shadow().new(size)
+ s_result = w_result.as_methodcontext_get_shadow()
+ s_result.store_w_method(w_method)
+ if w_sender:
+ s_result.store_w_sender(w_sender)
+ s_result.store_w_receiver(w_receiver)
+ s_result.store_pc(w_method.getliteralsize()+1)
+ for i in range(len(arguments)):
+ s_result.settemp(i, arguments[i])
+ s_result.store_stackpointer(s_result.stackstart())
+ return w_result
# Use black magic to create w_nil without running the constructor,
# thus allowing it to be used even in the constructor of its own
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py Mon Feb 25 23:32:10 2008
@@ -68,7 +68,7 @@
w_result = func(interp, argument_count_m1)
if not no_result:
assert w_result is not None
- interp.w_active_context.as_context_get_shadow().push(w_result)
+ interp.s_active_context().push(w_result)
return w_result
else:
len_unwrap_spec = len(unwrap_spec)
@@ -104,7 +104,7 @@
w_result = func(interp, *args)
# After calling primitive, reload context-shadow in case it
# needs to be updated
- new_s_frame = interp.w_active_context.as_context_get_shadow()
+ new_s_frame = interp.s_active_context()
frame.as_context_get_shadow().pop_n(len_unwrap_spec) # only if no exception occurs!
if not no_result:
assert w_result is not None
@@ -397,7 +397,6 @@
"Stores a value into a fixed field from the object, and fails otherwise"
s_class = w_rcvr.shadow_of_my_class()
assert_bounds(n0, 0, s_class.instsize())
- # only pointers have non-0 size
# XXX Now MethodContext is still own format, leave
#assert isinstance(w_rcvr, model.W_PointersObject)
w_rcvr.store(n0, w_value)
@@ -622,21 +621,19 @@
@expose_primitive(PRIMITIVE_BLOCK_COPY, unwrap_spec=[object, int])
def func(interp, w_context, argcnt):
- frame = interp.w_active_context.as_context_get_shadow()
+ frame = interp.s_active_context()
# From B.B.: If receiver is a MethodContext, then it becomes
# the new BlockContext's home context. Otherwise, the home
# context of the receiver is used for the new BlockContext.
# Note that in our impl, MethodContext.w_home == self
- if not isinstance(w_context, model.W_ContextPart):
- raise PrimitiveFailedError()
w_method_context = w_context.as_context_get_shadow().w_home()
# The block bytecodes are stored inline: so we skip past the
# byteodes to invoke this primitive to find them (hence +2)
initialip = frame.pc() + 2
w_new_context = model.W_BlockContext(
- w_method_context, None, argcnt, initialip)
+ w_method_context, objtable.w_nil, argcnt, initialip)
return w_new_context
def finalize_block_ctx(interp, s_block_ctx, frame):
@@ -653,14 +650,16 @@
# Rcvr | Arg 0 | Arg1 | Arg 2
#
- frame = interp.w_active_context.as_context_get_shadow()
+ frame = interp.s_active_context()
# Validate that we have a block on the stack and that it received
# the proper number of arguments:
w_block_ctx = frame.peek(argument_count)
if w_block_ctx.getclass() != classtable.w_BlockContext:
raise PrimitiveFailedError()
+
s_block_ctx = w_block_ctx.as_blockcontext_get_shadow()
+
exp_arg_cnt = s_block_ctx.expected_argument_count()
if argument_count != exp_arg_cnt: # exp_arg_cnt doesn't count self
raise PrimitiveFailedError()
@@ -668,6 +667,9 @@
# Initialize the block stack with the arguments that were
# pushed. Also pop the receiver.
block_args = frame.pop_and_return_n(exp_arg_cnt)
+
+ # Reset stack of blockcontext to []
+ s_block_ctx.store_stackpointer(s_block_ctx.stackstart())
s_block_ctx.push_all(block_args)
frame.pop()
@@ -710,7 +712,6 @@
w_frame.as_context_get_shadow().store_w_sender(interp.w_active_context)
interp.w_active_context = w_frame
-
@expose_primitive(PRIMITIVE_SIGNAL, unwrap_spec=[object])
def func(interp, w_rcvr):
if w_rcvr.getclass() != classtable.classtable['w_Semaphore']:
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py Mon Feb 25 23:32:10 2008
@@ -150,21 +150,6 @@
def new(self, extrasize=0, store=True):
from pypy.lang.smalltalk import classtable
w_cls = self.w_self()
-
- if w_cls == classtable.w_BlockContext:
- w_new = model.W_BlockContext(None, None, 0, 0)
- elif w_cls == classtable.w_MethodContext:
- # From slang: Contexts must only be created with newForMethod:
- # raise error.PrimitiveFailedError
- # XXX XXX XXX XXX
- # The above text is bogous. This does not come from slang but a
- # method implementation of ContextPart in Squeak3.9 which
- # overwrites the default compiledmethod to give this error.
- # The mini.image -however- doesn't overwrite this method, and as
- # far as I was able to trace it back, it -does- call this method.
- from pypy.rlib.objectmodel import instantiate
- w_new = instantiate(model.W_MethodContext)
-
if self.instance_kind == POINTERS:
w_new = model.W_PointersObject(w_cls, self.instance_size+extrasize)
elif self.instance_kind == WORDS:
@@ -391,43 +376,16 @@
def process_lists(self):
return self.w_self().fetch(constants.SCHEDULER_PROCESS_LISTS_INDEX)
-# XXX This should be changed once everything works using contextshadows
-# current hack to make the class extension-system for bytecode lookup happy...
-# Should be AbstractShadow
-# XXX XXX
-class ContextPartShadow(model.W_ContextPart):
+class ContextPartShadow(AbstractShadow):
- #__metaclass__ = extendabletype
+ __metaclass__ = extendabletype
def __init__(self, w_self):
- self._w_self = w_self
- self.invalidate()
+ AbstractShadow.__init__(self, w_self)
def s_home(self):
raise NotImplementedError()
- # XXX XXX Remove function when fixing superclass to AbstractShadow
- def w_self(self):
- return self._w_self
-
- # XXX XXX Remove function when fixing superclass to AbstractShadow
- def invalidate(self):
- self.invalid = True
-
- # XXX XXX Remove function when fixing superclass to AbstractShadow
- def check_for_updates(self):
- if self.invalid:
- self.w_self().setshadow(self)
- self.update_shadow()
-
- # XXX XXX Remove function when fixing superclass to AbstractShadow
- def update_shadow(self):
- pass
-
- # XXX XXX Remove function when fixing superclass to AbstractShadow
- def getname(self):
- return repr(self)
-
def w_receiver(self):
" Return self of the method, or the method that contains the block "
return self.s_home().w_receiver()
@@ -443,7 +401,7 @@
else:
return w_sender.as_context_get_shadow()
- def store_w_sender(self, s_sender):
+ def store_w_sender(self, w_sender):
self.w_self().store(constants.CTXPART_SENDER_INDEX, w_sender)
def pc(self):
@@ -516,7 +474,8 @@
self.store_stackpointer(self.stackpointer() - n)
def stack(self):
- return [self.w_self().fetch(i) for i in range(self.stackstart(), self.stackpointer() + 1)]
+ # fetch = 1-based
+ return [self.w_self().fetch(i) for i in range(self.stackstart() + 1, self.stackpointer() + 1)]
def pop_and_return_n(self, n):
self.pop_n(n)
@@ -538,6 +497,13 @@
def initialip(self):
return utility.unwrap_int(self.w_self().fetch(constants.BLKCTX_INITIAL_IP_INDEX))
+ def store_initialip(self, initialip):
+ self.w_self().store(constants.BLKCTX_INITIAL_IP_INDEX,
+ utility.wrap_int(initialip))
+
+ def store_w_home(self, w_home):
+ self.w_self().store(constants.BLKCTX_HOME_INDEX, w_home)
+
def w_home(self):
return self.w_self().fetch(constants.BLKCTX_HOME_INDEX)
@@ -545,7 +511,8 @@
return self.w_home().as_methodcontext_get_shadow()
def stackstart(self):
- return constants.BLKCTX_TEMP_FRAME_START
+ return (constants.BLKCTX_TEMP_FRAME_START +
+ self.expected_argument_count())
class MethodContextShadow(ContextPartShadow):
def __init__(self, w_self):
@@ -554,6 +521,9 @@
def w_method(self):
return self.w_self().fetch(constants.MTHDCTX_METHOD)
+ def store_w_method(self, w_method):
+ return self.w_self().store(constants.MTHDCTX_METHOD, w_method)
+
def w_receiver(self):
return self.w_self().fetch(constants.MTHDCTX_RECEIVER)
@@ -573,4 +543,6 @@
return self
def stackstart(self):
- return constants.MTHDCTX_TEMP_FRAME_START
+ return (constants.MTHDCTX_TEMP_FRAME_START +
+ self.w_method().argsize +
+ self.w_method().tempsize)
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_interpreter.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_interpreter.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_interpreter.py Mon Feb 25 23:32:10 2008
@@ -69,9 +69,10 @@
def new_interpreter(bytes, receiver=objtable.w_nil):
assert isinstance(bytes, str)
w_method = model.W_CompiledMethod(len(bytes))
+ w_method.islarge = 1
w_method.bytes = bytes
w_method.argsize=2
- w_method.tempsize=1
+ w_method.tempsize=8
w_frame = w_method.create_frame(receiver, ["foo", "bar"])
interp = interpreter.Interpreter()
interp.w_active_context = w_frame
@@ -80,18 +81,20 @@
def test_create_frame():
w_method = model.W_CompiledMethod(len("hello"))
w_method.bytes="hello"
+ w_method.islarge = 1
w_method.argsize=2
- w_method.tempsize=1
+ w_method.tempsize=8
w_frame = w_method.create_frame("receiver", ["foo", "bar"])
- assert w_frame.w_receiver() == "receiver"
- assert w_frame.gettemp(0) == "foo"
- assert w_frame.gettemp(1) == "bar"
- assert w_frame.gettemp(2) is objtable.w_nil
- w_frame.settemp(2, "spam")
- assert w_frame.gettemp(2) == "spam"
- assert w_frame.getNextBytecode() == ord("h")
- assert w_frame.getNextBytecode() == ord("e")
- assert w_frame.getNextBytecode() == ord("l")
+ s_frame = w_frame.as_context_get_shadow()
+ assert s_frame.w_receiver() == "receiver"
+ assert s_frame.gettemp(0) == "foo"
+ assert s_frame.gettemp(1) == "bar"
+ assert s_frame.gettemp(2) is objtable.w_nil
+ s_frame.settemp(2, "spam")
+ assert s_frame.gettemp(2) == "spam"
+ assert s_frame.getNextBytecode() == ord("h")
+ assert s_frame.getNextBytecode() == ord("e")
+ assert s_frame.getNextBytecode() == ord("l")
def test_push_pop():
interp = new_interpreter("")
@@ -185,15 +188,17 @@
def test_storeAndPopTemporaryVariableBytecode(bytecode=storeAndPopTemporaryVariableBytecode):
for index in range(8):
interp = new_interpreter(pushConstantTrueBytecode + bytecode(index))
- interp.w_active_context.as_methodcontext_get_shadow().temps = [None] * 8
+ #interp.w_active_context.as_methodcontext_get_shadow().temps = [None] * 8
interp.step()
interp.step()
assert interp.s_active_context().stack() == []
+ interp.w_active_context.as_methodcontext_get_shadow()
for test_index in range(8):
+ print interp.w_active_context._vars
if test_index == index:
- assert interp.w_active_context.as_methodcontext_get_shadow().temps[test_index] == interp.TRUE
+ assert interp.s_active_context().gettemp(test_index) == interp.TRUE
else:
- assert interp.w_active_context.as_methodcontext_get_shadow().temps[test_index] == None
+ assert interp.s_active_context().gettemp(test_index) != interp.TRUE
def test_pushConstantTrueBytecode():
interp = new_interpreter(pushConstantTrueBytecode)
@@ -398,7 +403,7 @@
assert interp.s_active_context().stack() == []
assert interp.w_active_context.as_methodcontext_get_shadow().w_receiver() == w_object
assert interp.w_active_context.as_methodcontext_get_shadow().w_method() == shadow.methoddict["foo"]
- assert callerContext.stack() == []
+ assert callerContext.as_context_get_shadow().stack() == []
interp.step()
interp.step()
assert interp.w_active_context == callerContext
@@ -448,7 +453,7 @@
def test_longJumpIfTrue():
interp = new_interpreter(longJumpIfTrue(0) + chr(15) + longJumpIfTrue(0) + chr(15))
interp.s_active_context().push(interp.FALSE)
- pc = interp.w_active_context.pc() + 2
+ pc = interp.s_active_context().pc() + 2
interp.step()
assert interp.s_active_context().pc() == pc
interp.s_active_context().push(interp.TRUE)
@@ -605,7 +610,7 @@
assert interp.w_active_context.as_methodcontext_get_shadow().w_receiver() == w_object
meth = w_specificclass.as_class_get_shadow().methoddict["foo"]
assert interp.w_active_context.as_methodcontext_get_shadow().w_method() == meth
- assert callerContext.stack() == []
+ assert callerContext.as_context_get_shadow().stack() == []
def test_secondExtendedSendBytecode():
w_class = mockclass(0)
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py Mon Feb 25 23:32:10 2008
@@ -204,12 +204,9 @@
w_frame = w_method.create_frame(w_object, [])
interp.w_active_context = w_frame
- print w_method
-
while True:
try:
interp.step()
- print interp.s_active_context().stack()
except interpreter.ReturnFromTopLevel, e:
assert e.object.value == abs(int)
return
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_primitives.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_primitives.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_primitives.py Mon Feb 25 23:32:10 2008
@@ -9,9 +9,12 @@
mockclass = classtable.bootstrap_class
-class MockFrame(model.W_MethodContext):
+class MockFrame(model.W_PointersObject):
def __init__(self, stack):
- self._stack = stack
+ self._vars = [None] * 6 + stack
+ s_self = self.as_blockcontext_get_shadow()
+ s_self.store_expected_argument_count(0)
+ s_self.store_stackpointer(s_self.stackstart()+len(stack)-1)
def wrap(x):
if isinstance(x, int): return utility.wrap_int(x)
Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_shadow.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_shadow.py (original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_shadow.py Mon Feb 25 23:32:10 2008
@@ -88,7 +88,7 @@
def methodcontext(w_sender=objtable.w_nil, pc=1, stackpointer=0, stacksize=5,
method=method()):
- stackstart = 7 # (len notation, not idx notation)
+ stackstart = 6+method.argsize+method.tempsize # (len notation, not idx notation)
w_object = model.W_PointersObject(classtable.w_MethodContext, stackstart+stacksize)
w_object.store(constants.CTXPART_SENDER_INDEX, w_sender)
w_object.store(constants.CTXPART_PC_INDEX, utility.wrap_int(pc))
@@ -98,20 +98,12 @@
w_object.store(constants.MTHDCTX_RECEIVER_MAP, '???')
w_object.store(constants.MTHDCTX_RECEIVER, 'receiver')
- # XXX Might want to check the realness of the next assumption,
- # XXX made by hooking into the suspended thread of the image.
- # XXX it seems the only possibility, and using this assumption
- # XXX it actually runs...
- # Weirdly enough, undependant from the size of the tempsize and
- # argsize, the stackpointer can point to anything starting from
- # the temp_frame_start. That's why stacks always print all elements
- # including possible "temps or args"
w_object.store(constants.MTHDCTX_TEMP_FRAME_START, 'el')
return w_object
def test_context():
w_m = method()
- w_object = methodcontext(stackpointer=2, method=w_m)
+ w_object = methodcontext(stackpointer=3, method=w_m)
w_object2 = methodcontext(w_sender=w_object)
s_object = w_object.as_methodcontext_get_shadow()
s_object2 = w_object2.as_methodcontext_get_shadow()
@@ -131,7 +123,7 @@
w_object.store(idx + 2, 'g')
w_object.store(idx + 3, 'h')
assert s_object.top() == 'h'
- assert s_object.stack() == ['el', 'f', 'g', 'h' ]
+ assert s_object.stack() == ['f', 'g', 'h' ]
s_object.push('i')
assert s_object.top() == 'i'
assert s_object.peek(1) == 'h'
More information about the Pypy-commit
mailing list