Author: Carl Friedrich Bolz <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit