def test_cached_methoddict(): # create a methoddict foo = model.W_CompiledMethod(space, 0) bar = model.W_CompiledMethod(space, 0) baz = model.W_CompiledMethod(space, 0) methods = {'foo': foo, 'bar': bar} w_class = build_smalltalk_class("Demo", 0x90, methods=methods) s_class = w_class.as_class_get_shadow(space) s_methoddict = s_class.s_methoddict() s_methoddict.sync_method_cache() i = 0 key = s_methoddict.w_self().fetch(s_methoddict.space, constants.METHODDICT_NAMES_INDEX + i) while key.is_nil(space): i = i + 1 key = s_methoddict.w_self().fetch(s_methoddict.space, constants.METHODDICT_NAMES_INDEX + i) assert (s_class.lookup(key) is foo or s_class.lookup(key) is bar) # change that entry w_array = s_class.w_methoddict().fetch(s_class.space, constants.METHODDICT_VALUES_INDEX) version = s_class.version w_array.atput0(space, i, baz) assert s_class.lookup(key) is baz assert version is not s_class.version
def test_methoddict(): 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(space) methoddict = classshadow.s_methoddict().methoddict assert len(methods) == len(methoddict) for w_key, value in methoddict.items(): assert methods[w_key.as_string()].as_compiledmethod_get_shadow(space) is value
def method(tempsize=3,argsize=2, bytes="abcde"): w_m = model.W_CompiledMethod() w_m.bytes = bytes w_m.tempsize = tempsize w_m.argsize = argsize w_m.literalsize = 2 return w_m
def create_method(tempsize=3, argsize=2, bytes="abcde"): w_m = model.W_CompiledMethod(space, ) w_m.bytes = bytes w_m._tempsize = tempsize w_m.argsize = argsize w_m.literalsize = 2 return w_m
def perform(self, w_receiver, selector, *arguments_w): if isinstance(selector, str): if selector == "asSymbol": w_selector = self.image.w_asSymbol else: w_selector = self.perform(self.space.wrap_string(selector), "asSymbol") else: w_selector = selector w_method = model.W_CompiledMethod(header=512) w_method.literalatput0(self.space, 1, w_selector) assert len(arguments_w) <= 7 w_method.setbytes([chr(131), chr(len(arguments_w) << 5 + 0), chr(124)]) #returnTopFromMethod s_method = w_method.as_compiledmethod_get_shadow(self.space) s_frame = MethodContextShadow.make_context(self.space, s_method, w_receiver, [], None) s_frame.push(w_receiver) s_frame.push_all(list(arguments_w)) self.interrupt_check_counter = self.interrupt_counter_size try: self.loop(s_frame.w_self()) except ReturnFromTopLevel, e: return e.object
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: s_class = w_class.as_class_get_shadow(space) prim_meth = model.W_CompiledMethod(space, 0) prim_meth._primitive = primnum prim_meth.argsize = argsize 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) try: func(active_context) if active_context else func() finally: # Uninstall those methods: for (w_class, _, _, methname) in methods: s_class = w_class.as_class_get_shadow(space) s_class.s_methoddict().sync_method_cache()
def sendBytecodesTest(w_class, w_object, bytecodes): for bytecode, result in [(returnReceiverBytecode, w_object), (returnTrueBytecode, space.w_true), (returnFalseBytecode, space.w_false), (returnNilBytecode, space.w_nil), (returnTopFromMethodBytecode, space.w_one)]: shadow = w_class.as_class_get_shadow(space) w_method = model.W_CompiledMethod(space, 2) w_method.bytes = pushConstantOneBytecode + bytecode literals = fakeliterals(space, "foo") w_foo = literals[0] shadow.installmethod(w_foo, w_method) w_frame, s_frame = new_frame(bytecodes) s_frame.w_method().setliterals(literals) s_frame.push(w_object) w_active_context = step_in_interp(s_frame) s_active_context = w_active_context.as_context_get_shadow(space) assert s_active_context.w_sender() == w_frame assert s_active_context.stack() == [] assert w_active_context.as_context_get_shadow( space).w_receiver().is_same_object(w_object) assert w_active_context.as_context_get_shadow( space).w_method().is_same_object( shadow.s_methoddict().methoddict[w_foo]) assert s_frame.stack() == [] step_in_interp(s_active_context) w_active_context = step_in_interp(s_active_context) s_active_context = w_active_context.as_context_get_shadow(space) assert w_active_context == w_frame assert_list(s_active_context.stack(), [result])
def create_toplevel_context(self, w_receiver, selector="", w_selector=None, w_arguments=[]): if w_selector is None: assert selector, "Need either string or W_Object selector" if selector == "asSymbol": w_selector = self.image.w_asSymbol else: w_selector = self.perform(self.space.wrap_string(selector), "asSymbol") w_method = model.W_CompiledMethod(self.space, header=512) w_method.literalatput0(self.space, 1, w_selector) assert len(w_arguments) <= 7 w_method.setbytes([chr(131), chr(len(w_arguments) << 5 + 0), chr(124)]) #returnTopFromMethodBytecode w_method.set_lookup_class_and_name(w_receiver.getclass(self.space), "Interpreter.perform") s_frame = ContextPartShadow.build_method_context( self.space, w_method, w_receiver) s_frame.push(w_receiver) s_frame.push_all(list(w_arguments)) return s_frame
def test_actual_stackdepth(): # | testBlock | # testBlock := [ :aNumber | # aNumber = 0 # ifTrue: [ 2 ] # ifFalse: [ (testBlock value: aNumber - 1) + aNumber ]]. # ^ testBlock value: 11 import operator interp = StackTestInterpreter(space, max_stack_depth=10) #create a method with the correct bytecodes and a literal bytes = reduce( operator.add, map(chr, [ 0x8a, 0x01, 0x68, 0x10, 0x8f, 0x11, 0x00, 0x11, 0x10, 0x75, 0xb6, 0x9a, 0x77, 0xa4, 0x09, 0x8c, 0x00, 0x01, 0x10, 0x76, 0xb1, 0xca, 0x10, 0xb0, 0x7d, 0x8e, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x20, 0xca, 0x7c ])) w_method = model.W_CompiledMethod(len(bytes)) w_method.islarge = 1 w_method.bytes = bytes w_method.argsize = 0 w_method.tempsize = 1 w_method.setliterals([space.wrap_int(11)]) #create a frame for that method w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame( space, space.wrap_int(0), []).w_self() try: interp.loop(w_frame) except interpreter.ReturnFromTopLevel, e: assert space.unwrap_int(e.object) == 68
def test_compiledmethod_atput0_not_aligned(): header = joinbits([0, 2, 0, 0, 0, 0], [9, 8, 1, 6, 4, 1]) w_method = model.W_CompiledMethod(3, header) with py.test.raises(error.PrimitiveFailedError): w_method.atput0(space, 7, 'lit1') with py.test.raises(error.PrimitiveFailedError): w_method.atput0(space, 9, space.wrap_int(5))
def test_compiledin_class(): w_super = bootstrap_class(0) w_class = bootstrap_class(0, w_superclass=w_super) supershadow = w_super.as_class_get_shadow(space) supershadow.installmethod(w_foo, model.W_CompiledMethod(space, 0)) classshadow = w_class.as_class_get_shadow(space) classshadow.initialize_methoddict() assert classshadow.lookup(w_foo).compiled_in() is w_super
def test_compiledin_class_assoc(): val = bootstrap_class(0) assoc = new_object(2) assoc.store(space, 0, new_object()) assoc.store(space, 1, val) meth = model.W_CompiledMethod(space, 0) meth.setliterals([new_object(), new_object(), assoc]) assert meth.compiled_in() == val
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(w_foo, model.W_CompiledMethod(0)) classshadow = w_class.as_class_get_shadow(space) classshadow.initialize_methoddict() assert classshadow.lookup(w_foo).w_compiledin is w_super
def test_size_of_compiled_method(): literalsize = 3 bytecount = 3 w_cm = model.W_CompiledMethod(space, bytecount) w_cm.literalsize = literalsize assert prim( primitives.SIZE, [w_cm ]).value == (literalsize + 1) * constants.BYTES_PER_WORD + bytecount
def create_method_shadow(bytes, literals=[], islarge=0, argsize=0, tempsize=0): w_method = model.W_CompiledMethod(len(bytes)) w_method.bytes = bytes w_method.islarge = islarge w_method.argsize = argsize w_method.tempsize = tempsize w_method.setliterals(literals) s_method = w_method.as_compiledmethod_get_shadow(space) return s_method
def new_frame(bytes, receiver=space.w_nil, space=space): 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 = 8 w_method.setliterals([model.W_PointersObject(space, None, 2)]) s_frame = w_method.as_compiledmethod_get_shadow(space).create_frame( space, receiver, ["foo", "bar"]) return s_frame.w_self(), s_frame
def test_updating_class_changes_subclasses(): w_parent = build_smalltalk_class("Demo", 0x90, methods={'bar': model.W_CompiledMethod(0)}) w_class = build_smalltalk_class("Demo", 0x90, methods={'foo': model.W_CompiledMethod(0)}, w_superclass=w_parent) s_class = w_class.as_class_get_shadow(space) version = s_class.version w_method = model.W_CompiledMethod(0) key = space.wrap_string('foo') s_md = w_parent.as_class_get_shadow(space).s_methoddict() s_md.sync_cache() w_ary = s_md._w_self._fetch(constants.METHODDICT_VALUES_INDEX) s_md._w_self.atput0(space, 0, key) w_ary.atput0(space, 0, w_method) assert s_class.lookup(key) is w_method.as_compiledmethod_get_shadow(space) assert s_class.version is not version assert s_class.version is w_parent.as_class_get_shadow(space).version
def test_singleExtendedSuperBytecode(bytecode=singleExtendedSuperBytecode + chr((0 << 5) + 0)): w_supersuper = bootstrap_class(0) w_super = bootstrap_class(0, w_superclass=w_supersuper) w_class = bootstrap_class(0, w_superclass=w_super) w_object = w_class.as_class_get_shadow(space).new() # first call method installed in w_class bytecodes = singleExtendedSendBytecode + chr(0) # which does a call to its super meth1 = model.W_CompiledMethod(space, 2) meth1.bytes = pushReceiverBytecode + bytecode 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(space, 2) meth2.bytes = pushReceiverBytecode + bytecode meth2.setliterals(fakeliterals(space, foo)) w_super.as_class_get_shadow(space).installmethod(foo, meth2) meth3 = model.W_CompiledMethod(space, 0) w_supersuper.as_class_get_shadow(space).installmethod(foo, meth3) w_frame, s_frame = new_frame(bytecodes) s_frame.w_method().setliterals(literals) s_frame.push(w_object) w_active_context = step_in_interp(s_frame) s_active_context = w_active_context.as_context_get_shadow(space) for w_specificclass in [w_super, w_supersuper]: w_caller_context = w_active_context s_caller_context = s_active_context step_in_interp(s_active_context) w_active_context = step_in_interp(s_active_context) s_active_context = w_active_context.as_context_get_shadow(space) assert s_active_context.w_sender() == w_caller_context assert s_active_context.stack() == [] assert w_active_context.as_context_get_shadow( space).w_receiver() == w_object meth = w_specificclass.as_class_get_shadow( space).s_methoddict().methoddict[foo] assert s_active_context.w_method() == meth assert s_caller_context.stack() == []
def test_compiledmethod_at0(): w_method = model.W_CompiledMethod() w_method.bytes = list("abc") w_method.header = 100 w_method.setliterals(['lit1', 'lit2']) w_method.literalsize = 2 assert space.unwrap_int(w_method.at0(space, 0)) == 100 assert w_method.at0(space, 4) == 'lit1' assert w_method.at0(space, 8) == 'lit2' assert space.unwrap_int(w_method.at0(space, 12)) == ord('a') assert space.unwrap_int(w_method.at0(space, 13)) == ord('b') assert space.unwrap_int(w_method.at0(space, 14)) == ord('c')
def make_method(self, bytes, literals=None, numargs=0): if not isinstance(bytes, str): bytes = "".join([chr(x) for x in bytes]) w_method = model.W_CompiledMethod(self, len(bytes)) w_method.islarge = 1 w_method.bytes = bytes w_method.argsize = numargs w_method._tempsize = 8 if literals is None: literals = [model.W_PointersObject(self, None, 2)] w_method.setliterals(literals) return w_method
def preload_execute_frame(imagename, bytes, literals, stack): interp = load(imagename) space = interp.space w_method = model.W_CompiledMethod(space, header=512) w_method.literals = literals w_method.setbytes(bytes) w_receiver = stack[0] s_frame = storage_contexts.ContextPartShadow.build_method_context( space, w_method, w_receiver) w_frame = s_frame.w_self() def interp_execute_frame(): return interp.interpret_toplevel(w_frame) return interp_execute_frame
def context_for(interp, number, benchmark, stringarg): # XXX: Copied from interpreter >> perform argcount = 0 if stringarg == "" else 1 w_receiver = interp.space.wrap_int(number) w_selector = interp.perform(interp.space.wrap_string(benchmark), "asSymbol") w_method = model.W_CompiledMethod(header=512) w_method.literalatput0(interp.space, 1, w_selector) w_method.setbytes([chr(131), chr(argcount << 5), chr(124)]) #returnTopFromMethod s_method = w_method.as_compiledmethod_get_shadow(interp.space) s_frame = shadow.MethodContextShadow.make_context(interp.space, s_method, w_receiver, [], None) s_frame.push(w_receiver) if not stringarg == "": s_frame.push(interp.space.wrap_string(stringarg)) return s_frame
def test_create_frame(): w_method = model.W_CompiledMethod(space, len("hello")) w_method.bytes = "hello" w_method.islarge = 1 w_method.argsize = 2 w_method._tempsize = 8 s_frame = w_method.create_frame(space, w("receiver"), [w("foo"), w("bar")]) w_frame = s_frame.w_self() assert s_frame.w_receiver().as_string() == "receiver" assert s_frame.gettemp(0).as_string() == "foo" assert s_frame.gettemp(1).as_string() == "bar" assert s_frame.gettemp(2).is_nil(space) s_frame.settemp(2, w("spam")) assert s_frame.gettemp(2).as_string() == "spam" assert s_frame.fetch_next_bytecode() == ord("h") assert s_frame.fetch_next_bytecode() == ord("e") assert s_frame.fetch_next_bytecode() == ord("l")
def test_compiledmethod_atput0(): w_method = model.W_CompiledMethod(3) newheader = joinbits([0, 2, 0, 0, 0, 0], [9, 8, 1, 6, 4, 1]) assert w_method.getliteralsize() == 0 w_method.atput0(space, 0, space.wrap_int(newheader)) assert w_method.getliteralsize( ) == 8 # 2 from new header * BYTES_PER_WORD (= 4) w_method.atput0(space, 4, 'lit1') w_method.atput0(space, 8, 'lit2') w_method.atput0(space, 12, space.wrap_int(ord('a'))) w_method.atput0(space, 13, space.wrap_int(ord('b'))) w_method.atput0(space, 14, space.wrap_int(ord('c'))) assert space.unwrap_int(w_method.at0(space, 0)) == newheader assert w_method.at0(space, 4) == 'lit1' assert w_method.at0(space, 8) == 'lit2' assert space.unwrap_int(w_method.at0(space, 12)) == ord('a') assert space.unwrap_int(w_method.at0(space, 13)) == ord('b') assert space.unwrap_int(w_method.at0(space, 14)) == ord('c')
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 = 8 s_frame = w_method.as_compiledmethod_get_shadow(space).create_frame( space, "receiver", ["foo", "bar"]) w_frame = s_frame.w_self() assert s_frame.w_receiver() == "receiver" assert s_frame.gettemp(0) == "foo" assert s_frame.gettemp(1) == "bar" assert s_frame.gettemp(2) is space.w_nil s_frame.settemp(2, "spam") assert s_frame.gettemp(2) == "spam" assert s_frame.getbytecode() == ord("h") assert s_frame.getbytecode() == ord("e") assert s_frame.getbytecode() == ord("l")
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 = bootstrap_class(0).as_class_get_shadow(space) method = model.W_CompiledMethod(space, len(bytecode)) method.literalsize = 1 method.bytes = bytecode method.argsize = 1 method._tempsize = 1 literals = fakeliterals(space, "fib:") method.setliterals(literals) shadow.installmethod(literals[0], method) w_object = shadow.new() w_frame, s_frame = new_frame(sendLiteralSelectorBytecode(16) + returnTopFromMethodBytecode) s_frame.w_method().setliterals(literals) s_frame.push(w_object) s_frame.push(space.wrap_int(8)) result = interp.interpret_toplevel(w_frame) assert space.unwrap_int(result) == 34
def test_objectsAsMethods(): w_foo = space.wrap_string("foo") w_foo_ = space.wrap_string("foo:") w_runwithin = space.special_object("w_runWithIn") w_holderclass = bootstrap_class(0) w_class = bootstrap_class(0) w_method = model.W_CompiledMethod(space, 1) w_method.setbytes(str(bytearray([0x10, 0x11, 0x12, 0x8a, 0x83, 0x7c]))) # "^ {selector. args. receiver}" push temps, pop 3 into array, return top w_method.argsize = 3 classshadow = w_class.as_class_get_shadow(space) classshadow.installmethod(w_runwithin, w_method) w_object = classshadow.new() holdershadow = w_holderclass.as_class_get_shadow(space) holdershadow.installmethod(w_foo, w_object) holdershadow.installmethod(w_foo_, w_object) w_holderobject = holdershadow.new() bytecodes = [112, 208, 124] #pushReceiverBytecode, sendBytecode for first literal # ^ self foo literals = [w_foo] runwithin_args_w = interpret_bc(bytecodes, literals, w_holderobject) w_runwithin_args = space.unwrap_array(runwithin_args_w) assert w_runwithin_args[0] == w_foo assert w_runwithin_args[1].getclass(space).is_same_object(space.w_Array) assert w_runwithin_args[1].size() == 0 # foo has no arguments assert w_runwithin_args[2] == w_holderobject bytecodes = [0x70, 0x70, 0xE0, 0x7c] #push receiver 2x, send literal with one arg # ^ self foo: self literals = [w_foo_] runwithin_args_w = interpret_bc(bytecodes, literals, w_holderobject) w_runwithin_args = space.unwrap_array(runwithin_args_w) assert w_runwithin_args[0] == w_foo_ assert w_runwithin_args[1].getclass(space).is_same_object(space.w_Array) assert w_runwithin_args[1].size() == 1 # foo: has one argument assert w_runwithin_args[1].fetch( space, 0) == w_holderobject # receiver was used as argument assert w_runwithin_args[2] == w_holderobject
def test_callPrimitiveAndPush_fallback(): w_frame, s_frame = new_frame(bytecodePrimAdd) shadow = bootstrap_class(0).as_class_get_shadow(space) w_method = model.W_CompiledMethod(space, 0) w_method.argsize = 1 w_method._tempsize = 1 w_method.literalsize = 1 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() s_frame.push(w_object) s_frame.push(space.w_one) w_active_context = step_in_interp(s_frame) s_active_context = w_active_context.as_context_get_shadow(space) assert w_active_context.as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol] assert s_active_context.w_receiver() is w_object assert w_active_context.as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) assert s_active_context.stack() == []
def test_compiledmethodshadow(): from test_model import joinbits header = joinbits([0,2,0,1,0,0],[9,8,1,6,4,1]) w_compiledmethod = model.W_CompiledMethod(3, header) w_compiledmethod.setbytes(list("abc")) shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abc" assert shadow.bytecodeoffset == 12 assert shadow.literalsize == 8 # 12 - 4byte header assert shadow.tempsize() == 1 w_compiledmethod.literalatput0(space, 1, 17) w_compiledmethod.literalatput0(space, 2, 41) assert w_compiledmethod._shadow is not None assert shadow.literals == [17, 41] w_compiledmethod.atput0(space, 14, space.wrap_int(ord("x"))) assert shadow.bytecode == "abx" assert shadow is w_compiledmethod.as_compiledmethod_get_shadow(space)
def test_bc_objectAtAndAtPut(): # ^ self objectAt: 1. yields the method header # ^ 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(space, header=1024) prim_meth.setliterals(fakeliterals(space, 22)) oal = fakeliterals(space, "objectAt:") oalp = fakeliterals(space, "objectAt:put:", 3) def test(): assert interpret_bc( [112, 118, 224, 124], oal, receiver=prim_meth).value == 1024 assert interpret_bc( [112, 119, 224, 124], oal, receiver=prim_meth).value == 22 assert interpret_bc( [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_primitive_methods( [[space.w_CompiledMethod, primitives.OBJECT_AT, 1, "objectAt:"], [space.w_CompiledMethod, primitives.OBJECT_AT_PUT, 2, "objectAt:put:"]], test)