Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: Changeset: r73:13fb55f6a092 Date: 2013-02-20 15:56 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/13fb55f6a092/
Log: merge diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -370,7 +370,7 @@ self.pop() # closure bytecodes - def pushNewArrayPopIntoArray(self, interp): + def pushNewArrayBytecode(self, interp): arraySize, popIntoArray = splitter[7, 1](self.getbytecode()) newArray = None if popIntoArray == 1: @@ -388,19 +388,19 @@ w_indirectTemps = self.gettemp(index_of_array) return index_in_array, w_indirectTemps - def pushTempAtInTempVectorAt(self, interp): + def pushRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() self.push(w_indirectTemps.at0(self.space, index_in_array)) - def storeTempAtInTempVectorAt(self, interp): + def storeRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.top()) - def popAndStoreTempAtInTempVectorAt(self, interp): + def storeAndPopRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.pop()) - def pushClosureNumCopiedNumArgsBlockSize(self, interp): + def pushClosureCopyCopiedValuesBytecode(self, interp): """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize "Simulate the action of a 'closure copy' bytecode whose result is the @@ -427,16 +427,8 @@ i = self.getbytecode() blockSize = (j << 8) | i #create new instance of BlockClosure - BlockClosureShadow = space.w_BlockClosure.as_class_get_shadow(space) - w_closure = BlockClosureShadow.new(numCopied) - closure = wrapper.BlockClosureWrapper(space, w_closure) - closure.store_outerContext(self._w_self) - closure.store_startpc(self.pc()) - closure.store_numArgs(numArgs) - if numCopied > 0: - copiedValues = self.pop_and_return_n(numCopied) - for i0 in range(numCopied): - closure.atput0(i0, copiedValues[i0]) + w_closure, closure = space.newClosure(self._w_self, self.pc(), numArgs, + self.pop_and_return_n(numCopied)) self.push(w_closure) self.jump(blockSize) @@ -572,12 +564,12 @@ (135, "popStackBytecode"), (136, "duplicateTopBytecode"), (137, "pushActiveContextBytecode"), - (138, "pushNewArrayPopIntoArray"), + (138, "pushNewArrayBytecode"), (139, "experimentalBytecode"), - (140, "pushTempAtInTempVectorAt"), - (141, "storeTempAtInTempVectorAt"), - (142, "popAndStoreTempAtInTempVectorAt"), - (143, "pushClosureNumCopiedNumArgsBlockSize"), + (140, "pushRemoteTempLongBytecode"), + (141, "storeRemoteTempLongBytecode"), + (142, "storeAndPopRemoteTempLongBytecode"), + (143, "pushClosureCopyCopiedValuesBytecode"), (144, 151, "shortUnconditionalJump"), (152, 159, "shortConditionalJump"), (160, 167, "longUnconditionalJump"), diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -1,6 +1,4 @@ -from spyvm import constants -from spyvm import model -from spyvm import shadow +from spyvm import constants, model, shadow, wrapper from spyvm.error import UnwrappingError, WrappingError from rpython.rlib.objectmodel import instantiate from rpython.rlib.rarithmetic import intmask, r_uint @@ -254,9 +252,27 @@ elif isinstance(w_v, model.W_SmallInteger): return float(w_v.value) raise UnwrappingError() + 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() + assert isinstance(w_array, model.W_PointersObject) + + return [w_array.at0(self, i) for i in range(w_array.size())] + def _freeze_(self): return True + def newClosure(self, outerContext, pc, numArgs, copiedValues): + BlockClosureShadow = self.w_BlockClosure.as_class_get_shadow(self) + w_closure = BlockClosureShadow.new(len(copiedValues)) + closure = wrapper.BlockClosureWrapper(self, w_closure) + closure.store_outerContext(outerContext) + closure.store_startpc(pc) + closure.store_numArgs(numArgs) + for i0 in range(len(copiedValues)): + closure.atput0(i0, copiedValues[i0]) + return w_closure, closure def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -97,6 +97,9 @@ elif spec is str: assert isinstance(w_arg, model.W_BytesObject) args += (w_arg.as_string(), ) + elif spec is list: + assert isinstance(w_arg, model.W_PointersObject) + args += (interp.space.unwrap_array(w_arg), ) elif spec is char: args += (unwrap_char(w_arg), ) else: @@ -829,25 +832,20 @@ frame.pop() finalize_block_ctx(interp, s_block_ctx, frame.w_self()) -@expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, object], +@expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list], no_result=True) -def func(interp, w_block_ctx, w_args): +def func(interp, w_block_ctx, args_w): assert isinstance(w_block_ctx, model.W_PointersObject) s_block_ctx = w_block_ctx.as_blockcontext_get_shadow(interp.space) exp_arg_cnt = s_block_ctx.expected_argument_count() - # Check that our arguments have pointers format and the right size: - if not w_args.getclass(interp.space).is_same_object( - interp.space.w_Array): - raise PrimitiveFailedError() - if w_args.size() != exp_arg_cnt: + if len(args_w) != exp_arg_cnt: raise PrimitiveFailedError() - assert isinstance(w_args, model.W_PointersObject) # Push all the items from the array for i in range(exp_arg_cnt): - s_block_ctx.push(w_args.at0(interp.space, i)) + s_block_ctx.push(args_w[i]) # XXX Check original logic. Image does not test this anyway # because falls back to value + internal implementation @@ -913,6 +911,80 @@ return w_rcvr # ___________________________________________________________________________ +# BlockClosure Primitives + +CLOSURE_COPY_WITH_COPIED_VALUES = 200 +CLOSURE_VALUE = 201 +CLOSURE_VALUE_ = 202 +CLOSURE_VALUE_VALUE = 203 +CLOSURE_VALUE_VALUE_VALUE = 204 +CLOSURE_VALUE_VALUE_VALUE_VALUE = 205 +CLOSURE_VALUE_WITH_ARGS = 206 #valueWithArguments: +CLOSURE_VALUE_NO_CONTEXT_SWITCH = 221 +CLOSURE_VALUE_NO_CONTEXT_SWITCH_ = 222 + +@expose_primitive(CLOSURE_COPY_WITH_COPIED_VALUES, unwrap_spec=[object, int, list]) +def func(interp, outerContext, numArgs, copiedValues): + frame = interp.s_active_context() + w_context, s_context = interp.space.newClosure(outerContext, frame.pc(), + numArgs, copiedValues) + frame.push(w_context) + + +def activateClosure(w_block_closure, args_w, mayContextSwitch=True): + if not w_block_closure.getclass(interp.space).is_same_object( + interp.space.w_BlockClosure): + raise PrimitiveFailedError() + if not w_block_closure.numArgs == len(args_w): + raise PrimitiveFailedError() + if not w_block_closure.outerContext.getclass(interp.space).issubclass( + interp.space.w_ContextPart): + raise PrimitiveFailedError() + w_closureMethod = w_block_closure.w_method() + assert isinstance(w_closureMethod, W_CompiledMethod) + assert w_block_closure is not w_block_closure.outerContext + numCopied = w_block_closure.size() + + s_block_closure = w_block_closure.as_blockclosure_get_shadow(interp.space) + s_block_closure.push_all(args_w) + + s_block_closure.store_pc(s_block_closure.initialip()) + s_block_closure.store_w_sender(frame) + + +@expose_primitive(CLOSURE_VALUE, unwrap_spec=[object]) +def func(interp, w_block_closure): + activateClosure(w_block_closure, []) + +@expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object]) +def func(interp, w_block_closure, w_a0): + activateClosure(w_block_closure, [w_a0]) + +@expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1): + activateClosure(w_block_closure, [w_a0, w_a1]) + +@expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1, w_a2): + activateClosure(w_block_closure, [w_a0, w_a1, w_a2]) + +@expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): + activateClosure(w_block_closure, [w_a0, w_a1, w_a2, w_a3]) + +@expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) +def func(interp, w_block_closure, args_w): + activateClosure(w_block_closure, args_w) + +@expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object]) +def func(interp, w_block_closure): + activateClosure(w_block_closure, [], mayContextSwitch=False) + +@expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object]) +def func(interp, w_block_closure, w_a0): + activateClosure(w_block_closure, [w_a0], mayContextSwitch=False) + +# ___________________________________________________________________________ # PrimitiveLoadInstVar # # These are some wacky bytecodes in squeak. They are defined to do 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 @@ -831,7 +831,7 @@ option.bc_trace = bc_trace # Closure Bytecodes -def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray): +def test_bc_pushNewArrayBytecode(bytecode=pushNewArrayBytecode): interp = new_interpreter(bytecode + chr(0x83)) context = interp.s_active_context() context.push(fakeliterals(space, "egg")) @@ -843,7 +843,7 @@ assert array.at0(space, 1) == fakeliterals(space, "bar") assert array.at0(space, 2) == fakeliterals(space, "baz") -def test_bc_pushNewArray(bytecode=pushNewArrayPopIntoArray): +def test_bc_pushNewArray(bytecode=pushNewArrayBytecode): interp = new_interpreter(bytecode + chr(0x07)) context = interp.s_active_context() interp.step(interp.s_active_context()) @@ -851,7 +851,7 @@ assert array.size() == 7 assert array.at0(space, 0) == space.w_nil -def test_pushTempAt0InTempVectorAt0(bytecode = pushTempAtInTempVectorAt): +def test_bc_pushRemoteTempLongBytecode(bytecode = pushRemoteTempLongBytecode): interp = new_interpreter(bytecode + chr(0) + chr(0)) context = interp.s_active_context() context.push(fakeliterals(space, "jam")) @@ -871,21 +871,21 @@ interp.step(context) return context, temp_array -def test_pushTempAt3InTempVectorAt1(bytecode = pushTempAtInTempVectorAt): +def test_bc_pushRemoteTempLongBytecode2(bytecode = pushRemoteTempLongBytecode): context, _ = setupTempArrayAndContext(bytecode) assert context.top() == fakeliterals(space, "pub") -def test_storeTempAtInTempVectorAt(bytecode = storeTempAtInTempVectorAt): +def test_bc_storeRemoteTempLongBytecode(bytecode = storeRemoteTempLongBytecode): context, temp_array = setupTempArrayAndContext(bytecode) assert context.top() == fakeliterals(space, "bar") assert temp_array.at0(space, 2) == fakeliterals(space, "bar") -def test_popAndStoreTempAtInTempVectorAt(bytecode = popAndStoreTempAtInTempVectorAt): +def test_bc_storeAndPopRemoteTempLongBytecode(bytecode = storeAndPopRemoteTempLongBytecode): context, temp_array = setupTempArrayAndContext(bytecode) assert temp_array.at0(space, 2) == fakeliterals(space, "bar") assert context.top() == fakeliterals(space, "english") -def test_pushClosureNumCopied0NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): +def test_bc_pushClosureCopyCopied0ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): for i in (0, 0xF0, 0x0FF0, 0xFFF0): interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) context = interp.s_active_context() @@ -897,7 +897,7 @@ assert closure.startpc() == pc + 4 assert closure.outerContext() is context._w_self -def test_pushClosureNumCopied2NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): +def test_bc_pushClosureCopyCopied2ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): interp = new_interpreter(bytecode + chr(0x23) + chr(0) + chr(0)) context = interp.s_active_context() context.push("english") diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -30,6 +30,7 @@ if isinstance(x, model.W_Object): return x if isinstance(x, str) and len(x) == 1: return space.wrap_char(x) if isinstance(x, str): return space.wrap_string(x) + if isinstance(x, list): return space.wrap_list(x) raise NotImplementedError def mock(stack): diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -22,5 +22,3 @@ Shadows: [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes -Lars ToDo -[ ] different image with BlockClosure instead of BlockContext _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit