[pypy-svn] r47982 - in pypy/dist/pypy/lang/smalltalk: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Oct 25 20:39:10 CEST 2007
Author: arigo
Date: Thu Oct 25 20:39:10 2007
New Revision: 47982
Modified:
pypy/dist/pypy/lang/smalltalk/interpreter.py
pypy/dist/pypy/lang/smalltalk/model.py
pypy/dist/pypy/lang/smalltalk/shadow.py
pypy/dist/pypy/lang/smalltalk/test/test_interpreter.py
pypy/dist/pypy/lang/smalltalk/test/test_miniimage.py
pypy/dist/pypy/lang/smalltalk/test/test_shadow.py
Log:
(arigo, toon around)
Following some discussion, revert r47962 and go for methoddicts that
contains RPython strings as keys. This makes it easier to look up
random strings - the interpreter has no way to find the symbol
corresponding to a string in general.
This introduces a performance issue that we think we'll fix with
a ShadowString.
Modified: pypy/dist/pypy/lang/smalltalk/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/interpreter.py (original)
+++ pypy/dist/pypy/lang/smalltalk/interpreter.py Thu Oct 25 20:39:10 2007
@@ -111,7 +111,7 @@
# send, return bytecodes
def sendLiteralSelectorBytecode(self, interp):
- selector = self.w_method().getliteral(self.currentBytecode & 15)
+ selector = self.w_method().getliteralsymbol(self.currentBytecode & 15)
argcount = ((self.currentBytecode >> 4) & 3) - 1
self._sendSelfSelector(selector, argcount, interp)
@@ -204,7 +204,8 @@
def getExtendedSelectorArgcount(self):
descriptor = self.getByte()
- return (self.w_method().getliteral(descriptor & 31)), (descriptor >> 5)
+ return ((self.w_method().getliteralsymbol(descriptor & 31)),
+ (descriptor >> 5))
def singleExtendedSendBytecode(self, interp):
selector, argcount = self.getExtendedSelectorArgcount()
@@ -216,11 +217,11 @@
opType = second >> 5
if opType == 0:
# selfsend
- self._sendSelfSelector(self.w_method().getliteral(third),
+ self._sendSelfSelector(self.w_method().getliteralsymbol(third),
second & 31, interp)
elif opType == 1:
# supersend
- self._sendSuperSelector(self.w_method().getliteral(third),
+ self._sendSuperSelector(self.w_method().getliteralsymbol(third),
second & 31, interp)
elif opType == 2:
# pushReceiver
@@ -246,7 +247,7 @@
def secondExtendedSendBytecode(self, interp):
descriptor = self.getByte()
- selector = self.w_method().getliteral(descriptor & 63)
+ selector = self.w_method().getliteralsymbol(descriptor & 63)
argcount = descriptor >> 6
self._sendSelfSelector(selector, argcount, interp)
Modified: pypy/dist/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/model.py (original)
+++ pypy/dist/pypy/lang/smalltalk/model.py Thu Oct 25 20:39:10 2007
@@ -221,6 +221,11 @@
def getliteral(self, index):
return self.literals[index + 1] # header of compiledmethod at index 0
+ def getliteralsymbol(self, index):
+ w_literal = self.getliteral(index)
+ assert isinstance(w_literal, W_BytesObject)
+ return w_literal.as_string() # XXX performance issue here
+
def create_frame(self, receiver, arguments, sender = None):
assert len(arguments) == self.argsize
return W_MethodContext(self, receiver, arguments, sender)
Modified: pypy/dist/pypy/lang/smalltalk/shadow.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/shadow.py (original)
+++ pypy/dist/pypy/lang/smalltalk/shadow.py Thu Oct 25 20:39:10 2007
@@ -94,8 +94,11 @@
for i in range(size):
w_selector = w_methoddict.fetch(constants.METHODDICT_NAMES_INDEX+i)
if w_selector is not objtable.w_nil:
+ if not isinstance(w_selector, model.W_BytesObject):
+ raise ClassShadowError("bogus selector in method dict")
+ selector = w_selector.as_string()
w_compiledmethod = w_values.fetch(i)
- self.methoddict[w_selector] = w_compiledmethod
+ self.methoddict[selector] = w_compiledmethod
# for the rest, we need to reset invalid to False already so
# that cycles in the superclass and/or metaclass chains don't
# cause infinite recursion
@@ -169,12 +172,12 @@
return "<ClassShadow %s>" % (self.name or '?',)
def lookup(self, selector):
- if selector in self.methoddict:
- return self.methoddict[selector]
- elif self.s_superclass is not None:
- return self.s_superclass.lookup(selector)
- else:
- raise MethodNotFound
+ look_in_shadow = self
+ while selector not in look_in_shadow.methoddict:
+ look_in_shadow = look_in_shadow.s_superclass
+ if look_in_shadow is None:
+ raise MethodNotFound
+ return look_in_shadow.methoddict[selector]
def installmethod(self, selector, method):
"NOT_RPYTHON" # this is only for testing.
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 Oct 25 20:39:10 2007
@@ -26,8 +26,19 @@
setup()
+def fakesymbol(s, _cache={}):
+ try:
+ return _cache[s]
+ except KeyError:
+ result = _cache[s] = objtable.wrap_string(s)
+ return result
+
def fakeliterals(*literals):
- return ["methodheader"] + list(literals)
+ lst = ["methodheader"] + list(literals)
+ for i in range(len(lst)):
+ if isinstance(lst[i], str):
+ lst[i] = fakesymbol(lst[i])
+ return lst
def new_interpreter(bytes, receiver=objtable.w_nil):
assert isinstance(bytes, str)
@@ -108,7 +119,9 @@
interp.step()
interp.step()
interp.step()
- assert interp.w_active_context.stack == ["a", "b", "c"]
+ assert interp.w_active_context.stack == [fakesymbol("a"),
+ fakesymbol("b"),
+ fakesymbol("c")]
def test_pushLiteralVariableBytecode(bytecode=pushLiteralVariableBytecode(0)):
w_association = mockclass(2).as_class_get_shadow().new()
Modified: pypy/dist/pypy/lang/smalltalk/test/test_miniimage.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/test/test_miniimage.py (original)
+++ pypy/dist/pypy/lang/smalltalk/test/test_miniimage.py Thu Oct 25 20:39:10 2007
@@ -34,29 +34,6 @@
image = get_image()
return image.special(constants.SO_FLOAT_CLASS)
-# ------ custom lookup implementations --------------------------------
-
-def compiledmethodnamed(w_class, methodname):
- w_methoddict = w_class.fetch(constants.CLASS_METHODDICT_INDEX)._vars
- names = w_methoddict[constants.METHODDICT_NAMES_INDEX:]
- values = w_methoddict[constants.METHODDICT_VALUES_INDEX]._vars
- for var in names:
- if isinstance(var, model.W_BytesObject):
- if str(var) == str(methodname):
- return values[names.index(var)]
- raise shadow.MethodNotFound
-
-def lookup(w_class, methodname):
- in_class = w_class
- while in_class != None:
- try:
- return compiledmethodnamed(in_class, methodname)
- except shadow.MethodNotFound:
- pass
- in_class = in_class._vars[constants.CLASS_SUPERCLASS_INDEX]
- if in_class is objtable.w_nil:
- raise shadow.MethodNotFound
-
# ------ tests ------------------------------------------
def test_miniimageexists():
@@ -218,15 +195,8 @@
# Should get this from w_object
w_smallint_class = image.special(constants.SO_SMALLINTEGER_CLASS)
- w_method = lookup(w_smallint_class, "abs")
-
- # XXX
- # currently still using highlevel lookup directly pointing to
- # class. Should work using classmirrors when the metaclass of
- # SmallInt is correctly set
-
- # s_class = w_object.shadow_of_my_class()
- # w_method = s_class.lookup("abs")
+ s_class = w_object.shadow_of_my_class()
+ w_method = s_class.lookup("abs")
assert w_method
w_frame = w_method.create_frame(w_object, [])
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 Oct 25 20:39:10 2007
@@ -18,8 +18,9 @@
w_methoddict.store(constants.METHODDICT_VALUES_INDEX, w_array)
positions = range(size)
random.shuffle(positions)
- for w_selector, w_compiledmethod in methods.items():
+ for selector, w_compiledmethod in methods.items():
pos = positions.pop()
+ w_selector = objtable.wrap_string(selector)
w_methoddict.store(constants.METHODDICT_NAMES_INDEX+pos, w_selector)
w_array.store(pos, w_compiledmethod)
#print w_methoddict._vars
@@ -62,8 +63,8 @@
yield basicshape, "CompiledMeth", 0xE02, shadow.COMPILED_METHOD, True, 0
def test_methoddict():
- methods = {objtable.wrap_string('foo'): 'foo_method',
- objtable.wrap_string('bar'): 'bar_method'}
+ methods = {'foo': 'foo_method',
+ 'bar': 'bar_method'}
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