[pypy-commit] pypy py3k: braindump + move anto's old TODO, minus a couple finished things, here too

2013-05-03 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r63844:608621b8c9bb
Date: 2013-05-03 19:12 -0700
http://bitbucket.org/pypy/pypy/changeset/608621b8c9bb/

Log:braindump + move anto's old TODO, minus a couple finished things,
here too

diff --git a/TODO b/TODO
deleted file mode 100644
--- a/TODO
+++ /dev/null
@@ -1,24 +0,0 @@
-kill Exception.message
-
-what to do with the ListRangeStrategy? We also have 
__builtin__.functional.W_Range
-
-run coverage against the parser/astbuilder/astcompiler: it's probably full of
-dead code because the grammar changed
-
-re-enable IntDictStrategy
-
-re-enable StdObjSpace.listview_str
-
-re-enable the kwargs dict strategy in dictmultiobject.py
-re-enable view_as_kwargs
-
-check the "assert rbigint.SHIFT <= 32" in module/_random/interp_random.py,
-which has been commented out for now
-
-unskip numpypy tests in module/test_lib_pypy/numpypy/
-
-optimize W_UnicodeObject, right now it stores both an unicode and an utf8
-version of the same string
-
-re-enable BUILD_LIST_FROM_ARG: see the comment in astcompiler/codegen.py in
-ast.ListComp.build_container
\ No newline at end of file
diff --git a/pypy/TODO b/pypy/TODO
--- a/pypy/TODO
+++ b/pypy/TODO
@@ -6,10 +6,12 @@
It's important to be compatible, since other classes like Decimal
and Fractions have to return the same hashes for equivalent values.
IOW: int.__hash__ is part of the Python language specification.
+   The py3k-newhash branch has an updated float hash, int's hash is
+   still pending
 
 * test_fractions
 * test_numeric_tower
-   float.__hash__ has changed as well.
+   float.__hash__ has changed as well (fixed on py3k-newhash)
 
 * test_float
nan = float('nan');  assert nan in [nan]
@@ -20,7 +22,8 @@
FloatListStrategy.unwrap().
 
 * test_memoryview
-   Needs bytes/str changes. Probably easy.
+   Needs bytes/str changes. Probably easy. Work for this has begun on
+   py3k-memoryview (by mjacob)
 
 * test_peepholer
'a in [1,2,3]' is rewritten as 'a in (1, 2, 3)'
@@ -28,7 +31,9 @@
Likewise, a set becomes a frozenset.
 
 * test_pep263
-   Tracebacks should be able to print unicode source code.
+   Tracebacks should be able to print unicode source code. This is
+   really due to the tokenizer not being fully unicode aware. The
+   parser can somewhat hack around this but maybe not completely
 
 * test_sqlite
(Probably easy) Ports of CPython changeset fc6f90545cb4 and PyPy
@@ -36,6 +41,53 @@
 
 * test_sys
 * test_threading:
-   Missing sys.getswitchinterval().
+   Missing sys.getswitchinterval(). https://bugs.pypy.org/issue1470
We would be interesting to implement the new thread switching
logic, it's a lot of work though.
+
+
+own-tests:
+
+* module/test_lib_pypy
+  These crash the buildbots (via SyntaxErrors): some were really made
+  to run under Python 2.x
+
+* interpreter.test.test_zzpickle_and_slow test_pickle_frame_with_exc
+  Due to W_OperationError not being pickleable. Probably be best for
+  the ExceptionHandlerBlock to push *sys.exc_info() instead of it,
+  like CPython does
+
+* module.bz2.test.test_bz2_file test_open_non_existent
+  Some really obscure GC stuff
+
+* module.cpyext.test.test_structseq test_StructSeq
+  structseq now subclasses tuple on py3, which breaks how
+  BaseCpyTypeDescr.realize allocates it
+
+* module.marshal.test.test_marshal
+  Handling of exceptions w/ bad data? Or is the test wrong?
+
+* objspace.std.test.test_floatobject test_from_string
+  The unicode-based number parsing routines don't raise UnicodeErrors,
+  but more importantly they raise unprintable exceptions
+
+
+antocuni's older TODO:
+
+run coverage against the parser/astbuilder/astcompiler: it's probably full of
+dead code because the grammar changed
+
+re-enable IntDictStrategy
+
+re-enable StdObjSpace.listview_str
+
+re-enable the kwargs dict strategy in dictmultiobject.py
+re-enable view_as_kwargs
+
+unskip numpypy tests in module/test_lib_pypy/numpypy/
+
+optimize W_UnicodeObject, right now it stores both an unicode and an utf8
+version of the same string
+
+re-enable BUILD_LIST_FROM_ARG: see the comment in astcompiler/codegen.py in
+ast.ListComp.build_container
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: kill BaseException's message/__getitem__

2013-05-03 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r63843:ac27970cee54
Date: 2013-05-03 18:46 -0700
http://bitbucket.org/pypy/pypy/changeset/ac27970cee54/

Log:kill BaseException's message/__getitem__

diff --git a/pypy/interpreter/test/test_argument.py 
b/pypy/interpreter/test/test_argument.py
--- a/pypy/interpreter/test/test_argument.py
+++ b/pypy/interpreter/test/test_argument.py
@@ -669,23 +669,23 @@
 class AppTestArgument:
 def test_error_message(self):
 exc = raises(TypeError, (lambda a, b=2: 0), b=3)
-assert exc.value.message == "() takes at least 1 non-keyword 
argument (0 given)"
+assert str(exc.value) == "() takes at least 1 non-keyword 
argument (0 given)"
 exc = raises(TypeError, (lambda: 0), b=3)
-assert exc.value.message == "() takes no arguments (1 given)"
+assert str(exc.value) == "() takes no arguments (1 given)"
 exc = raises(TypeError, (lambda a, b: 0), 1, 2, 3, a=1)
-assert exc.value.message == "() takes exactly 2 arguments (4 
given)"
+assert str(exc.value) == "() takes exactly 2 arguments (4 
given)"
 exc = raises(TypeError, (lambda a, b=1: 0), 1, 2, 3, a=1)
-assert exc.value.message == "() takes at most 2 non-keyword 
arguments (3 given)"
+assert str(exc.value) == "() takes at most 2 non-keyword 
arguments (3 given)"
 exc = raises(TypeError, (lambda a, b=1, **kw: 0), 1, 2, 3)
-assert exc.value.message == "() takes at most 2 non-keyword 
arguments (3 given)"
+assert str(exc.value) == "() takes at most 2 non-keyword 
arguments (3 given)"
 exc = raises(TypeError, (lambda a, b, c=3, **kw: 0), 1)
-assert exc.value.message == "() takes at least 2 arguments (1 
given)"
+assert str(exc.value) == "() takes at least 2 arguments (1 
given)"
 exc = raises(TypeError, (lambda a, b, **kw: 0), 1)
-assert exc.value.message == "() takes exactly 2 non-keyword 
arguments (1 given)"
+assert str(exc.value) == "() takes exactly 2 non-keyword 
arguments (1 given)"
 exc = raises(TypeError, (lambda a, b, c=3, **kw: 0), a=1)
-assert exc.value.message == "() takes at least 2 non-keyword 
arguments (0 given)"
+assert str(exc.value) == "() takes at least 2 non-keyword 
arguments (0 given)"
 exc = raises(TypeError, (lambda a, b, **kw: 0), a=1)
-assert exc.value.message == "() takes exactly 2 non-keyword 
arguments (0 given)"
+assert str(exc.value) == "() takes exactly 2 non-keyword 
arguments (0 given)"
 
 def test_unicode_keywords(self):
 """
diff --git a/pypy/interpreter/test/test_typedef.py 
b/pypy/interpreter/test/test_typedef.py
--- a/pypy/interpreter/test/test_typedef.py
+++ b/pypy/interpreter/test/test_typedef.py
@@ -180,7 +180,7 @@
 self.space.appexec([w_obj], """(obj):
 assert type(obj).__hash__ is None
 err = raises(TypeError, hash, obj)
-assert err.value.message == "'some_type' objects are unhashable"
+assert str(err.value) == "'some_type' objects are unhashable"
 """)
 
 def test_destructor(self):
diff --git a/pypy/module/_ffi/test/test_funcptr.py 
b/pypy/module/_ffi/test/test_funcptr.py
--- a/pypy/module/_ffi/test/test_funcptr.py
+++ b/pypy/module/_ffi/test/test_funcptr.py
@@ -574,7 +574,7 @@
 try:
 pow(2, 3)
 except ValueError as e:
-assert e.message.startswith('Procedure called with')
+assert str(e).startswith('Procedure called with')
 else:
 assert 0, 'test must assert, wrong calling convention'
 
@@ -595,7 +595,7 @@
 try:
 wrong_sleep(10)
 except ValueError as e:
-assert e.message.startswith('Procedure called with')
+assert str(e).startswith('Procedure called with')
 else:
 assert 0, 'test must assert, wrong calling convention'
 
@@ -611,7 +611,7 @@
 try:
 wrong_pow(2, 3) == 8
 except ValueError as e:
-assert e.message.startswith('Procedure called with')
+assert str(e).startswith('Procedure called with')
 else:
 assert 0, 'test must assert, wrong calling convention'
 
diff --git a/pypy/module/_rawffi/test/test__rawffi.py 
b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -883,7 +883,7 @@
 try:
 f()
 except ValueError as e:
-assert "Procedure called with not enough arguments" in e.message
+assert "Procedure called with not enough arguments" in str(e)
 else:
 assert 0, "Did not raise"
 
@@ -894,7 +894,7 @@
 try:
 f(arg)
 except ValueError as e:
-assert "Procedure called with too many arguments" in e.message
+assert "Procedure called with too many arguments" in str(e)
 els

[pypy-commit] pypy py3k: maintain AssertionError.__doc__

2013-05-03 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r63842:5ffc21d95e86
Date: 2013-05-03 18:41 -0700
http://bitbucket.org/pypy/pypy/changeset/5ffc21d95e86/

Log:maintain AssertionError.__doc__

diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py
--- a/pypy/tool/pytest/appsupport.py
+++ b/pypy/tool/pytest/appsupport.py
@@ -184,7 +184,8 @@
 space.wrap('AssertionError'))
 w_metaclass = space.type(w_BuiltinAssertionError)
 w_init = space.wrap(gateway.interp2app_temp(my_init))
-w_dict = space.newdict()
+w_dict = space.getattr(w_BuiltinAssertionError, space.wrap('__dict__'))
+w_dict = space.call_method(w_dict, 'copy')
 space.setitem(w_dict, space.wrap('__init__'), w_init)
 return space.call_function(w_metaclass,
space.wrap('AssertionError'),
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: exceptions is really builtins in appdirect

2013-05-03 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r63841:44741af7e252
Date: 2013-05-03 18:41 -0700
http://bitbucket.org/pypy/pypy/changeset/44741af7e252/

Log:exceptions is really builtins in appdirect

diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py
--- a/pypy/tool/pytest/apptest.py
+++ b/pypy/tool/pytest/apptest.py
@@ -20,7 +20,7 @@
 
 RENAMED_USEMODULES = dict(
 _winreg='winreg',
-exceptions='__exceptions__',
+exceptions='builtins',
 rctime='time',
 struct='_struct',
 thread='_thread',
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Resolve names at decoding time

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63840:d3207d87d828
Date: 2013-05-02 17:04 +0100
http://bitbucket.org/pypy/pypy/changeset/d3207d87d828/

Log:Resolve names at decoding time

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -139,6 +139,8 @@
 
 if opnum in opcode.hasjrel:
 oparg += next_instr
+elif opnum in opcode.hasname:
+oparg = self.names[oparg]
 try:
 op = Opcode.num2op[opnum].decode(oparg, pos, self)
 except KeyError:
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -595,12 +595,6 @@
 def getlocalvarname(self, index):
 return self.pycode.co_varnames[index]
 
-def getname_u(self, index):
-return self.pycode.names[index]
-
-def getname_w(self, index):
-return Constant(self.pycode.names[index])
-
 def BAD_OPCODE(self, _):
 raise FlowingError(self, "This operation is not RPython")
 
@@ -674,17 +668,16 @@
 operror = space.exc_from_raise(w_type, w_value)
 raise operror
 
-def IMPORT_NAME(self, nameindex):
+def IMPORT_NAME(self, modulename):
 space = self.space
-modulename = self.getname_u(nameindex)
 glob = space.unwrap(self.w_globals)
 fromlist = space.unwrap(self.popvalue())
 level = self.popvalue().value
 w_obj = space.import_name(modulename, glob, None, fromlist, level)
 self.pushvalue(w_obj)
 
-def IMPORT_FROM(self, nameindex):
-w_name = self.getname_w(nameindex)
+def IMPORT_FROM(self, name):
+w_name = Constant(name)
 w_module = self.peekvalue()
 self.pushvalue(self.space.import_from(w_module, w_name))
 
@@ -867,15 +860,15 @@
 w_const = self.space.wrap(const)
 self.pushvalue(w_const)
 
-def LOAD_GLOBAL(self, nameindex):
-w_result = self.space.find_global(self.w_globals, 
self.getname_u(nameindex))
+def LOAD_GLOBAL(self, name):
+w_result = self.space.find_global(self.w_globals, name)
 self.pushvalue(w_result)
 LOAD_NAME = LOAD_GLOBAL
 
-def LOAD_ATTR(self, nameindex):
+def LOAD_ATTR(self, name):
 "obj.attributename"
 w_obj = self.popvalue()
-w_attributename = self.getname_w(nameindex)
+w_attributename = Constant(name)
 w_value = self.space.getattr(w_obj, w_attributename)
 self.pushvalue(w_value)
 LOOKUP_METHOD = LOAD_ATTR
@@ -888,8 +881,7 @@
 assert w_newvalue is not None
 self.locals_stack_w[varindex] = w_newvalue
 
-def STORE_GLOBAL(self, nameindex):
-varname = self.getname_u(nameindex)
+def STORE_GLOBAL(self, varname):
 raise FlowingError(self,
 "Attempting to modify global variable  %r." % (varname))
 
@@ -989,9 +981,9 @@
 fn = self.space.newfunction(w_codeobj, self.w_globals, defaults)
 self.pushvalue(fn)
 
-def STORE_ATTR(self, nameindex):
+def STORE_ATTR(self, name):
 "obj.attributename = newvalue"
-w_attributename = self.getname_w(nameindex)
+w_attributename = Constant(name)
 w_obj = self.popvalue()
 w_newvalue = self.popvalue()
 self.space.setattr(w_obj, w_attributename, w_newvalue)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Resolve LOAD_CONST constants at decoding time

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63839:64d1839ad4a4
Date: 2013-05-02 16:02 +0100
http://bitbucket.org/pypy/pypy/changeset/64d1839ad4a4/

Log:Resolve LOAD_CONST constants at decoding time

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -184,5 +184,16 @@
 def register_opcode(cls):
 """Class decorator: register opcode class as real Python opcode"""
 name = cls.__name__
+cls.name = name
 cls.num = Opcode.register_name(name, cls)
 return cls
+
+@register_opcode
+class LOAD_CONST(Opcode):
+def __init__(self, arg, offset=-1):
+self.arg = arg
+self.offset = offset
+
+@staticmethod
+def decode(arg, offset, code):
+return LOAD_CONST(code.consts[arg], offset)
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -595,9 +595,6 @@
 def getlocalvarname(self, index):
 return self.pycode.co_varnames[index]
 
-def getconstant_w(self, index):
-return self.space.wrap(self.pycode.consts[index])
-
 def getname_u(self, index):
 return self.pycode.names[index]
 
@@ -866,8 +863,8 @@
 raise FlowingError(self, "Local variable referenced before 
assignment")
 self.pushvalue(w_value)
 
-def LOAD_CONST(self, constindex):
-w_const = self.getconstant_w(constindex)
+def LOAD_CONST(self, const):
+w_const = self.space.wrap(const)
 self.pushvalue(w_const)
 
 def LOAD_GLOBAL(self, nameindex):
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Decode the bytecode up-front

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63838:b0a33987a874
Date: 2013-04-28 15:02 +0100
http://bitbucket.org/pypy/pypy/changeset/b0a33987a874/

Log:Decode the bytecode up-front

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -52,6 +52,7 @@
 self.co_firstlineno = firstlineno
 self.co_lnotab = lnotab
 self.signature = cpython_code_signature(self)
+self.build_flow()
 
 def disassemble(self):
 contents = []
@@ -69,6 +70,14 @@
 i += 1
 return contents, offsets, jumps
 
+def build_flow(self):
+next_pos = pos = 0
+contents, offsets, jumps = self.disassemble()
+self.contents = zip(offsets, contents)
+self.pos_index = dict((offset, i) for i, offset in enumerate(offsets))
+# add end marker
+self.contents.append((len(self.co_code), None))
+
 
 @classmethod
 def _from_code(cls, code):
@@ -95,10 +104,17 @@
 return self.signature.scope_length()
 
 def read(self, pos):
+i = self.pos_index[pos]
+op = self.contents[i][1]
+next_pos = self.contents[i+1][0]
+return next_pos, op
+
+
+def decode(self, pos):
 """
 Decode the instruction starting at position ``next_instr``.
 
-Returns (next_instr, opname, oparg).
+Returns (next_instr, op).
 """
 co_code = self.co_code
 opnum = ord(co_code[pos])
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Create @register_opcode

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63836:83dc2f3f8201
Date: 2013-05-02 19:09 +0100
http://bitbucket.org/pypy/pypy/changeset/83dc2f3f8201/

Log:Create @register_opcode

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -132,3 +132,21 @@
 
 def eval(self, frame):
 return getattr(frame, self.name)(self.arg)
+
+@classmethod
+def register_name(cls, name, op_class):
+try:
+num = OPNAMES.index(name)
+cls.num2op[num] = op_class
+return num
+except ValueError:
+return -1
+
+def __repr__(self):
+return "%s(%d)" % (self.name, self.arg)
+
+def register_opcode(cls):
+"""Class decorator: register opcode class as real Python opcode"""
+name = cls.__name__
+cls.num = Opcode.register_name(name, cls)
+return cls
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Deal with FSFrame.last_instr a bit more explicitly

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63833:8fcf71337b33
Date: 2013-04-30 15:32 +0100
http://bitbucket.org/pypy/pypy/changeset/8fcf71337b33/

Log:Deal with FSFrame.last_instr a bit more explicitly

diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -424,7 +424,7 @@
 raise BytecodeCorruption("misplaced bytecode - should not return")
 return block.handle(self, unroller)
 
-def getstate(self):
+def getstate(self, next_pos):
 # getfastscope() can return real None, for undefined locals
 data = self.save_locals_stack()
 if self.last_exception is None:
@@ -434,7 +434,7 @@
 data.append(self.last_exception.w_type)
 data.append(self.last_exception.w_value)
 recursively_flatten(self.space, data)
-return FrameState(data, self.blockstack[:], self.last_instr)
+return FrameState(data, self.blockstack[:], next_pos)
 
 def setstate(self, state):
 """ Reset the frame to the given state. """
@@ -446,7 +446,6 @@
 self.last_exception = None
 else:
 self.last_exception = FSException(data[-2], data[-1])
-self.last_instr = state.next_instr
 self.blockstack = state.blocklist[:]
 
 def guessbool(self, w_condition, **kwds):
@@ -490,11 +489,12 @@
 
 def record_block(self, block):
 self.setstate(block.framestate)
+next_pos = block.framestate.next_instr
 self.recorder = block.make_recorder()
 try:
 while True:
-self.last_instr = self.handle_bytecode(self.last_instr)
-self.recorder.final_state = self.getstate()
+next_pos = self.handle_bytecode(next_pos)
+self.recorder.final_state = self.getstate(next_pos)
 
 except ImplicitOperationError, e:
 if isinstance(e.w_type, Constant):
@@ -577,6 +577,7 @@
 def handle_bytecode(self, next_instr):
 next_instr, opcode = self.pycode.read(next_instr)
 try:
+self.last_instr = opcode.offset
 res = opcode.eval(self)
 return res if res is not None else next_instr
 except FSException, operr:
diff --git a/rpython/flowspace/test/test_framestate.py 
b/rpython/flowspace/test/test_framestate.py
--- a/rpython/flowspace/test/test_framestate.py
+++ b/rpython/flowspace/test/test_framestate.py
@@ -25,55 +25,55 @@
 
 def test_eq_framestate(self):
 frame = self.getframe(self.func_simple)
-fs1 = frame.getstate()
-fs2 = frame.getstate()
+fs1 = frame.getstate(0)
+fs2 = frame.getstate(0)
 assert fs1 == fs2
 
 def test_neq_hacked_framestate(self):
 frame = self.getframe(self.func_simple)
-fs1 = frame.getstate()
+fs1 = frame.getstate(0)
 frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
-fs2 = frame.getstate()
+fs2 = frame.getstate(0)
 assert fs1 != fs2
 
 def test_union_on_equal_framestates(self):
 frame = self.getframe(self.func_simple)
-fs1 = frame.getstate()
-fs2 = frame.getstate()
+fs1 = frame.getstate(0)
+fs2 = frame.getstate(0)
 assert fs1.union(fs2) == fs1
 
 def test_union_on_hacked_framestates(self):
 frame = self.getframe(self.func_simple)
-fs1 = frame.getstate()
+fs1 = frame.getstate(0)
 frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
-fs2 = frame.getstate()
+fs2 = frame.getstate(0)
 assert fs1.union(fs2) == fs2  # fs2 is more general
 assert fs2.union(fs1) == fs2  # fs2 is more general
 
 def test_restore_frame(self):
 frame = self.getframe(self.func_simple)
-fs1 = frame.getstate()
+fs1 = frame.getstate(0)
 frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
 frame.setstate(fs1)
-assert fs1 == frame.getstate()
+assert fs1 == frame.getstate(0)
 
 def test_copy(self):
 frame = self.getframe(self.func_simple)
-fs1 = frame.getstate()
+fs1 = frame.getstate(0)
 fs2 = fs1.copy()
 assert fs1 == fs2
 
 def test_getvariables(self):
 frame = self.getframe(self.func_simple)
-fs1 = frame.getstate()
+fs1 = frame.getstate(0)
 vars = fs1.getvariables()
 assert len(vars) == 1
 
 def test_getoutputargs(self):
 frame = self.getframe(self.func_simple)
-fs1 = frame.getstate()
+fs1 = frame.getstate(0)
 frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
-fs2 = frame.getstate()
+fs2 = frame.getstate(0)
 outputargs = fs1.getoutputargs(fs2)
 # 'x' -> 'x' is a Variable
 # locals_w[n-1] -> locals_w[n-1] is Constant(None)
@@ -81,9 +81,9 @@
 
 def test_union_differen

[pypy-commit] pypy Opcode-class: Kill next_instr argument in FSFrame.OPCODE methods

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63832:d27c6cf80457
Date: 2013-04-29 03:03 +0100
http://bitbucket.org/pypy/pypy/changeset/d27c6cf80457/

Log:Kill next_instr argument in FSFrame.OPCODE methods

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -3,6 +3,7 @@
 """
 from rpython.tool.stdlib_opcode import host_bytecode_spec
 from opcode import EXTENDED_ARG, HAVE_ARGUMENT
+import opcode
 from rpython.flowspace.argument import Signature
 from rpython.flowspace.flowcontext import BytecodeCorruption
 
@@ -83,10 +84,10 @@
 Returns (next_instr, opname, oparg).
 """
 co_code = self.co_code
-opcode = ord(co_code[pos])
+opnum = ord(co_code[pos])
 next_instr = pos + 1
 
-if opcode >= HAVE_ARGUMENT:
+if opnum >= HAVE_ARGUMENT:
 lo = ord(co_code[next_instr])
 hi = ord(co_code[next_instr+1])
 next_instr += 2
@@ -94,16 +95,18 @@
 else:
 oparg = 0
 
-while opcode == EXTENDED_ARG:
-opcode = ord(co_code[next_instr])
-if opcode < HAVE_ARGUMENT:
+while opnum == EXTENDED_ARG:
+opnum = ord(co_code[next_instr])
+if opnum < HAVE_ARGUMENT:
 raise BytecodeCorruption
 lo = ord(co_code[next_instr+1])
 hi = ord(co_code[next_instr+2])
 next_instr += 3
 oparg = (oparg * 65536) | (hi * 256) | lo
 
-return next_instr, Opcode(opcode, oparg, pos)
+if opnum in opcode.hasjrel:
+oparg += next_instr
+return next_instr, Opcode(opnum, oparg, pos)
 
 @property
 def is_generator(self):
@@ -117,5 +120,5 @@
 self.arg = arg
 self.offset = offset
 
-def eval(self, frame, next_instr):
-return getattr(frame, self.name)(self.arg, next_instr)
+def eval(self, frame):
+return getattr(frame, self.name)(self.arg)
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -577,7 +577,7 @@
 def handle_bytecode(self, next_instr):
 next_instr, opcode = self.pycode.read(next_instr)
 try:
-res = opcode.eval(self, next_instr)
+res = opcode.eval(self)
 return res if res is not None else next_instr
 except FSException, operr:
 return self.handle_operation_error(operr)
@@ -603,13 +603,13 @@
 def getname_w(self, index):
 return Constant(self.pycode.names[index])
 
-def BAD_OPCODE(self, _, next_instr):
+def BAD_OPCODE(self, _):
 raise FlowingError(self, "This operation is not RPython")
 
-def BREAK_LOOP(self, oparg, next_instr):
+def BREAK_LOOP(self, oparg):
 return self.unrollstack_and_jump(SBreakLoop.singleton)
 
-def CONTINUE_LOOP(self, startofloop, next_instr):
+def CONTINUE_LOOP(self, startofloop):
 unroller = SContinueLoop(startofloop)
 return self.unrollstack_and_jump(unroller)
 
@@ -646,13 +646,13 @@
 def cmp_exc_match(self, w_1, w_2):
 return self.space.newbool(self.space.exception_match(w_1, w_2))
 
-def COMPARE_OP(self, testnum, next_instr):
+def COMPARE_OP(self, testnum):
 w_2 = self.popvalue()
 w_1 = self.popvalue()
 w_result = getattr(self, compare_method[testnum])(w_1, w_2)
 self.pushvalue(w_result)
 
-def RAISE_VARARGS(self, nbargs, next_instr):
+def RAISE_VARARGS(self, nbargs):
 space = self.space
 if nbargs == 0:
 if self.last_exception is not None:
@@ -676,7 +676,7 @@
 operror = space.exc_from_raise(w_type, w_value)
 raise operror
 
-def IMPORT_NAME(self, nameindex, next_instr):
+def IMPORT_NAME(self, nameindex):
 space = self.space
 modulename = self.getname_u(nameindex)
 glob = space.unwrap(self.w_globals)
@@ -685,12 +685,12 @@
 w_obj = space.import_name(modulename, glob, None, fromlist, level)
 self.pushvalue(w_obj)
 
-def IMPORT_FROM(self, nameindex, next_instr):
+def IMPORT_FROM(self, nameindex):
 w_name = self.getname_w(nameindex)
 w_module = self.peekvalue()
 self.pushvalue(self.space.import_from(w_module, w_name))
 
-def RETURN_VALUE(self, oparg, next_instr):
+def RETURN_VALUE(self, oparg):
 w_returnvalue = self.popvalue()
 block = self.unrollstack(SReturnValue.kind)
 if block is None:
@@ -700,7 +700,7 @@
 next_instr = block.handle(self, unroller)
 return next_instr# now inside a 'finally' block
 
-def END_FINALLY(self, oparg, next_instr):
+def END_FINALLY(self, oparg):
 # unlike CPython, there are two statically distinct cases: the
 # END_FINALLY might be closing an 'except' block or a 'finally'
 

[pypy-commit] pypy Opcode-class: Simplify record_block() setup.

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63827:34743f1d56d2
Date: 2013-05-02 04:12 +0100
http://bitbucket.org/pypy/pypy/changeset/34743f1d56d2/

Log:Simplify record_block() setup.

Kill FSFrame.recording() and dispatch its logic to Block methods.

diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -55,25 +55,44 @@
 pass
 
 class SpamBlock(Block):
-# make slots optional, for debugging
-if hasattr(Block, '__slots__'):
-__slots__ = "dead framestate".split()
-
 def __init__(self, framestate):
 Block.__init__(self, framestate.getvariables())
 self.framestate = framestate
 self.dead = False
 
+def make_recorder(self):
+return BlockRecorder(self)
+
 class EggBlock(Block):
-# make slots optional, for debugging
-if hasattr(Block, '__slots__'):
-__slots__ = "prevblock booloutcome last_exception".split()
-
 def __init__(self, inputargs, prevblock, booloutcome):
 Block.__init__(self, inputargs)
 self.prevblock = prevblock
 self.booloutcome = booloutcome
 
+@property
+def ancestor(self):
+parent = self.prevblock
+while isinstance(parent, EggBlock):
+parent = parent.prevblock
+return parent
+
+@property
+def dead(self):
+return self.ancestor.dead
+
+@property
+def framestate(self):
+return self.ancestor.framestate
+
+def make_recorder(self):
+recorder = BlockRecorder(self)
+curr = self
+while isinstance(curr, EggBlock):
+prev = curr.prevblock
+recorder = Replayer(prev, curr.booloutcome, recorder)
+curr = prev
+return recorder
+
 def extravars(self, last_exception=None, last_exc_value=None):
 self.last_exception = last_exception
 
@@ -430,24 +449,6 @@
 self.last_instr = state.next_instr
 self.blockstack = state.blocklist[:]
 
-def recording(self, block):
-""" Setup recording of the block and return the recorder. """
-parentblocks = []
-parent = block
-while isinstance(parent, EggBlock):
-parent = parent.prevblock
-parentblocks.append(parent)
-# parentblocks = [Egg, Egg, ..., Egg, Spam] not including block
-if parent.dead:
-raise StopFlowing
-self.setstate(parent.framestate)
-recorder = BlockRecorder(block)
-prevblock = block
-for parent in parentblocks:
-recorder = Replayer(parent, prevblock.booloutcome, recorder)
-prevblock = parent
-return recorder
-
 def record(self, spaceop):
 """Record an operation into the active block"""
 recorder = self.recorder
@@ -488,11 +489,13 @@
 self.pendingblocks = collections.deque([graph.startblock])
 while self.pendingblocks:
 block = self.pendingblocks.popleft()
-self.record_block(block)
+if not block.dead:
+self.record_block(block)
 
 def record_block(self, block):
+self.setstate(block.framestate)
+self.recorder = block.make_recorder()
 try:
-self.recorder = self.recording(block)
 while True:
 self.last_instr = self.handle_bytecode(self.last_instr)
 self.recorder.final_state = self.getstate()
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Replace unwrap_for_computation() with Constant.foldable()

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63825:75c10594741f
Date: 2013-05-01 16:49 +0100
http://bitbucket.org/pypy/pypy/changeset/75c10594741f/

Log:Replace unwrap_for_computation() with Constant.foldable()

diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py
--- a/rpython/flowspace/model.py
+++ b/rpython/flowspace/model.py
@@ -3,6 +3,7 @@
 #
 # the below object/attribute model evolved from
 # a discussion in Berlin, 4th of october 2003
+import types
 import py
 
 from rpython.tool.uid import uid, Hashable
@@ -261,6 +262,7 @@
 dummyname = 'v'
 namesdict = {dummyname : (dummyname, 0)}
 
+@property
 def name(self):
 _name = self._name
 _nr = self._nr
@@ -270,11 +272,10 @@
 _nr = self._nr = nd[_name][1]
 nd[_name] = (_name, _nr + 1)
 return "%s%d" % (_name, _nr)
-name = property(name)
 
+@property
 def renamed(self):
 return self._name is not self.dummyname
-renamed = property(renamed)
 
 def __init__(self, name=None):
 self._name = self.dummyname
@@ -314,6 +315,9 @@
 self._name = intern(name)
 self._nr = nr
 
+def foldable(self):
+return False
+
 
 class Constant(Hashable):
 __slots__ = ["concretetype"]
@@ -323,6 +327,25 @@
 if concretetype is not None:
 self.concretetype = concretetype
 
+def foldable(self):
+to_check = self.value
+if hasattr(to_check, 'im_self'):
+to_check = to_check.im_self
+if isinstance(to_check, (type, types.ClassType, types.ModuleType)):
+# classes/types/modules are assumed immutable
+return True
+if (hasattr(to_check, '__class__') and
+to_check.__class__.__module__ == '__builtin__'):
+# builtin object
+return True
+# User-created instance
+if hasattr(to_check, '_freeze_'):
+assert to_check._freeze_() is True
+return True
+else:
+# cannot count on it not mutating at runtime!
+return False
+
 
 class UnwrapException(Exception):
 """Attempted to unwrap a Variable."""
diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py
--- a/rpython/flowspace/objspace.py
+++ b/rpython/flowspace/objspace.py
@@ -176,22 +176,6 @@
 else:
 raise TypeError("not wrapped: " + repr(w_obj))
 
-def unwrap_for_computation(self, w_obj):
-obj = self.unwrap(w_obj)
-to_check = obj
-if hasattr(to_check, 'im_self'):
-to_check = to_check.im_self
-if (not isinstance(to_check, (type, types.ClassType, 
types.ModuleType)) and
-# classes/types/modules are assumed immutable
-hasattr(to_check, '__class__') and to_check.__class__.__module__ 
!= '__builtin__'):
-frozen = hasattr(to_check, '_freeze_')
-if frozen:
-assert to_check._freeze_() is True
-else:
-# cannot count on it not mutating at runtime!
-raise UnwrapException
-return obj
-
 def exception_issubclass_w(self, w_cls1, w_cls2):
 return self.is_true(self.issubtype(w_cls1, w_cls2))
 
@@ -291,12 +275,8 @@
 return self.wrap(not self.is_true(w_obj))
 
 def is_true(self, w_obj):
-try:
-obj = self.unwrap_for_computation(w_obj)
-except UnwrapException:
-pass
-else:
-return bool(obj)
+if w_obj.foldable():
+return bool(w_obj.value)
 w_truthvalue = self.frame.do_operation('is_true', w_obj)
 return self.frame.guessbool(w_truthvalue)
 
@@ -343,12 +323,8 @@
 if w_name not in const_w:
 return 
self.frame.do_operation_with_implicit_exceptions('getattr',
 w_obj, w_name)
-try:
-obj = self.unwrap_for_computation(w_obj)
-name = self.unwrap_for_computation(w_name)
-except UnwrapException:
-pass
-else:
+if w_obj.foldable() and w_name.foldable():
+obj, name = w_obj.value, w_name.value
 try:
 result = getattr(obj, name)
 except Exception, e:
@@ -495,14 +471,8 @@
 def generic_operator(self, *args_w):
 assert len(args_w) == arity, name + " got the wrong number of 
arguments"
 args = []
-for w_arg in args_w:
-try:
-arg = self.unwrap_for_computation(w_arg)
-except UnwrapException:
-break
-else:
-args.append(arg)
-else:
+if all(w_arg.foldable() for w_arg in args_w):
+args = [w_arg.value for w_arg in args_w]
 # All arguments are constants: call the operator now
 try:
 result = op(*args)
_

[pypy-commit] pypy Opcode-class: Create HostCode.disassemble()

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63837:62e72859ced3
Date: 2013-05-02 23:24 +0100
http://bitbucket.org/pypy/pypy/changeset/62e72859ced3/

Log:Create HostCode.disassemble()

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -53,6 +53,23 @@
 self.co_lnotab = lnotab
 self.signature = cpython_code_signature(self)
 
+def disassemble(self):
+contents = []
+offsets = []
+jumps = {}
+pos = 0
+i = 0
+while pos < len(self.co_code):
+offsets.append(pos)
+next_pos, op = self.decode(pos)
+contents.append(op)
+if op.has_jump():
+jumps[pos] = op.arg
+pos = next_pos
+i += 1
+return contents, offsets, jumps
+
+
 @classmethod
 def _from_code(cls, code):
 """Initialize the code object from a real (CPython) one.
@@ -142,6 +159,9 @@
 except ValueError:
 return -1
 
+def has_jump(self):
+return self.num in opcode.hasjrel or self.num in opcode.hasjabs
+
 def __repr__(self):
 return "%s(%d)" % (self.name, self.arg)
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Add hook to customize opcode decoding

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63835:a436f69d22e4
Date: 2013-05-02 15:29 +0100
http://bitbucket.org/pypy/pypy/changeset/a436f69d22e4/

Log:Add hook to customize opcode decoding

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -107,7 +107,7 @@
 if opnum in opcode.hasjrel:
 oparg += next_instr
 try:
-op = Opcode.num2op[opnum](oparg, pos)
+op = Opcode.num2op[opnum].decode(oparg, pos, self)
 except KeyError:
 op = Opcode(opnum, oparg, pos)
 return next_instr, op
@@ -126,5 +126,9 @@
 self.arg = arg
 self.offset = offset
 
+@classmethod
+def decode(cls, arg, offset, code):
+return cls(arg, offset)
+
 def eval(self, frame):
 return getattr(frame, self.name)(self.arg)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Implement registration of opcode classes

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63834:612e87240217
Date: 2013-05-02 05:43 +0100
http://bitbucket.org/pypy/pypy/changeset/612e87240217/

Log:Implement registration of opcode classes

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -106,7 +106,11 @@
 
 if opnum in opcode.hasjrel:
 oparg += next_instr
-return next_instr, Opcode(opnum, oparg, pos)
+try:
+op = Opcode.num2op[opnum](oparg, pos)
+except KeyError:
+op = Opcode(opnum, oparg, pos)
+return next_instr, op
 
 @property
 def is_generator(self):
@@ -115,8 +119,10 @@
 OPNAMES = host_bytecode_spec.method_names
 
 class Opcode(object):
+num2op = {}
 def __init__(self, opcode, arg, offset=-1):
 self.name = OPNAMES[opcode]
+self.num = opcode
 self.arg = arg
 self.offset = offset
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Create Opcode class

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63831:3a1519f5a455
Date: 2013-05-02 06:11 +0100
http://bitbucket.org/pypy/pypy/changeset/3a1519f5a455/

Log:Create Opcode class

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -103,9 +103,19 @@
 next_instr += 3
 oparg = (oparg * 65536) | (hi * 256) | lo
 
-opname = self.opnames[opcode]
-return next_instr, opname, oparg
+return next_instr, Opcode(opcode, oparg, pos)
 
 @property
 def is_generator(self):
 return bool(self.co_flags & CO_GENERATOR)
+
+OPNAMES = host_bytecode_spec.method_names
+
+class Opcode(object):
+def __init__(self, opcode, arg, offset=-1):
+self.name = OPNAMES[opcode]
+self.arg = arg
+self.offset = offset
+
+def eval(self, frame, next_instr):
+return getattr(frame, self.name)(self.arg, next_instr)
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -575,9 +575,9 @@
 break
 
 def handle_bytecode(self, next_instr):
-next_instr, methodname, oparg = self.pycode.read(next_instr)
+next_instr, opcode = self.pycode.read(next_instr)
 try:
-res = getattr(self, methodname)(oparg, next_instr)
+res = opcode.eval(self, next_instr)
 return res if res is not None else next_instr
 except FSException, operr:
 return self.handle_operation_error(operr)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Create exc_wrap()

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63830:9a3915380afb
Date: 2013-05-02 18:08 +0100
http://bitbucket.org/pypy/pypy/changeset/9a3915380afb/

Log:Create exc_wrap()

diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -507,11 +507,11 @@
 link = Link([w_type, w_value], self.graph.exceptblock)
 self.recorder.crnt_block.closeblock(link)
 
-except FSException, e:
-if e.w_type is self.space.w_ImportError:
-msg = 'import statement always raises %s' % e
-raise ImportError(msg)
-link = Link([e.w_type, e.w_value], self.graph.exceptblock)
+except FSException as exc:
+if exc.w_type == self.space.w_ImportError:
+msg = 'import statement always raises %s' % exc
+raise exc.w_value.value
+link = Link([exc.w_type, exc.w_value], self.graph.exceptblock)
 self.recorder.crnt_block.closeblock(link)
 
 except StopFlowing:
@@ -663,8 +663,8 @@
 self.last_exception = operr
 raise operr
 else:
-raise FSException(space.w_TypeError,
-space.wrap("raise: no active exception to re-raise"))
+raise space.exc_wrap(TypeError(
+"raise: no active exception to re-raise"))
 
 w_value = space.w_None
 if nbargs >= 3:
diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py
--- a/rpython/flowspace/objspace.py
+++ b/rpython/flowspace/objspace.py
@@ -135,6 +135,11 @@
 raise WrapException
 return Constant(obj)
 
+def exc_wrap(self, exc):
+w_value = self.wrap(exc)
+w_type = self.wrap(type(exc))
+return FSException(w_type, w_value)
+
 def int_w(self, w_obj):
 if isinstance(w_obj, Constant):
 val = w_obj.value
@@ -238,7 +243,7 @@
 else:
 # the only case left here is (inst, None), from a 'raise inst'.
 if not self.is_w(w_arg2, self.w_None):
-raise FSException(self.w_TypeError, self.wrap(
+raise self.exc_wrap(TypeError(
 "instance exception may not have a separate value"))
 w_value = w_arg1
 w_type = self.type(w_value)
@@ -292,7 +297,7 @@
 try:
 v, next_unroller = it.step()
 except IndexError:
-raise FSException(self.w_StopIteration, self.w_None)
+raise self.exc_wrap(StopIteration())
 else:
 frame.replace_in_stack(it, next_unroller)
 return self.wrap(v)
@@ -341,8 +346,8 @@
 def import_name(self, name, glob=None, loc=None, frm=None, level=-1):
 try:
 mod = __import__(name, glob, loc, frm, level)
-except ImportError, e:
-raise FSException(self.w_ImportError, self.wrap(str(e)))
+except ImportError as e:
+raise self.exc_wrap(e)
 return self.wrap(mod)
 
 def import_from(self, w_module, w_name):
@@ -357,8 +362,8 @@
 try:
 return self.wrap(getattr(w_module.value, w_name.value))
 except AttributeError:
-raise FSException(self.w_ImportError,
-self.wrap("cannot import name '%s'" % w_name.value))
+raise self.exc_wrap(ImportError(
+"cannot import name '%s'" % w_name.value))
 
 def call_method(self, w_obj, methname, *arg_w):
 w_meth = self.getattr(w_obj, self.wrap(methname))
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Clean up exc_from_raise()

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63829:33acc1d192dc
Date: 2013-05-02 17:32 +0100
http://bitbucket.org/pypy/pypy/changeset/33acc1d192dc/

Log:Clean up exc_from_raise()

diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py
--- a/rpython/flowspace/objspace.py
+++ b/rpython/flowspace/objspace.py
@@ -216,36 +216,32 @@
 return True
 return False
 
-def exc_from_raise(self, w_type, w_value):
+def exc_from_raise(self, w_arg1, w_arg2):
 """
 Create a wrapped exception from the arguments of a raise statement.
 
 Returns an FSException object whose w_value is an instance of w_type.
 """
-if self.isinstance_w(w_type, self.w_type):
+if self.isinstance_w(w_arg1, self.w_type):
 # this is for all cases of the form (Class, something)
-if self.is_w(w_value, self.w_None):
+if self.is_w(w_arg2, self.w_None):
 # raise Type: we assume we have to instantiate Type
-w_value = self.call_function(w_type)
-w_type = self.type(w_value)
+w_value = self.call_function(w_arg1)
 else:
-w_valuetype = self.type(w_value)
-if self.exception_issubclass_w(w_valuetype, w_type):
+w_valuetype = self.type(w_arg2)
+if self.exception_issubclass_w(w_valuetype, w_arg1):
 # raise Type, Instance: let etype be the exact type of 
value
-w_type = w_valuetype
+w_value = w_arg2
 else:
 # raise Type, X: assume X is the constructor argument
-w_value = self.call_function(w_type, w_value)
-w_type = self.type(w_value)
+w_value = self.call_function(w_arg1, w_arg2)
 else:
 # the only case left here is (inst, None), from a 'raise inst'.
-w_inst = w_type
-w_instclass = self.type(w_inst)
-if not self.is_w(w_value, self.w_None):
+if not self.is_w(w_arg2, self.w_None):
 raise FSException(self.w_TypeError, self.wrap(
 "instance exception may not have a separate value"))
-w_value = w_inst
-w_type = w_instclass
+w_value = w_arg1
+w_type = self.type(w_value)
 return FSException(w_type, w_value)
 
 def unpackiterable(self, w_iterable):
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Merge FSFrame.record() into .do_operation()

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63828:fcd38d092db1
Date: 2013-05-02 04:14 +0100
http://bitbucket.org/pypy/pypy/changeset/fcd38d092db1/

Log:Merge FSFrame.record() into .do_operation()

diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -449,21 +449,17 @@
 self.last_instr = state.next_instr
 self.blockstack = state.blocklist[:]
 
-def record(self, spaceop):
-"""Record an operation into the active block"""
+def guessbool(self, w_condition, **kwds):
+return self.recorder.guessbool(self, w_condition, **kwds)
+
+def do_operation(self, name, *args_w):
 recorder = self.recorder
 if getattr(recorder, 'final_state', None) is not None:
 self.mergeblock(recorder.crnt_block, recorder.final_state)
 raise StopFlowing
-recorder.append(spaceop)
-
-def guessbool(self, w_condition, **kwds):
-return self.recorder.guessbool(self, w_condition, **kwds)
-
-def do_operation(self, name, *args_w):
 spaceop = SpaceOperation(name, args_w, Variable())
 spaceop.offset = self.last_instr
-self.record(spaceop)
+recorder.append(spaceop)
 return spaceop.result
 
 def do_operation_with_implicit_exceptions(self, name, *args_w):
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Extract record_block() from FSFrame.build_flow()

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63826:84404950a8bf
Date: 2013-04-28 16:02 +0100
http://bitbucket.org/pypy/pypy/changeset/84404950a8bf/

Log:Extract record_block() from FSFrame.build_flow()

diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -488,39 +488,42 @@
 self.pendingblocks = collections.deque([graph.startblock])
 while self.pendingblocks:
 block = self.pendingblocks.popleft()
-try:
-self.recorder = self.recording(block)
-while True:
-self.last_instr = self.handle_bytecode(self.last_instr)
-self.recorder.final_state = self.getstate()
+self.record_block(block)
 
-except ImplicitOperationError, e:
-if isinstance(e.w_type, Constant):
-exc_cls = e.w_type.value
-else:
-exc_cls = Exception
-msg = "implicit %s shouldn't occur" % exc_cls.__name__
-w_type = Constant(AssertionError)
-w_value = Constant(AssertionError(msg))
-link = Link([w_type, w_value], graph.exceptblock)
-self.recorder.crnt_block.closeblock(link)
+def record_block(self, block):
+try:
+self.recorder = self.recording(block)
+while True:
+self.last_instr = self.handle_bytecode(self.last_instr)
+self.recorder.final_state = self.getstate()
 
-except FSException, e:
-if e.w_type is self.space.w_ImportError:
-msg = 'import statement always raises %s' % e
-raise ImportError(msg)
-link = Link([e.w_type, e.w_value], graph.exceptblock)
-self.recorder.crnt_block.closeblock(link)
+except ImplicitOperationError, e:
+if isinstance(e.w_type, Constant):
+exc_cls = e.w_type.value
+else:
+exc_cls = Exception
+msg = "implicit %s shouldn't occur" % exc_cls.__name__
+w_type = Constant(AssertionError)
+w_value = Constant(AssertionError(msg))
+link = Link([w_type, w_value], self.graph.exceptblock)
+self.recorder.crnt_block.closeblock(link)
 
-except StopFlowing:
-pass
+except FSException, e:
+if e.w_type is self.space.w_ImportError:
+msg = 'import statement always raises %s' % e
+raise ImportError(msg)
+link = Link([e.w_type, e.w_value], self.graph.exceptblock)
+self.recorder.crnt_block.closeblock(link)
 
-except Return as exc:
-w_result = exc.value
-link = Link([w_result], graph.returnblock)
-self.recorder.crnt_block.closeblock(link)
+except StopFlowing:
+pass
 
-del self.recorder
+except Return as exc:
+w_result = exc.value
+link = Link([w_result], self.graph.returnblock)
+self.recorder.crnt_block.closeblock(link)
+
+self.recorder = None
 
 def mergeblock(self, currentblock, currentstate):
 next_instr = currentstate.next_instr
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy Opcode-class: Simplify flowspace op creation

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63824:cd71cce3a8c8
Date: 2013-04-28 13:37 +0100
http://bitbucket.org/pypy/pypy/changeset/cd71cce3a8c8/

Log:Simplify flowspace op creation

diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py
--- a/rpython/flowspace/objspace.py
+++ b/rpython/flowspace/objspace.py
@@ -462,11 +462,15 @@
 raise FlowingError(self.frame, self.wrap(message))
 return self.wrap(value)
 
+def make_impure_op(name, arity):
+def generic_operator(self, *args_w):
+assert len(args_w) == arity, name + " got the wrong number of 
arguments"
+w_result = self.frame.do_operation_with_implicit_exceptions(name, 
*args_w)
+return w_result
+return generic_operator
+
 def make_op(name, arity):
 """Add function operation to the flow space."""
-if getattr(FlowObjSpace, name, None) is not None:
-return
-
 op = None
 skip = False
 arithmetic = False
@@ -474,11 +478,9 @@
 if (name.startswith('del') or
 name.startswith('set') or
 name.startswith('inplace_')):
-# skip potential mutators
-skip = True
+return make_impure_op(name, arity)
 elif name in ('id', 'hash', 'iter', 'userdel'):
-# skip potential runtime context dependecies
-skip = True
+return make_impure_op(name, arity)
 elif name in ('repr', 'str'):
 rep = getattr(__builtin__, name)
 def op(obj):
@@ -490,54 +492,50 @@
 op = operation.FunctionByName[name]
 arithmetic = (name + '_ovf') in operation.FunctionByName
 
-if not op and not skip:
-raise ValueError("XXX missing operator: %s" % (name,))
-
 def generic_operator(self, *args_w):
 assert len(args_w) == arity, name + " got the wrong number of 
arguments"
-if op:
-args = []
-for w_arg in args_w:
-try:
-arg = self.unwrap_for_computation(w_arg)
-except UnwrapException:
-break
+args = []
+for w_arg in args_w:
+try:
+arg = self.unwrap_for_computation(w_arg)
+except UnwrapException:
+break
+else:
+args.append(arg)
+else:
+# All arguments are constants: call the operator now
+try:
+result = op(*args)
+except Exception, e:
+etype = e.__class__
+msg = "%s%r always raises %s: %s" % (
+name, tuple(args), etype, e)
+raise FlowingError(self.frame, msg)
+else:
+# don't try to constant-fold operations giving a 'long'
+# result.  The result is probably meant to be sent to
+# an intmask(), but the 'long' constant confuses the
+# annotator a lot.
+if arithmetic and type(result) is long:
+pass
+# don't constant-fold getslice on lists, either
+elif name == 'getslice' and type(result) is list:
+pass
+# otherwise, fine
 else:
-args.append(arg)
-else:
-# All arguments are constants: call the operator now
-try:
-result = op(*args)
-except Exception, e:
-etype = e.__class__
-msg = "%s%r always raises %s: %s" % (
-name, tuple(args), etype, e)
-raise FlowingError(self.frame, msg)
-else:
-# don't try to constant-fold operations giving a 'long'
-# result.  The result is probably meant to be sent to
-# an intmask(), but the 'long' constant confuses the
-# annotator a lot.
-if arithmetic and type(result) is long:
+try:
+return self.wrap(result)
+except WrapException:
+# type cannot sanely appear in flow graph,
+# store operation with variable result instead
 pass
-# don't constant-fold getslice on lists, either
-elif name == 'getslice' and type(result) is list:
-pass
-# otherwise, fine
-else:
-try:
-return self.wrap(result)
-except WrapException:
-# type cannot sanely appear in flow graph,
-# store operation with variable result instead
-pass
 w_result = self.frame.do_operation_with_implicit_exceptions(name, 
*args_w)
 return w_result
-
-setattr(FlowObjSpace, name

[pypy-commit] pypy Opcode-class: This branch introduces an Opcode class to deal with decoding bytecode

2013-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: Opcode-class
Changeset: r63823:483f596960d2
Date: 2013-05-04 00:48 +0100
http://bitbucket.org/pypy/pypy/changeset/483f596960d2/

Log:This branch introduces an Opcode class to deal with decoding
bytecode in rpython.flowspace in a more object-oriented way.

___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: My comments about py3k failing tests

2013-05-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3k
Changeset: r63822:634e55c1f144
Date: 2013-05-03 23:49 +0200
http://bitbucket.org/pypy/pypy/changeset/634e55c1f144/

Log:My comments about py3k failing tests

diff --git a/pypy/TODO b/pypy/TODO
--- a/pypy/TODO
+++ b/pypy/TODO
@@ -1,2 +1,41 @@
+TODO for the python3 test suite:
 
-* ARM
+* test_decimal:
+   In py3k, hash(-1) is now -2 (probably as an optimisation, because
+   PyObject_Hash() return -1 on exception).
+   It's important to be compatible, since other classes like Decimal
+   and Fractions have to return the same hashes for equivalent values.
+   IOW: int.__hash__ is part of the Python language specification.
+
+* test_fractions
+* test_numeric_tower
+   float.__hash__ has changed as well.
+
+* test_float
+   nan = float('nan');  assert nan in [nan]
+   This has always been true in CPython, it is now guaranteed that the
+   containers use the "is" operator as an optimization.
+   Difficult in pypy because optimized containers are arrays of
+   unwrapped doubles. A possible solution is to special-case nan in
+   FloatListStrategy.unwrap().
+
+* test_memoryview
+   Needs bytes/str changes. Probably easy.
+
+* test_peepholer
+   'a in [1,2,3]' is rewritten as 'a in (1, 2, 3)'
+   and the tuple is a prebuilt constant.
+   Likewise, a set becomes a frozenset.
+
+* test_pep263
+   Tracebacks should be able to print unicode source code.
+
+* test_sqlite
+   (Probably easy) Ports of CPython changeset fc6f90545cb4 and PyPy
+   48d194e3ac07.
+
+* test_sys
+* test_threading:
+   Missing sys.getswitchinterval().
+   We would be interesting to implement the new thread switching
+   logic, it's a lot of work though.
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: Fix test_compiler: pypy optimizes the code like CPython 3.3,

2013-05-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3k
Changeset: r63820:c277866e4943
Date: 2013-05-03 22:21 +0200
http://bitbucket.org/pypy/pypy/changeset/c277866e4943/

Log:Fix test_compiler: pypy optimizes the code like CPython 3.3, and
stores -0.0 in co_const.

diff --git a/pypy/interpreter/test/test_compiler.py 
b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -717,6 +717,9 @@
 
 class AppTestCompiler:
 
+def setup_class(cls):
+cls.w_runappdirect = cls.space.wrap(cls.runappdirect)
+
 def test_bom_with_future(self):
 s = b'\xef\xbb\xbffrom __future__ import division\nx = 1/2'
 ns = {}
@@ -738,12 +741,15 @@
 assert type(ns['d'][0][0]) is complex
 
 def test_zeros_not_mixed(self):
-import math
+import math, sys
 code = compile("x = -0.0; y = 0.0", "", "exec")
 consts = code.co_consts
-x, y = consts
-assert isinstance(x, float)
-assert math.copysign(1, x) == 1
+if not self.runappdirect or sys.version_info[:2] != (3, 2):
+# Only CPython 3.2 does not store -0.0.
+# PyPy implements 3.3 here.
+x, y, z = consts
+assert isinstance(x, float) and isinstance(y, float)
+assert math.copysign(1, x) != math.copysign(1, y)
 ns = {}
 exec("z1, z2 = 0j, -0j", ns)
 assert math.atan2(ns["z1"].imag, -1.) == math.atan2(0., -1.)
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: PyBytes_FromStringAndSize(NULL, n) was returning a Unicode string!

2013-05-03 Thread amauryfa
Author: Amaury Forgeot d'Arc 
Branch: py3k
Changeset: r63821:e59ac0bca759
Date: 2013-05-03 23:46 +0200
http://bitbucket.org/pypy/pypy/changeset/e59ac0bca759/

Log:PyBytes_FromStringAndSize(NULL, n) was returning a Unicode string!
Test and fix.

diff --git a/pypy/module/cpyext/bytesobject.py 
b/pypy/module/cpyext/bytesobject.py
--- a/pypy/module/cpyext/bytesobject.py
+++ b/pypy/module/cpyext/bytesobject.py
@@ -100,7 +100,7 @@
 """
 py_str = rffi.cast(PyBytesObject, py_obj)
 s = rffi.charpsize2str(py_str.c_buffer, py_str.c_size)
-w_obj = space.wrap(s)
+w_obj = space.wrapbytes(s)
 track_reference(space, py_obj, w_obj)
 return w_obj
 
diff --git a/pypy/module/cpyext/test/test_bytesobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -77,7 +77,7 @@
 ])
 s = module.getbytes()
 assert len(s) == 4
-assert s == 'ab\x00c'
+assert s == b'ab\x00c'
 
 
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] lang-smalltalk default: added may_context_switch to stack frame to enable primitives 221, 222: valueNoContextSwitch(:)

2013-05-03 Thread lwassermann
Author: Lars Wassermann 
Branch: 
Changeset: r372:854e627f1b25
Date: 2013-05-03 20:09 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/854e627f1b25/

Log:added may_context_switch to stack frame to enable primitives 221,
222: valueNoContextSwitch(:)

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -83,9 +83,9 @@
 print "== Switch from: %s to: %s ==" % 
(s_new_context.short_str(0), p.s_new_context.short_str(0))
 s_new_context = p.s_new_context
 
-def c_loop(self, s_context):
+def c_loop(self, s_context, may_context_switch=True):
 old_pc = 0
-if not jit.we_are_jitted():
+if not jit.we_are_jitted() and may_context_switch:
 self.quick_check_for_interrupt(s_context)
 while True:
 pc = s_context.pc()
@@ -118,7 +118,7 @@
 decr_by = int(trace_length // 100)
 return max(decr_by, 1)
 
-def stack_frame(self, s_new_frame):
+def stack_frame(self, s_new_frame, may_context_switch=True):
 if not self._loop:
 return s_new_frame # this test is done to not loop in test,
# but rather step just once where wanted
@@ -127,7 +127,7 @@
 
 self.remaining_stack_depth -= 1
 try:
-retval = self.c_loop(s_new_frame)
+retval = self.c_loop(s_new_frame, may_context_switch)
 finally:
 self.remaining_stack_depth += 1
 return retval
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -51,7 +51,8 @@
 pos_32bit_int = object()
 
 def expose_primitive(code, unwrap_spec=None, no_result=False,
-result_is_new_frame=False, clean_stack=True, 
compiled_method=False):
+result_is_new_frame=False, may_context_switch=True,
+clean_stack=True, compiled_method=False):
 # heuristics to give it a nice name
 name = None
 for key, value in globals().iteritems():
@@ -68,7 +69,7 @@
 
 wrapped = wrap_primitive(
 unwrap_spec=unwrap_spec, no_result=no_result,
-result_is_new_frame=result_is_new_frame,
+result_is_new_frame=result_is_new_frame, 
may_context_switch=may_context_switch,
 clean_stack=clean_stack, compiled_method=compiled_method
 )(func)
 wrapped.func_name = "wrap_prim_" + name
@@ -79,12 +80,14 @@
 
 
 def wrap_primitive(unwrap_spec=None, no_result=False,
-   result_is_new_frame=False, clean_stack=True,
-   compiled_method=False):
+   result_is_new_frame=False, may_context_switch=True,
+   clean_stack=True, compiled_method=False):
 # some serious magic, don't look
 from rpython.rlib.unroll import unrolling_iterable
 
 assert not (no_result and result_is_new_frame)
+assert may_context_switch or result_is_new_frame
+
 # Because methods always have a receiver, an unwrap_spec of [] is a bug
 assert unwrap_spec is None or unwrap_spec
 
@@ -96,7 +99,7 @@
 else:
 w_result = func(interp, s_frame, argument_count_m1)
 if result_is_new_frame:
-return interp.stack_frame(w_result)
+return interp.stack_frame(w_result, may_context_switch)
 if not no_result:
 assert w_result is not None
 s_frame.push(w_result)
@@ -144,7 +147,7 @@
 if clean_stack:
 # happens only if no exception occurs!
 s_frame.pop_n(len_unwrap_spec)
-return interp.stack_frame(s_new_frame)
+return interp.stack_frame(s_new_frame, may_context_switch)
 else:
 w_result = func(interp, s_frame, *args)
 # After calling primitive, reload context-shadow in case it
@@ -1278,8 +1281,7 @@
 return w_context
 
 
-def activateClosure(interp, s_frame, w_block, args_w, mayContextSwitch=True):
-# XXX mayContextSwitch is ignored
+def activateClosure(interp, s_frame, w_block, args_w):
 space = interp.space
 if not w_block.getclass(space).is_same_object(
 space.w_BlockClosure):
@@ -1327,13 +1329,13 @@
 def func(interp, s_frame, w_block_closure, args_w):
 return activateClosure(interp, s_frame, w_block_closure, args_w)
 
-@expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object], 
result_is_new_frame=True)
+@expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object], 
result_is_new_frame=True, may_context_switch=False)
 def func(interp, s_frame, w_block_closure):
-return activateClosure(interp, s_frame, w_block_closure, [], 
mayContextSwitch=False)
+return activateClosure(interp, s_frame, w_block_closure, [])
 
-@expose_primitive(CLOSURE_VALUE_

[pypy-commit] lang-smalltalk default: fixed one of the problems with the last of the four shootout tests used by eliot: renamed highest_priority_process to pop_highest_priority_process to indicate the

2013-05-03 Thread lwassermann
Author: Lars Wassermann 
Branch: 
Changeset: r373:5dddfd278ce6
Date: 2013-05-03 20:11 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/5dddfd278ce6/

Log:fixed one of the problems with the last of the four shootout tests
used by eliot: renamed highest_priority_process to
pop_highest_priority_process to indicate the resulting state changes

diff --git a/spyvm/test/test_wrapper.py b/spyvm/test/test_wrapper.py
--- a/spyvm/test/test_wrapper.py
+++ b/spyvm/test/test_wrapper.py
@@ -216,15 +216,15 @@
 assert semaphore.excess_signals() == 1
 
 def test_highest_priority(self):
-py.test.raises(FatalError, 
wrapper.scheduler(space).highest_priority_process)
+py.test.raises(FatalError, 
wrapper.scheduler(space).pop_highest_priority_process)
 process, old_process = self.make_processes(4, 2, space.w_false)
 process.put_to_sleep()
 old_process.put_to_sleep()
-highest = wrapper.scheduler(space).highest_priority_process()
+highest = wrapper.scheduler(space).pop_highest_priority_process()
 assert highest is process._w_self
-highest = wrapper.scheduler(space).highest_priority_process()
+highest = wrapper.scheduler(space).pop_highest_priority_process()
 assert highest is old_process._w_self
-py.test.raises(FatalError, 
wrapper.scheduler(space).highest_priority_process)
+py.test.raises(FatalError, 
wrapper.scheduler(space).pop_highest_priority_process)
 
 def test_semaphore_wait(self):
 semaphore = new_semaphore()
diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py
--- a/spyvm/wrapper.py
+++ b/spyvm/wrapper.py
@@ -104,7 +104,7 @@
 def suspend(self, w_current_frame):
 if self.is_active_process():
 assert self.my_list().is_same_object(self.space.w_nil)
-w_process = scheduler(self.space).highest_priority_process()
+w_process = scheduler(self.space).pop_highest_priority_process()
 self.store_suspended_context(w_current_frame)
 return ProcessWrapper(self.space, w_process).activate()
 else:
@@ -176,6 +176,18 @@
 
 return ProcessListWrapper(self.space, lists.read(priority))
 
+def pop_highest_priority_process(self):
+w_lists = self.priority_list()
+# Asserts as W_PointersObjectonion in the varnish.
+lists = Wrapper(self.space, w_lists)
+
+for i in range(w_lists.size() - 1, -1, -1):
+process_list = ProcessListWrapper(self.space, lists.read(i))
+if not process_list.is_empty_list():
+return process_list.remove_first_link_of_list()
+
+raise FatalError("Scheduler could not find a runnable process")
+
 def highest_priority_process(self):
 w_lists = self.priority_list()
 # Asserts as W_PointersObjectonion in the varnish.
@@ -184,7 +196,7 @@
 for i in range(w_lists.size() - 1, -1, -1):
 process_list = ProcessListWrapper(self.space, lists.read(i))
 if not process_list.is_empty_list():
-return process_list.remove_first_link_of_list()
+return process_list.first_link()
 
 raise FatalError("Scheduler could not find a runnable process")
 
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -12,6 +12,8 @@
 def _run_benchmark(interp, number, benchmark):
 scheduler = wrapper.scheduler(interp.space)
 w_hpp = scheduler.highest_priority_process()
+if space.unwrap_int(scheduler.active_process().fetch(space, 2)) > 
space.unwrap_int(w_hpp.fetch(space, 2)):
+w_hpp = scheduler.active_process()
 assert isinstance(w_hpp, model.W_PointersObject)
 w_benchmark_proc = model.W_PointersObject(
 interp.space,
@@ -34,7 +36,7 @@
 # third variable is priority
 priority = space.unwrap_int(w_hpp.fetch(space, 2)) / 2 + 1
 # Priorities below 10 are not allowed in newer versions of Squeak.
-priority = max(10, priority)
+priority = max(11, priority)
 w_benchmark_proc.store(space, 2, space.wrap_int(priority))
 
 # make process eligible for scheduling
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] lang-smalltalk default: changed tracing prefixes from words to symbols to alleviate reading

2013-05-03 Thread lwassermann
Author: Lars Wassermann 
Branch: 
Changeset: r370:b080c3949fe4
Date: 2013-05-03 14:48 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/b080c3949fe4/

Log:changed tracing prefixes from words to symbols to alleviate reading

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -347,7 +347,7 @@
 func = primitives.prim_holder.prim_table[code]
 # 
##
 if interp.trace:
-print "%s calling primitive %d \t(in #%s, named #%s)" % (
+print "%s-> primitive %d \t(in #%s, named #%s)" % (
 ' ' * (interp.max_stack_depth - 
interp.remaining_stack_depth),
 code, self.w_method()._likely_methodname, 
w_selector.as_string())
 try:
@@ -411,7 +411,7 @@
 # assert self._stack_ptr == self.tempsize()
 
 if interp.trace:
-print '%sreturning %s' % (interp.padding(), 
return_value.as_repr_string())
+print '%s<- %s' % (interp.padding(), return_value.as_repr_string())
 raise Return(return_value, s_return_to)
 
 def returnReceiver(self, interp, current_bytecode):
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] lang-smalltalk default: merge ci-fix

2013-05-03 Thread lwassermann
Author: Lars Wassermann 
Branch: 
Changeset: r371:66a8f9a4cd9e
Date: 2013-05-03 14:49 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/66a8f9a4cd9e/

Log:merge ci-fix

diff --git a/benchmarks.py b/benchmarks.py
--- a/benchmarks.py
+++ b/benchmarks.py
@@ -214,13 +214,14 @@
 callback=(lambda x: subprocess.Popen(["mv", 
"Squeak-4.10.2.2614-linux_i386", "stackvm"]).wait())
 )
 ],
-arguments=['-vm-display-X11', '-headless', "images/%s.image" % 
SqueakImage, '../benchmarks.st'],
+arguments=['-vm-display-null', "images/%s.image" % SqueakImage, 
'../benchmarks.st'],
 commitid=cogid
 )
 RSqueakVM = Project(
 "lang-smalltalk",
 executables=[
-Executable("targetimageloadingsmalltalk-c", 
"./targetimageloadingsmalltalk-c")
+Executable("rsqueakvm", "./targetimageloadingsmalltalk-c"),
+Executable("rsqueakvm-nojit", "./targetimageloadingsmalltalk-nojit-c")
 ],
 arguments=["images/%s.image" % SqueakImage, '-m', 'runSPyBenchmarks']
 )
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] lang-smalltalk default: ensuring that our artificial benchmark-process is valid in newer Squeak versions

2013-05-03 Thread lwassermann
Author: Lars Wassermann 
Branch: 
Changeset: r368:d058cc407ad5
Date: 2013-05-03 14:32 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/d058cc407ad5/

Log:ensuring that our artificial benchmark-process is valid in newer
Squeak versions

diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -33,6 +33,8 @@
 
 # third variable is priority
 priority = space.unwrap_int(w_hpp.fetch(space, 2)) / 2 + 1
+# Priorities below 10 are not allowed in newer versions of Squeak.
+priority = max(10, priority)
 w_benchmark_proc.store(space, 2, space.wrap_int(priority))
 
 # make process eligible for scheduling
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] lang-smalltalk default: factored out padding from the different tracing code points

2013-05-03 Thread lwassermann
Author: Lars Wassermann 
Branch: 
Changeset: r367:dd37b2932749
Date: 2013-05-03 09:18 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/dd37b2932749/

Log:factored out padding from the different tracing code points

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -184,7 +184,8 @@
 # We do not support external semaphores.
 # In cog, the method to add such a semaphore is only called in GC.
 
-
+def padding(self, symbol=' '):
+return symbol * (self.max_stack_depth - self.remaining_stack_depth)
 
 class ReturnFromTopLevel(Exception):
 def __init__(self, object):
@@ -373,8 +374,7 @@
 
 # 
##
 if interp.trace:
-padding = ' ' * (interp.max_stack_depth - 
interp.remaining_stack_depth)
-print padding + s_frame.short_str(argcount)
+print interp.padding() + s_frame.short_str(argcount)
 
 return interp.stack_frame(s_frame)
 
@@ -397,8 +397,7 @@
 
 # 
##
 if interp.trace:
-padding = '#' * (interp.max_stack_depth - 
interp.remaining_stack_depth)
-print '%s%s missing: #%s' % (padding, s_frame.short_str(0), 
w_selector.as_string())
+print '%s%s missing: #%s' % (interp.padding('#'), 
s_frame.short_str(0), w_selector.as_string())
 if not objectmodel.we_are_translated():
 import pdb; pdb.set_trace()
 
@@ -411,6 +410,8 @@
 # unfortunately, the assert below is not true for some tests
 # assert self._stack_ptr == self.tempsize()
 
+if interp.trace:
+print '%sreturning %s' % (interp.padding(), 
return_value.as_repr_string())
 raise Return(return_value, s_return_to)
 
 def returnReceiver(self, interp, current_bytecode):
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: merge

2013-05-03 Thread fijal
Author: Maciej Fijalkowski 
Branch: 
Changeset: r63819:c16cd00e82ef
Date: 2013-05-03 14:07 +0200
http://bitbucket.org/pypy/pypy/changeset/c16cd00e82ef/

Log:merge

diff --git a/pypy/doc/release-2.0.0.rst b/pypy/doc/release-2.0.0.rst
--- a/pypy/doc/release-2.0.0.rst
+++ b/pypy/doc/release-2.0.0.rst
@@ -3,18 +3,18 @@
 
 
 We're pleased to announce PyPy 2.0. This is a stable release that brings
-swath of bugfixes, small performance improvements and compatibility fixes.
+a swath of bugfixes, small performance improvements and compatibility fixes.
 
 You can download the PyPy 2.0 release here:
 
 http://pypy.org/download.html
 
-Two biggest changes since PyPy 1.9 are:
+The two biggest changes since PyPy 1.9 are:
 
 * stackless is now supported including greenlets, which means eventlet
   and gevent should work (but read below about gevent)
 
-* PyPy now contains a release 0.6 of `cffi`_ as a builtin module, which
+* PyPy now contains release 0.6 of `cffi`_ as a builtin module, which
   is preferred way of calling C from Python that works well on PyPy
 
 .. _`cffi`: http://cffi.readthedocs.org
@@ -37,17 +37,22 @@
 ==
 
 * Stackless including greenlets should work. For gevent, you need to check
-  out `pypycore`_ and use `pypy-hacks`_ branch of gevent.
+  out `pypycore`_ and use the `pypy-hacks`_ branch of gevent.
 
-* cffi is not a module included with PyPy. It's a preferred way of calling
-  C from Python that works on PyPy.
+* cffi is now a module included with PyPy.  (`cffi`_ also exists for
+  CPython; the two versions should be fully compatible.)  It is the
+  preferred way of calling C from Python that works on PyPy.
 
-* Callbacks from C are now JITted, which means XML parsing is much faster
+* Callbacks from C are now JITted, which means XML parsing is much faster.
 
 * A lot of speed improvements in various language corners, most of them small,
-  but speeding up a particular corner a lot
+  but speeding up some particular corners a lot.
 
-* A lot of stability issues fixed
+* The JIT was refactored to emit machine code which manipulates a "frame"
+  that lives on the heap rather than on the stack.  This is what makes
+  Stackless work, and it could bring another future speed-up (not done yet).
+
+* A lot of stability issues fixed.
 
 .. _`pypycore`: https://github.com/gevent-on-pypy/pypycore/
 .. _`pypy-hacks`: https://github.com/schmir/gevent/tree/pypy-hacks
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: shuffle self.finished_helpers - finalizers can be still discovered during

2013-05-03 Thread fijal
Author: Maciej Fijalkowski 
Branch: 
Changeset: r63818:61f249b5cc08
Date: 2013-05-03 14:07 +0200
http://bitbucket.org/pypy/pypy/changeset/61f249b5cc08/

Log:shuffle self.finished_helpers - finalizers can be still discovered
during finish_rtype

diff --git a/rpython/memory/gctransform/transform.py 
b/rpython/memory/gctransform/transform.py
--- a/rpython/memory/gctransform/transform.py
+++ b/rpython/memory/gctransform/transform.py
@@ -281,11 +281,11 @@
 def finish_helpers(self, backendopt=True):
 if self.translator is not None:
 self.mixlevelannotator.finish_annotate()
-self.finished_helpers = True
 if self.translator is not None:
 self.mixlevelannotator.finish_rtype()
 if backendopt:
 self.mixlevelannotator.backend_optimize()
+self.finished_helpers = True
 # Make sure that the database also sees all finalizers now.
 # It is likely that the finalizers need special support there
 newgcdependencies = self.ll_finalizers_ptrs
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] lang-smalltalk default: add nojit vm, rename targetimageloadingsmalltalk(-nojit)-c to rsqueakvm(-nojit)

2013-05-03 Thread timfel
Author: Tim Felgentreff 
Branch: 
Changeset: r365:31e9905ba200
Date: 2013-05-03 13:34 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/31e9905ba200/

Log:add nojit vm, rename targetimageloadingsmalltalk(-nojit)-c to
rsqueakvm(-nojit)

diff --git a/benchmarks.py b/benchmarks.py
--- a/benchmarks.py
+++ b/benchmarks.py
@@ -208,7 +208,8 @@
 RSqueakVM = Project(
 "lang-smalltalk",
 executables=[
-Executable("targetimageloadingsmalltalk-c", 
"./targetimageloadingsmalltalk-c")
+Executable("rsqueakvm", "./targetimageloadingsmalltalk-c"),
+Executable("rsqueakvm-nojit", "./targetimageloadingsmalltalk-nojit-c")
 ],
 arguments=["images/%s.image" % SqueakImage, '-m', 'runSPyBenchmarks']
 )
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] lang-smalltalk default: merge default

2013-05-03 Thread timfel
Author: Tim Felgentreff 
Branch: 
Changeset: r366:daca802d08e8
Date: 2013-05-03 13:36 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/daca802d08e8/

Log:merge default

diff --git a/benchmarks.py b/benchmarks.py
--- a/benchmarks.py
+++ b/benchmarks.py
@@ -30,13 +30,19 @@
 benchmarks = output.split('\n')
 for s in benchmarks:
 if ';' in s:
-name, time = s.split(';')
-self.add(executable, name, time)
+results = s.split(';')
+if len(results) == 2:
+self.add(executable, *results)
+elif len(results) == 4:
+self.add(executble, *results)
 
-def add(self, executable, benchmark, result):
+def add(self, executable, benchmark, result, min=None, max=None):
 print "Saving result %s for executable %s, benchmark %s" % (
 result, executable, benchmark)
-data = self.build_data(executable, benchmark, result)
+if min is max is None:
+data = self.build_data(executable, benchmark, result)
+else:
+data = self.build_extended_data(executable, benchmark, result, 
min, max)
 params = urllib.urlencode(data)
 response = "None"
 print "Saving result for executable %s, revision %s, benchmark %s" % (
@@ -89,7 +95,13 @@
 # 'max': 4001.6, # Optional. Default is blank
 # 'min': 3995.1, # Optional. Default is blank
 # }
-
+def build_data_extended(self, executable, benchmark, result, min, max):
+return dict(self.build_data(executable, benchmark, result),
+**{
+'min': str(min),
+'max': str(max)
+}
+)
 
 class Archive(object):
 def __init__(self, filename, target, func):
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] lang-smalltalk default: fix benchmark script for stackvm

2013-05-03 Thread timfel
Author: Tim Felgentreff 
Branch: 
Changeset: r364:8d2fabd0a163
Date: 2013-05-03 13:25 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/8d2fabd0a163/

Log:fix benchmark script for stackvm

diff --git a/benchmarks.py b/benchmarks.py
--- a/benchmarks.py
+++ b/benchmarks.py
@@ -202,7 +202,7 @@
 callback=(lambda x: subprocess.Popen(["mv", 
"Squeak-4.10.2.2614-linux_i386", "stackvm"]).wait())
 )
 ],
-arguments=['-vm-display-X11', '-headless', "images/%s.image" % 
SqueakImage, '../benchmarks.st'],
+arguments=['-vm-display-null', "images/%s.image" % SqueakImage, 
'../benchmarks.st'],
 commitid=cogid
 )
 RSqueakVM = Project(
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Small additions and typos.

2013-05-03 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r63817:d1d797def730
Date: 2013-05-03 11:43 +0200
http://bitbucket.org/pypy/pypy/changeset/d1d797def730/

Log:Small additions and typos.

diff --git a/pypy/doc/release-2.0.0.rst b/pypy/doc/release-2.0.0.rst
--- a/pypy/doc/release-2.0.0.rst
+++ b/pypy/doc/release-2.0.0.rst
@@ -3,18 +3,18 @@
 
 
 We're pleased to announce PyPy 2.0. This is a stable release that brings
-swath of bugfixes, small performance improvements and compatibility fixes.
+a swath of bugfixes, small performance improvements and compatibility fixes.
 
 You can download the PyPy 2.0 release here:
 
 http://pypy.org/download.html
 
-Two biggest changes since PyPy 1.9 are:
+The two biggest changes since PyPy 1.9 are:
 
 * stackless is now supported including greenlets, which means eventlet
   and gevent should work (but read below about gevent)
 
-* PyPy now contains a release 0.6 of `cffi`_ as a builtin module, which
+* PyPy now contains release 0.6 of `cffi`_ as a builtin module, which
   is preferred way of calling C from Python that works well on PyPy
 
 .. _`cffi`: http://cffi.readthedocs.org
@@ -37,17 +37,22 @@
 ==
 
 * Stackless including greenlets should work. For gevent, you need to check
-  out `pypycore`_ and use `pypy-hacks`_ branch of gevent.
+  out `pypycore`_ and use the `pypy-hacks`_ branch of gevent.
 
-* cffi is not a module included with PyPy. It's a preferred way of calling
-  C from Python that works on PyPy.
+* cffi is now a module included with PyPy.  (`cffi`_ also exists for
+  CPython; the two versions should be fully compatible.)  It is the
+  preferred way of calling C from Python that works on PyPy.
 
-* Callbacks from C are now JITted, which means XML parsing is much faster
+* Callbacks from C are now JITted, which means XML parsing is much faster.
 
 * A lot of speed improvements in various language corners, most of them small,
-  but speeding up a particular corner a lot
+  but speeding up some particular corners a lot.
 
-* A lot of stability issues fixed
+* The JIT was refactored to emit machine code which manipulates a "frame"
+  that lives on the heap rather than on the stack.  This is what makes
+  Stackless work, and it could bring another future speed-up (not done yet).
+
+* A lot of stability issues fixed.
 
 .. _`pypycore`: https://github.com/gevent-on-pypy/pypycore/
 .. _`pypy-hacks`: https://github.com/schmir/gevent/tree/pypy-hacks
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy release-2.0.x: Release announcement

2013-05-03 Thread fijal
Author: Maciej Fijalkowski 
Branch: release-2.0.x
Changeset: r63816:8c3f07eb25d0
Date: 2013-05-03 11:23 +0200
http://bitbucket.org/pypy/pypy/changeset/8c3f07eb25d0/

Log:Release announcement

diff --git a/pypy/doc/release-2.0.0.rst b/pypy/doc/release-2.0.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-2.0.0.rst
@@ -0,0 +1,56 @@
+
+PyPy 2.0 - Einstein Sandwich
+
+
+We're pleased to announce PyPy 2.0. This is a stable release that brings
+swath of bugfixes, small performance improvements and compatibility fixes.
+
+You can download the PyPy 2.0 release here:
+
+http://pypy.org/download.html
+
+Two biggest changes since PyPy 1.9 are:
+
+* stackless is now supported including greenlets, which means eventlet
+  and gevent should work (but read below about gevent)
+
+* PyPy now contains a release 0.6 of `cffi`_ as a builtin module, which
+  is preferred way of calling C from Python that works well on PyPy
+
+.. _`cffi`: http://cffi.readthedocs.org
+
+What is PyPy?
+=
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy 2.0 and cpython 2.7.3`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 64 or
+Windows 32.  Windows 64 work is still stalling, we would welcome a volunteer
+to handle that. ARM support is on the way and we're expecting to release
+an alpha ARM version shortly.
+
+.. _`pypy 2.0 and cpython 2.7.3`: http://speed.pypy.org
+
+Highlights
+==
+
+* Stackless including greenlets should work. For gevent, you need to check
+  out `pypycore`_ and use `pypy-hacks`_ branch of gevent.
+
+* cffi is not a module included with PyPy. It's a preferred way of calling
+  C from Python that works on PyPy.
+
+* Callbacks from C are now JITted, which means XML parsing is much faster
+
+* A lot of speed improvements in various language corners, most of them small,
+  but speeding up a particular corner a lot
+
+* A lot of stability issues fixed
+
+.. _`pypycore`: https://github.com/gevent-on-pypy/pypycore/
+.. _`pypy-hacks`: https://github.com/schmir/gevent/tree/pypy-hacks
+
+Cheers,
+fijal, arigo and the PyPy team
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -5,4 +5,3 @@
 .. this is a revision shortly after release-2.0
 .. startrev: a13c07067613
 
-
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Release announcement

2013-05-03 Thread fijal
Author: Maciej Fijalkowski 
Branch: 
Changeset: r63815:73c218764043
Date: 2013-05-03 11:23 +0200
http://bitbucket.org/pypy/pypy/changeset/73c218764043/

Log:Release announcement

diff --git a/pypy/doc/release-2.0.0.rst b/pypy/doc/release-2.0.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-2.0.0.rst
@@ -0,0 +1,56 @@
+
+PyPy 2.0 - Einstein Sandwich
+
+
+We're pleased to announce PyPy 2.0. This is a stable release that brings
+swath of bugfixes, small performance improvements and compatibility fixes.
+
+You can download the PyPy 2.0 release here:
+
+http://pypy.org/download.html
+
+Two biggest changes since PyPy 1.9 are:
+
+* stackless is now supported including greenlets, which means eventlet
+  and gevent should work (but read below about gevent)
+
+* PyPy now contains a release 0.6 of `cffi`_ as a builtin module, which
+  is preferred way of calling C from Python that works well on PyPy
+
+.. _`cffi`: http://cffi.readthedocs.org
+
+What is PyPy?
+=
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy 2.0 and cpython 2.7.3`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 64 or
+Windows 32.  Windows 64 work is still stalling, we would welcome a volunteer
+to handle that. ARM support is on the way and we're expecting to release
+an alpha ARM version shortly.
+
+.. _`pypy 2.0 and cpython 2.7.3`: http://speed.pypy.org
+
+Highlights
+==
+
+* Stackless including greenlets should work. For gevent, you need to check
+  out `pypycore`_ and use `pypy-hacks`_ branch of gevent.
+
+* cffi is not a module included with PyPy. It's a preferred way of calling
+  C from Python that works on PyPy.
+
+* Callbacks from C are now JITted, which means XML parsing is much faster
+
+* A lot of speed improvements in various language corners, most of them small,
+  but speeding up a particular corner a lot
+
+* A lot of stability issues fixed
+
+.. _`pypycore`: https://github.com/gevent-on-pypy/pypycore/
+.. _`pypy-hacks`: https://github.com/schmir/gevent/tree/pypy-hacks
+
+Cheers,
+fijal, arigo and the PyPy team
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -5,4 +5,3 @@
 .. this is a revision shortly after release-2.0
 .. startrev: a13c07067613
 
-
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit