Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: Changeset: r84:235293a3b353 Date: 2013-02-21 15:44 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/235293a3b353/
Log: (cfbolz, lwassermann around): stop using unwrapped strings as values and just compare them by identity, which Squeak guarantees to be unique. this actually makes the behaviour more correct, because now doing nasty stuff like manually changing the symbol won't break method dicts. diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -62,7 +62,7 @@ SO_SMALLINTEGER_CLASS = 5 SO_STRING_CLASS = 6 SO_ARRAY_CLASS = 7 -SO_SMALLTALK = 8 # Deperacted +SO_SMALLTALK = 8 # Deprecated SO_FLOAT_CLASS = 9 SO_METHODCONTEXT_CLASS = 10 SO_BLOCKCONTEXT_CLASS = 11 @@ -128,9 +128,25 @@ "false": SO_FALSE, "charactertable": SO_CHARACTER_TABLE_ARRAY, "schedulerassociationpointer" : SO_SCHEDULERASSOCIATIONPOINTER, + "special_selectors": SO_SPECIAL_SELECTORS_ARRAY, "smalltalkdict" : SO_SMALLTALK, } LONG_BIT = 32 TAGGED_MAXINT = 2 ** (LONG_BIT - 2) - 1 TAGGED_MININT = -2 ** (LONG_BIT - 2) + + +# Entries into SO_SPECIAL_SELECTORS_ARRAY: +#(#+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0) + + +SPECIAL_SELECTORS = ['+', '-', '<', '>', '<=', '>=', '=', '~=', '*', '/', '\\\\', + '@', 'bitShift:', '//', 'bitAnd:', 'bitOr:', 'at:', + 'at:put:', 'size', 'next', 'nextPut:', 'atEnd', '==', + 'class', 'blockCopy:', 'value', 'value:', 'do:', 'new', + 'new:', 'x', 'y'] + +def find_selectorindex(selector): + return SPECIAL_SELECTORS.index(selector) * 2 +find_selectorindex._annspecialcase_ = "specialize:memo" diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -115,13 +115,14 @@ # else that the user put in a class in an 'at:' method. # The rule of thumb is that primitives with only int and float # in their unwrap_spec are safe. + # XXX move next line out of callPrimitive? func = primitives.prim_table[primitive] try: func(interp, argcount) return except primitives.PrimitiveFailedError: pass - self._sendSelfSelector(selector, argcount, interp) + self._sendSelfSelectorSpecial(selector, argcount, interp) return callPrimitive # ___________________________________________________________________________ @@ -194,31 +195,31 @@ # send, return bytecodes def sendLiteralSelectorBytecode(self, interp): - selector = self.method().getliteralsymbol(self.currentBytecode & 15) + w_selector = self.method().getliteral(self.currentBytecode & 15) argcount = ((self.currentBytecode >> 4) & 3) - 1 - self._sendSelfSelector(selector, argcount, interp) + self._sendSelfSelector(w_selector, argcount, interp) - def _sendSelfSelector(self, selector, argcount, interp): + def _sendSelfSelector(self, w_selector, argcount, interp): receiver = self.peek(argcount) - self._sendSelector(selector, argcount, interp, + self._sendSelector(w_selector, argcount, interp, receiver, receiver.shadow_of_my_class(self.space)) - def _sendSuperSelector(self, selector, argcount, interp): + def _sendSuperSelector(self, w_selector, argcount, interp): w_compiledin = self.method().w_compiledin assert isinstance(w_compiledin, model.W_PointersObject) s_compiledin = w_compiledin.as_class_get_shadow(self.space) - self._sendSelector(selector, argcount, interp, self.w_receiver(), + self._sendSelector(w_selector, argcount, interp, self.w_receiver(), s_compiledin.s_superclass()) - def _sendSelector(self, selector, argcount, interp, + def _sendSelector(self, w_selector, argcount, interp, receiver, receiverclassshadow): if interp.should_trace(): print "%sSending selector %r to %r with: %r" % ( - interp._last_indent, selector, receiver, + interp._last_indent, w_selector.as_string(), receiver, [self.peek(argcount-1-i) for i in range(argcount)]) pass assert argcount >= 0 - method = receiverclassshadow.lookup(selector) + method = receiverclassshadow.lookup(w_selector) # XXX catch MethodNotFound here and send doesNotUnderstand: # AK shouln't that be done in lookup itself, please check what spec says about DNU in case of super sends. if method.primitive: @@ -242,7 +243,7 @@ return except primitives.PrimitiveFailedError: if interp.should_trace(True): - print "PRIMITIVE FAILED: %d %s" % (method.primitive, selector,) + print "PRIMITIVE FAILED: %d %s" % (method.primitive, w_selector.as_string(),) pass # ignore this error and fall back to the Smalltalk version arguments = self.pop_and_return_n(argcount) frame = method.create_frame(self.space, receiver, arguments, @@ -317,12 +318,12 @@ def getExtendedSelectorArgcount(self): descriptor = self.getbytecode() - return ((self.method().getliteralsymbol(descriptor & 31)), + return ((self.method().getliteral(descriptor & 31)), (descriptor >> 5)) def singleExtendedSendBytecode(self, interp): - selector, argcount = self.getExtendedSelectorArgcount() - self._sendSelfSelector(selector, argcount, interp) + w_selector, argcount = self.getExtendedSelectorArgcount() + self._sendSelfSelector(w_selector, argcount, interp) def doubleExtendedDoAnythingBytecode(self, interp): second = self.getbytecode() @@ -330,11 +331,11 @@ opType = second >> 5 if opType == 0: # selfsend - self._sendSelfSelector(self.method().getliteralsymbol(third), + self._sendSelfSelector(self.method().getliteral(third), second & 31, interp) elif opType == 1: # supersend - self._sendSuperSelector(self.method().getliteralsymbol(third), + self._sendSuperSelector(self.method().getliteral(third), second & 31, interp) elif opType == 2: # pushReceiver @@ -357,14 +358,14 @@ association.store_value(self.top()) def singleExtendedSuperBytecode(self, interp): - selector, argcount = self.getExtendedSelectorArgcount() - self._sendSuperSelector(selector, argcount, interp) + w_selector, argcount = self.getExtendedSelectorArgcount() + self._sendSuperSelector(w_selector, argcount, interp) def secondExtendedSendBytecode(self, interp): descriptor = self.getbytecode() - selector = self.method().getliteralsymbol(descriptor & 63) + w_selector = self.method().getliteral(descriptor & 63) argcount = descriptor >> 6 - self._sendSelfSelector(selector, argcount, interp) + self._sendSelfSelector(w_selector, argcount, interp) def popStackBytecode(self, interp): self.pop() @@ -479,27 +480,32 @@ bytecodePrimBitAnd = make_call_primitive_bytecode(primitives.BIT_AND, "bitAnd:", 1) bytecodePrimBitOr = make_call_primitive_bytecode(primitives.BIT_OR, "bitOr:", 1) + @objectmodel.specialize.arg(1) + def _sendSelfSelectorSpecial(self, selector, numargs, interp): + w_selector = self.space.get_special_selector(selector) + return self._sendSelfSelector(w_selector, numargs, interp) + def bytecodePrimAt(self, interp): # n.b.: depending on the type of the receiver, this may invoke # primitives.AT, primitives.STRING_AT, or something else for all - # I know. - self._sendSelfSelector("at:", 1, interp) + # I know. + self._sendSelfSelectorSpecial("at:", 1, interp) def bytecodePrimAtPut(self, interp): # n.b. as above - self._sendSelfSelector("at:put:", 2, interp) + self._sendSelfSelectorSpecial("at:put:", 2, interp) def bytecodePrimSize(self, interp): - self._sendSelfSelector("size", 0, interp) + self._sendSelfSelectorSpecial("size", 0, interp) def bytecodePrimNext(self, interp): - self._sendSelfSelector("next", 0, interp) + self._sendSelfSelectorSpecial("next", 0, interp) def bytecodePrimNextPut(self, interp): - self._sendSelfSelector("nextPut:", 1, interp) + self._sendSelfSelectorSpecial("nextPut:", 1, interp) def bytecodePrimAtEnd(self, interp): - self._sendSelfSelector("atEnd", 0, interp) + self._sendSelfSelectorSpecial("atEnd", 0, interp) def bytecodePrimEquivalent(self, interp): # short-circuit: classes cannot override the '==' method, @@ -517,19 +523,19 @@ bytecodePrimValueWithArg = make_call_primitive_bytecode(primitives.VALUE, "value:", 1) def bytecodePrimDo(self, interp): - self._sendSelfSelector("do:", 1, interp) + self._sendSelfSelectorSpecial("do:", 1, interp) def bytecodePrimNew(self, interp): - self._sendSelfSelector("new", 0, interp) + self._sendSelfSelectorSpecial("new", 0, interp) def bytecodePrimNewWithArg(self, interp): - self._sendSelfSelector("new:", 1, interp) + self._sendSelfSelectorSpecial("new:", 1, interp) def bytecodePrimPointX(self, interp): - self._sendSelfSelector("x", 0, interp) + self._sendSelfSelectorSpecial("x", 0, interp) def bytecodePrimPointY(self, interp): - self._sendSelfSelector("y", 0, interp) + self._sendSelfSelectorSpecial("y", 0, interp) BYTECODE_RANGES = [ ( 0, 15, "pushReceiverVariableBytecode"), diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -1,6 +1,6 @@ from spyvm import constants, model, shadow, wrapper from spyvm.error import UnwrappingError, WrappingError -from rpython.rlib.objectmodel import instantiate +from rpython.rlib.objectmodel import instantiate, specialize from rpython.rlib.rarithmetic import intmask, r_uint class ObjSpace(object): @@ -147,8 +147,11 @@ self.w_zero = model.W_SmallInteger(0) self.w_one = model.W_SmallInteger(1) self.w_two = model.W_SmallInteger(2) + w_special_selectors = model.W_PointersObject( + self.classtable['w_Array'], len(constants.SPECIAL_SELECTORS) * 2) + self.w_special_selectors = w_special_selectors + self.objtable = {} - for name in constants.objects_in_special_object_table: name = "w_" + name try: @@ -156,6 +159,11 @@ except KeyError, e: self.objtable[name] = None + @specialize.arg(1) + def get_special_selector(self, selector): + i0 = constants.find_selectorindex(selector) + return self.w_special_selectors.at0(self, i0) + # methods for wrapping and unwrapping stuff def wrap_int(self, val): @@ -255,7 +263,7 @@ def unwrap_array(self, w_array): # Check that our argument has pointers format and the class: if not w_array.getclass(self).is_same_object(self.w_Array): - raise PrimitiveFailedError() + raise UnwrappingError() assert isinstance(w_array, model.W_PointersObject) return [w_array.at0(self, i) for i in range(w_array.size())] diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -856,10 +856,10 @@ raise PrimitiveFailedError() @expose_primitive(PERFORM_WITH_ARGS, - unwrap_spec=[object, str, object], + unwrap_spec=[object, object, object], no_result=True) -def func(interp, w_rcvr, sel, w_args): - w_method = w_rcvr.shadow_of_my_class(interp.space).lookup(sel) +def func(interp, w_rcvr, w_sel, w_args): + w_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel) assert w_method w_frame = w_method.create_frame(interp.space, w_rcvr, diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -232,15 +232,15 @@ def __repr__(self): return "<ClassShadow %s>" % (self.name or '?',) - def lookup(self, selector): + def lookup(self, w_selector): look_in_shadow = self while look_in_shadow is not None: try: - w_method = look_in_shadow.s_methoddict().methoddict[selector] + w_method = look_in_shadow.s_methoddict().methoddict[w_selector] return w_method except KeyError, e: look_in_shadow = look_in_shadow.s_superclass() - raise MethodNotFound(self, selector) + raise MethodNotFound(self, w_selector) def initialize_methoddict(self): "NOT_RPYTHON" # this is only for testing. @@ -249,10 +249,11 @@ self.w_methoddict._store(1, model.W_PointersObject(None, 0)) self.s_methoddict().invalid = False - def installmethod(self, selector, w_method): + def installmethod(self, w_selector, w_method): "NOT_RPYTHON" # this is only for testing. + assert not isinstance(w_selector, str) self.initialize_methoddict() - self.s_methoddict().methoddict[selector] = w_method + self.s_methoddict().methoddict[w_selector] = w_method if isinstance(w_method, model.W_CompiledMethod): method = w_method.as_compiledmethod_get_shadow(self.space) method.w_compiledin = self.w_self() @@ -276,12 +277,12 @@ if not w_selector.is_same_object(self.space.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) if not isinstance(w_compiledmethod, model.W_CompiledMethod): raise ClassShadowError("the methoddict must contain " "CompiledMethods only for now") - self.methoddict[selector] = w_compiledmethod + self.methoddict[w_selector] = w_compiledmethod + selector = w_selector.as_string() w_compiledmethod._likely_methodname = selector @@ -738,7 +739,8 @@ class CompiledMethodShadow(object): _immutable_fields_ = ["_w_self", "bytecode", "literals[*]", "bytecodeoffset", - "literalsize", "tempsize", "w_compiledin"] + "literalsize", "tempsize", "primitive", + "w_compiledin"] def __init__(self, w_compiledmethod): self._w_self = w_compiledmethod @@ -747,6 +749,7 @@ self.bytecodeoffset = w_compiledmethod.bytecodeoffset() self.literalsize = w_compiledmethod.getliteralsize() self.tempsize = w_compiledmethod.gettempsize() + self.primitive = w_compiledmethod.primitive self.w_compiledin = None if self.literals: diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -77,4 +77,4 @@ def interp_w(): interp.interpret() - self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) \ No newline at end of file + self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -1,6 +1,6 @@ import py from spyvm import model, interpreter, primitives, shadow -from spyvm import objspace, wrapper +from spyvm import objspace, wrapper, constants mockclass = objspace.bootstrap_class @@ -25,7 +25,7 @@ globals()[name] = make_getter(entry) setup() -def run_with_faked_methods(methods, func, active_context=None): +def run_with_faked_primitive_methods(methods, func, active_context=None): # Install faked compiled methods that just invoke the primitive: for (w_class, primnum, argsize, methname) in methods: @@ -33,8 +33,17 @@ prim_meth = model.W_CompiledMethod(0) prim_meth.primitive = primnum prim_meth.argsize = argsize - s_class.installmethod(methname, prim_meth) - + symbol = fakesymbol(methname) + # somewhat evil: + try: + index = constants.find_selectorindex(methname) + except ValueError: + pass + else: + space.w_special_selectors.atput0(space, index, symbol) + assert space.get_special_selector(methname) is symbol + s_class.installmethod(symbol, prim_meth) + assert space.w_nil._shadow is None try: func(active_context) if active_context else func() @@ -43,7 +52,7 @@ assert space.w_nil._shadow is None for (w_class, _, _, methname) in methods: s_class = w_class.as_class_get_shadow(space) - del s_class.s_methoddict().methoddict[methname] + del s_class.s_methoddict().methoddict[fakesymbol(methname)] def fakesymbol(s, _cache={}): try: @@ -349,7 +358,7 @@ w_metaclass=w_fakeclassclass) interp = new_interpreter(bytecodePrimNew) interp.s_active_context().push(w_fakeclass) - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclassclass, primitives.NEW, 0, "new"]], interp.step, interp.s_active_context()) @@ -365,7 +374,7 @@ interp = new_interpreter(bytecodePrimNewWithArg) interp.s_active_context().push(w_fakeclass) interp.s_active_context().push(space.w_two) - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclassclass, primitives.NEW_WITH_ARG, 1, "new:"]], interp.step, interp.s_active_context()) @@ -379,7 +388,7 @@ w_fakeinst = w_fakeclass.as_class_get_shadow(space).new(5) interp = new_interpreter(bytecodePrimSize) interp.s_active_context().push(w_fakeinst) - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclass, primitives.SIZE, 0, "size"]], interp.step, interp.s_active_context()) @@ -399,16 +408,18 @@ shadow = w_class.as_class_get_shadow(space) w_method = model.W_CompiledMethod(2) w_method.bytes = pushConstantOneBytecode + bytecode - shadow.installmethod("foo", w_method) + literals = fakeliterals(space, "foo") + w_foo = literals[0] + shadow.installmethod(w_foo, w_method) interp = new_interpreter(bytecodes) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo")) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) interp.s_active_context().push(w_object) callerContext = interp.w_active_context() interp.step(interp.s_active_context()) assert interp.s_active_context().w_sender() == callerContext assert interp.s_active_context().stack() == [] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict["foo"]) + assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo]) assert callerContext.as_context_get_shadow(space).stack() == [] interp.step(interp.s_active_context()) interp.step(interp.s_active_context()) @@ -428,11 +439,12 @@ method.bytes = bytecode method.argsize = 1 method.tempsize = 1 - method.setliterals(fakeliterals(space, "fib:")) - shadow.installmethod("fib:", method) + literals = fakeliterals(space, "fib:") + method.setliterals(literals) + shadow.installmethod(literals[0], method) w_object = shadow.new() interp = new_interpreter(sendLiteralSelectorBytecode(16) + returnTopFromMethod) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "fib:")) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) interp.s_active_context().push(w_object) interp.s_active_context().push(space.wrap_int(8)) result = interp.interpret() @@ -442,7 +454,7 @@ def test(): interp = new_interpreter(sendLiteralSelectorBytecode(1 + 16)) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo", "sub")) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo", "-")) interp.s_active_context().push(space.wrap_int(50)) interp.s_active_context().push(space.wrap_int(8)) callerContext = interp.w_active_context() @@ -452,9 +464,9 @@ w_result = interp.s_active_context().pop() assert space.unwrap_int(w_result) == 42 - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_SmallInteger, primitives.SUBTRACT, - 1, "sub"]], + 1, "-"]], test) def test_makePoint(): @@ -568,13 +580,16 @@ w_method.argsize = 1 w_method.tempsize = 1 w_method.literalsize = 1 - shadow.installmethod("+", w_method) - + w_symbol = fakesymbol("+") + shadow.installmethod(w_symbol, w_method) + # slightly evil + space.w_special_selectors.atput0(space, constants.find_selectorindex("+"), w_symbol) + w_object = shadow.new() interp.s_active_context().push(w_object) interp.s_active_context().push(space.w_one) interp.step(interp.s_active_context()) - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict["+"] + assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol] assert interp.s_active_context().w_receiver() is w_object assert interp.w_active_context().as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) assert interp.s_active_context().stack() == [] @@ -609,17 +624,19 @@ # which does a call to its super meth1 = model.W_CompiledMethod(2) meth1.bytes = pushReceiverBytecode + bytecode - meth1.setliterals(fakeliterals(space, "foo")) - w_class.as_class_get_shadow(space).installmethod("foo", meth1) + literals = fakeliterals(space, "foo") + foo = literals[0] + meth1.setliterals(literals) + w_class.as_class_get_shadow(space).installmethod(foo, meth1) # and that one again to its super meth2 = model.W_CompiledMethod(2) meth2.bytes = pushReceiverBytecode + bytecode - meth2.setliterals(fakeliterals(space, "foo")) - w_super.as_class_get_shadow(space).installmethod("foo", meth2) + meth2.setliterals(fakeliterals(space, foo)) + w_super.as_class_get_shadow(space).installmethod(foo, meth2) meth3 = model.W_CompiledMethod(0) - w_supersuper.as_class_get_shadow(space).installmethod("foo", meth3) + w_supersuper.as_class_get_shadow(space).installmethod(foo, meth3) interp = new_interpreter(bytecodes) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo")) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) interp.s_active_context().push(w_object) interp.step(interp.s_active_context()) for w_specificclass in [w_super, w_supersuper]: @@ -629,7 +646,7 @@ assert interp.s_active_context().w_sender() == callerContext assert interp.s_active_context().stack() == [] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver() == w_object - meth = w_specificclass.as_class_get_shadow(space).s_methoddict().methoddict["foo"] + meth = w_specificclass.as_class_get_shadow(space).s_methoddict().methoddict[foo] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == meth assert callerContext.as_context_get_shadow(space).stack() == [] @@ -703,7 +720,7 @@ [ 137, 119, 200, 164, 6, 105, 104, 16, 17, 176, 125, 33, 34, 240, 124 ], fakeliterals(space, "value:value:", space.wrap_int(3), space.wrap_int(4))).value == 7 - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_BlockContext, primitives.VALUE, 2, "value:value:"]], test) @@ -741,7 +758,7 @@ 125, 33, 224, 124 ], fakeliterals(space, "valueWithArguments:", [3, 2])).value == 1 - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_BlockContext, primitives.VALUE_WITH_ARGS, 1, "valueWithArguments:"]], test) @@ -752,7 +769,7 @@ assert interpret_bc( [ 32, 118, 192, 124], fakeliterals(space, "a")) == space.wrap_char("a") - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_String, primitives.STRING_AT, 1, "at:"]], test) @@ -762,7 +779,7 @@ assert interpret_bc( [ 32, 118, 33, 193, 124 ], fakeliterals(space, "a", space.wrap_char("b"))) == space.wrap_char("b") - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_String, primitives.STRING_AT_PUT, 2, "at:put:"]], test) @@ -777,7 +794,7 @@ [112, 118, 192, 124], fakeliterals(space, ), receiver=w_fakeinst)) == "b" - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclass, primitives.AT, 1, "at:"]], test) @@ -794,7 +811,7 @@ receiver=w_fakeinst)) == "b" assert space.unwrap_char(w_fakeinst.fetch(space, 0)) == "a" assert space.unwrap_char(w_fakeinst.fetch(space, 1)) == "b" - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclass, primitives.AT_PUT, 2, "at:put:"]], test) @@ -816,7 +833,7 @@ [112, 119, 33, 240, 124], oalp, receiver=prim_meth).value == 3 assert interpret_bc( [112, 119, 224, 124], oal, receiver=prim_meth).value == 3 - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_CompiledMethod, primitives.OBJECT_AT, 1, "objectAt:"], [space.w_CompiledMethod, primitives.OBJECT_AT_PUT, 2, "objectAt:put:"]], test) diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -17,9 +17,23 @@ module.reader = open_miniimage(space) reader.initialize() module.image = squeakimage.SqueakImage() - module.image.from_reader(space, get_reader()) + module.image.from_reader(space, reader) module.space = space - + +def find_symbol(name): + w_dnu = image.special(constants.SO_DOES_NOT_UNDERSTAND) + assert str(w_dnu) == "doesNotUnderstand:" + w_Symbol = w_dnu.getclass(space) + for chunk in reader.chunklist: + w_obj = chunk.g_object.w_object + if not isinstance(w_obj, model.W_BytesObject): + continue + if not w_obj.getclass(space).is_same_object(w_Symbol): + continue + if w_obj.as_string() == name: + return w_obj + return perform(space.wrap_string(name), "asSymbol") + def open_miniimage(space): return squeakimage.ImageReader(space, squeakimage.Stream(mini_image.open())) @@ -192,7 +206,7 @@ # Should get this from w_object w_smallint_class = image.special(constants.SO_SMALLINTEGER_CLASS) s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup("abs") + w_method = s_class.lookup(find_symbol("abs")) assert w_method w_frame = w_method.create_frame(space, w_object, []) @@ -286,7 +300,11 @@ def perform(w_receiver, selector, *arguments_w): interp = interpreter.Interpreter(space) s_class = w_receiver.shadow_of_my_class(space) - w_method = s_class.lookup(selector) + if isinstance(selector, str): + w_selector = find_symbol(selector) + else: + w_selector = selector + w_method = s_class.lookup(w_selector) assert w_method w_frame = w_method.create_frame(space, w_receiver, list(arguments_w)) interp.store_w_active_context(w_frame) diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -6,6 +6,8 @@ mockclass = objspace.bootstrap_class space = objspace.ObjSpace() +w_foo = space.wrap_string("foo") +w_bar = space.wrap_string("bar") def joinbits(values, lengths): result = 0 @@ -59,29 +61,29 @@ def test_method_lookup(): w_class = mockclass(space, 0) shadow = w_class.as_class_get_shadow(space) - shadow.installmethod("foo", 1) - shadow.installmethod("bar", 2) + shadow.installmethod(w_foo, 1) + shadow.installmethod(w_bar, 2) w_subclass = mockclass(space, 0, w_superclass=w_class) subshadow = w_subclass.as_class_get_shadow(space) assert subshadow.s_superclass() is shadow - subshadow.installmethod("foo", 3) + subshadow.installmethod(w_foo, 3) shadow.initialize_methoddict() subshadow.initialize_methoddict() - assert shadow.lookup("foo") == 1 - assert shadow.lookup("bar") == 2 + assert shadow.lookup(w_foo) == 1 + assert shadow.lookup(w_bar) == 2 py.test.raises(MethodNotFound, shadow.lookup, "zork") - assert subshadow.lookup("foo") == 3 - assert subshadow.lookup("bar") == 2 + assert subshadow.lookup(w_foo) == 3 + assert subshadow.lookup(w_bar) == 2 py.test.raises(MethodNotFound, subshadow.lookup, "zork") def test_w_compiledin(): w_super = mockclass(space, 0) w_class = mockclass(space, 0, w_superclass=w_super) supershadow = w_super.as_class_get_shadow(space) - supershadow.installmethod("foo", model.W_CompiledMethod(0)) + supershadow.installmethod(w_foo, model.W_CompiledMethod(0)) classshadow = w_class.as_class_get_shadow(space) classshadow.initialize_methoddict() - assert classshadow.lookup("foo").as_compiledmethod_get_shadow(space).w_compiledin is w_super + assert classshadow.lookup(w_foo).as_compiledmethod_get_shadow(space).w_compiledin is w_super def test_compiledmethod_setchar(): w_method = model.W_CompiledMethod(3) diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -69,7 +69,10 @@ 'bar': model.W_CompiledMethod(0)} w_class = build_smalltalk_class("Demo", 0x90, methods=methods) classshadow = w_class.as_class_get_shadow(space) - assert classshadow.s_methoddict().methoddict == methods + methoddict = classshadow.s_methoddict().methoddict + assert len(methods) == len(methoddict) + for w_key, value in methoddict.items(): + assert methods[w_key.as_string()] is value def method(tempsize=3,argsize=2, bytes="abcde"): w_m = model.W_CompiledMethod() _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit