churchyard pushed to pypy3 (f22). "Merge with pypy + package review (#1215732) history"

notifications at fedoraproject.org notifications at fedoraproject.org
Sun May 10 19:33:28 UTC 2015


From e7601b33d2a63eb288a8796d6cbe42b692bf1079 Mon Sep 17 00:00:00 2001
From: Fedora Release Engineering <rel-eng at lists.fedoraproject.org>
Date: Mon, 3 Jan 2011 19:50:05 +0000
Subject: Initial setup of the repo


diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/sources b/sources
new file mode 100644
index 0000000..e69de29
-- 
cgit v0.10.2


From f756cfcb34f7e48db6afaf04f79ca5c576a4b696 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Mon, 3 Jan 2011 15:06:28 -0500
Subject: Initial import of pypy-1.4.1-3 from package review (rhbz#588941)


diff --git a/.gitignore b/.gitignore
index e69de29..2878978 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/pypy-1.4.1-src.tar.bz2
diff --git a/fix-test_commands-expected-ls-output-issue7108.patch b/fix-test_commands-expected-ls-output-issue7108.patch
new file mode 100644
index 0000000..becc3e0
--- /dev/null
+++ b/fix-test_commands-expected-ls-output-issue7108.patch
@@ -0,0 +1,11 @@
+--- test/test_commands.py.orig	2010-12-22 13:25:11.357333216 -0500
++++ test/test_commands.py	2010-12-22 13:25:57.927166219 -0500
+@@ -47,7 +47,7 @@ class CommandTests(unittest.TestCase):
+         # Note that the first case above has a space in the group name
+         # while the second one has a space in both names.
+         pat = r'''d.........   # It is a directory.
+-                  \+?          # It may have ACLs.
++                  [.+@]?       # It may have alt access (SELinux, ACLs or metadata ('@' OS X).
+                   \s+\d+       # It has some number of links.
+                   [^/]*        # Skip user, group, size, and date.
+                   /\.          # and end with the name of the file.
diff --git a/pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch b/pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
new file mode 100644
index 0000000..257f60f
--- /dev/null
+++ b/pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
@@ -0,0 +1,13 @@
+diff --git a/pypy/tool/ansi_print.py b/pypy/tool/ansi_print.py
+index 3eff27c..fac4ba2 100644
+--- a/pypy/tool/ansi_print.py
++++ b/pypy/tool/ansi_print.py
+@@ -25,7 +25,7 @@ class AnsiLog:
+         self.kw_to_color = self.KW_TO_COLOR.copy()
+         self.kw_to_color.update(kw_to_color)
+         self.file = file
+-        self.fancy = True
++        self.fancy = False
+         self.isatty = getattr(sys.stderr, 'isatty', lambda: False)
+         if self.fancy and self.isatty(): 
+             self.mandelbrot_driver = Driver()
diff --git a/pypy-1.4-config.patch b/pypy-1.4-config.patch
new file mode 100644
index 0000000..0b82ac8
--- /dev/null
+++ b/pypy-1.4-config.patch
@@ -0,0 +1,44 @@
+Index: pypy-1.4/pypy/translator/platform/linux.py
+===================================================================
+--- pypy-1.4.orig/pypy/translator/platform/linux.py
++++ pypy-1.4/pypy/translator/platform/linux.py
+@@ -3,17 +3,22 @@ import py, os
+ from pypy.translator.platform import _run_subprocess
+ from pypy.translator.platform.posix import BasePosix
+ 
++CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
++          '-Wall', '-Wno-unused']
++if os.environ.get('CFLAGS', None):
++    CFLAGS.extend(os.environ['CFLAGS'].split())
++CFLAGS = tuple(CFLAGS)
++
+ class BaseLinux(BasePosix):
+     name = "linux"
+     
+     link_flags = ('-pthread', '-lrt')
+-    cflags = ('-O3', '-pthread', '-fomit-frame-pointer',
+-              '-Wall', '-Wno-unused')
++    cflags = CFLAGS
+     standalone_only = ()
+     shared_only = ('-fPIC',)
+     so_ext = 'so'
+     so_prefixes = ('lib', '')
+-    
++
+     def _args_for_shared(self, args):
+         return ['-shared'] + args
+ 
+@@ -29,9 +34,10 @@ class BaseLinux(BasePosix):
+ class Linux(BaseLinux):
+     shared_only = ()    # it seems that on 32-bit linux, compiling with -fPIC
+                         # gives assembler that asmgcc is not happy about.
+-    def library_dirs_for_libffi_a(self):
+-        # places where we need to look for libffi.a
+-        return self.library_dirs_for_libffi() + ['/usr/lib']
++    # Fedora Linux, at least, has the shared version but not the static
++    #def library_dirs_for_libffi_a(self):
++    #    # places where we need to look for libffi.a
++    #    return self.library_dirs_for_libffi() + ['/usr/lib']
+ 
+ 
+ class Linux64(BaseLinux):
diff --git a/pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch b/pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
new file mode 100644
index 0000000..93bcb69
--- /dev/null
+++ b/pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
@@ -0,0 +1,16 @@
+diff -r cd083843b67a pypy/translator/goal/app_main.py
+--- a/pypy/translator/goal/app_main.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/goal/app_main.py	Wed Dec 22 17:43:21 2010 -0500
+@@ -191,6 +191,12 @@
+     IS_WINDOWS = False
+ 
+ def get_library_path(executable):
++    # FIXME: get this from translator configuration
++    dirname = LIBRARY_INSTALLATION_PATH
++    newpath = sys.pypy_initial_path(dirname)
++    if newpath:
++        return newpath
++    
+     search = executable
+     while 1:
+         dirname = resolvedirof(search)
diff --git a/pypy.spec b/pypy.spec
new file mode 100644
index 0000000..96354e2
--- /dev/null
+++ b/pypy.spec
@@ -0,0 +1,762 @@
+Name:           pypy
+Version:        1.4.1
+Release:        3%{?dist}
+Summary:        Python implementation with a Just-In-Time compiler
+
+Group:          Development/Languages
+# LGPL and another free license we'd need to ask spot about are present in some
+# java jars that we're not building with atm (in fact, we're deleting them
+# before building).  If we restore those we'll have to work out the new
+# licensing terms
+License:        MIT and Python and UCD
+URL:            http://pypy.org/
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+# High-level configuration of the build:
+
+# PyPy consists of an implementation of an interpreter (with JIT compilation)
+# for the full Python language  written in a high-level language, leaving many
+# of the implementation details as "pluggable" policies.
+#
+# The implementation language is then compiled down to .c code, from which we
+# obtain a binary.
+#
+# This allows us to build a near-arbitrary collection of different
+# implementations of Python with differing tradeoffs
+#
+# (As it happens, the implementation language is itself Python, albeit a
+# restricted subset "RPython", chosen to making it amenable to being compiled.
+# The result implements the full Python language though)
+
+# We could build many different implementations of Python.
+# For now, let's focus on the implementation that appears to be receiving the
+# most attention upstream: the JIT-enabled build, with all standard
+# optimizations
+
+# Building a configuration can take significant time:
+
+# A build of pypy (with jit) on i686 took 77 mins:
+#  [Timer] Timings:
+#  [Timer] annotate                       ---  583.3 s
+#  [Timer] rtype_lltype                   ---  760.9 s
+#  [Timer] pyjitpl_lltype                 ---  567.3 s
+#  [Timer] backendopt_lltype              ---  375.6 s
+#  [Timer] stackcheckinsertion_lltype     ---   54.1 s
+#  [Timer] database_c                     ---  852.2 s
+#  [Timer] source_c                       --- 1007.3 s
+#  [Timer] compile_c                      ---  419.9 s
+#  [Timer] ===========================================
+#  [Timer] Total:                         --- 4620.5 s
+#
+# A build of pypy (nojit) on x86_64 took about an hour:
+#  [Timer] Timings:
+#  [Timer] annotate                       ---  537.5 s
+#  [Timer] rtype_lltype                   ---  667.3 s
+#  [Timer] backendopt_lltype              ---  385.4 s
+#  [Timer] stackcheckinsertion_lltype     ---   42.5 s
+#  [Timer] database_c                     ---  625.3 s
+#  [Timer] source_c                       --- 1040.2 s
+#  [Timer] compile_c                      ---  273.9 s
+#  [Timer] ===========================================
+#  [Timer] Total:                         --- 3572.0 s
+#
+#
+# A build of pypy-stackless on i686 took about 87 mins:
+#  [Timer] Timings:
+#  [Timer] annotate                       ---  584.2 s
+#  [Timer] rtype_lltype                   ---  777.3 s
+#  [Timer] backendopt_lltype              ---  365.9 s
+#  [Timer] stackcheckinsertion_lltype     ---   39.3 s
+#  [Timer] database_c                     --- 1089.6 s
+#  [Timer] source_c                       --- 1868.6 s
+#  [Timer] compile_c                      ---  490.4 s
+#  [Timer] ===========================================
+#  [Timer] Total:                         --- 5215.3 s
+
+
+# Should we build a "pypy" binary? (with jit)
+# pypy-1.4/pypy/jit/backend/detect_cpu.py:getcpuclassname currently supports the
+# following options:
+#  'i386', 'x86'
+#  'x86-without-sse2':
+#  'x86_64'
+#  'cli'
+#  'llvm'
+%ifarch %{ix86} x86_64
+# FIXME: is there a better way of expressing "intel" here?
+%global with_jit 1
+%else
+%global with_jit 0
+%endif
+
+# Should we build a "pypy-stackless" binary?
+%global with_stackless 0
+
+
+# Easy way to enable/disable verbose logging:
+%global verbose_logs 0
+
+%global pypyprefix %{_libdir}/pypy-%{version}
+%global pylibver 2.5.2
+
+# We refer to this subdir of the source tree in a few places during the build:
+%global goal_dir pypy/translator/goal
+
+
+# Turn off the brp-python-bytecompile postprocessing script
+# We manually invoke it later on, using the freshly built pypy binary
+%global __os_install_post \
+  %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
+
+# Source and patches:
+Source0:        http://pypy.org/download/pypy-%{version}-src.tar.bz2
+
+# Edit a translator file for linux in order to configure our cflags and dynamic libffi
+Patch0:         pypy-1.4-config.patch
+
+# By default, if built at a tty, the translation process renders a Mandelbrot
+# set to indicate progress.
+# This obscures useful messages, and may waste CPU cycles, so suppress it, and
+# merely render dots:
+Patch1:         pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
+
+# test_commmands fails on SELinux systems due to a change in the output
+# of "ls" (http://bugs.python.org/issue7108)
+Patch2: fix-test_commands-expected-ls-output-issue7108.patch
+
+# When locating the pypy standard libraries, look first within
+# LIBRARY_INSTALLATION_PATH.
+# We convert this from being a non-existant variable into a string literal
+# with the value of "pypyprefix" in the "prep" phase below.
+#
+# We still use the scanning relative to the binary location when invoking a
+# pypy binary during the build (e.g. during "check")
+#
+# Sent upstream (with caveats) as:
+#   https://codespeak.net/issue/pypy-dev/issue614
+Patch3: pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
+
+# Build-time requirements:
+
+BuildRequires:  python-devel
+
+# FIXME: I'm seeing errors like this in the logs:
+#   [translation:WARNING] The module '_rawffi' is disabled
+#   [translation:WARNING] because importing pypy.rlib.libffi raised ImportError
+#   [translation:WARNING] 'libffi.a' not found in ['/usr/lib/libffi', '/usr/lib']
+# Presumably we need to fix things to support dynamically-linked libffi
+BuildRequires:  libffi-devel
+
+BuildRequires:  zlib-devel
+BuildRequires:  bzip2-devel
+BuildRequires:  ncurses-devel
+BuildRequires:  expat-devel
+BuildRequires:  openssl-devel
+BuildRequires:  valgrind-devel
+
+# Used by the selftests, though not by the build:
+BuildRequires:  gc-devel
+
+BuildRequires:  /usr/bin/execstack
+
+# pypy is bundling these so we delete them in %%prep.  I don't think they are
+# needed unless we build pypy targetted at running on the jvm.
+#BuildRequires:  jna
+#BuildRequires: jasmin  # Not yet in Fedora
+
+
+# Metadata for the core package (the JIT build):
+Requires: pypy-libs = %{version}-%{release}
+
+%description
+PyPy's implementation of Python, featuring a Just-In-Time compiler, and various
+optimized implementations of the standard types (strings, dictionaries, etc)
+
+
+%package libs
+Group:    Development/Languages
+Summary:  Run-time libraries used by PyPy implementations of Python
+%description libs
+Libraries required by the various PyPy implementations of Python.
+
+%if 0%{with_stackless}
+%package stackless
+Group:    Development/Languages
+Summary:  Stackless Python interpreter built using PyPy
+Requires: pypy-libs = %{version}-%{release}
+%description stackless
+Build of PyPy with support for micro-threads for massive concurrency
+%endif
+
+%if 0%{with_stackless}
+%package stackless
+Group:    Development/Languages
+Summary:  Stackless Python interpreter built using PyPy
+Requires: pypy-libs = %{version}-%{release}
+%description stackless
+Build of PyPy with support for micro-threads for massive concurrency
+%endif
+
+
+%prep
+%setup -q -n pypy-%{version}-src
+%patch0 -p1 -b .configure-fedora
+%patch1 -p1 -b .suppress-mandelbrot-set-during-tty-build
+
+pushd lib-python/%{pylibver}
+%patch2 -p0
+popd
+
+# Look for the pypy libraries within LIBRARY_INSTALLATION_PATH first:
+%patch3 -p1
+# Fixup LIBRARY_INSTALLATION_PATH to be a string literal containing our value
+# for "pypyprefix":
+sed -i \
+  -e 's|LIBRARY_INSTALLATION_PATH|"%{pypyprefix}"|' \
+  pypy/translator/goal/app_main.py
+
+
+# Replace /usr/local/bin/python shebangs with /usr/bin/python:
+find -name "*.py" -exec \
+  sed \
+    -i -e "s|/usr/local/bin/python|/usr/bin/python|" \
+    "{}" \
+    \;
+
+find . -name '*.jar' -exec rm \{\} \;
+
+# Remove stray ".svn" directories present within the 1.4.1 tarball
+# (reported as https://codespeak.net/issue/pypy-dev/issue612 )
+find . -path '*/.svn*' -delete
+
+# Remove DOS batch files:
+find -name "*.bat"|xargs rm -f
+
+# The "demo" directory gets auto-installed by virture of being listed in %doc
+# Remove shebang lines from demo .py files, and remove executability from them:
+for f in demo/bpnn.py ; do
+   # Detect shebang lines && remove them:
+   sed -e '/^#!/Q 0' -e 'Q 1' $f \
+      && sed -i '1d' $f
+   chmod a-x $f
+done
+
+%build
+
+BuildPyPy() {
+  ExeName=$1
+  Options=$2
+
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "STARTING BUILD OF: $ExeName"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+
+  pushd %{goal_dir}
+
+  # The build involves invoking a python script, passing in particular
+  # arguments, environment variables, etc.
+  # Some notes on those follow:
+
+  # The generated binary embeds copies of the values of all environment
+  # variables.  We need to unset "RPM_BUILD_ROOT" to avoid a fatal error from
+  #  /usr/lib/rpm/check-buildroot
+  # during the postprocessing of the rpmbuild, complaining about this
+  # reference to the buildroot
+
+
+  # By default, pypy's autogenerated C code is placed in
+  #    /tmp/usession-N
+  #  
+  # and it appears that this stops rpm from extracting the source code to the
+  # debuginfo package
+  #
+  # The logic in pypy-1.4/pypy/tool/udir.py indicates that it is generated in:
+  #    $PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-N    
+  # and so we set PYPY_USESSION_DIR so that this tempdir is within the build
+  # location, and set $PYPY_USESSION_BASENAME so that the tempdir is unique
+  # for each invocation of BuildPyPy
+
+  # Compilation flags for C code:
+  #   pypy-1.4/pypy/translator/c/genc.py:gen_makefile
+  # assembles a Makefile within
+  #   THE_UDIR/testing_1/Makefile
+  # calling out to platform.gen_makefile
+  # For us, that's
+  #   pypy-1.4/pypy/translator/platform/linux.py: class BaseLinux(BasePosix):
+  # which by default has:
+  #   CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
+  #             '-Wall', '-Wno-unused']
+  # plus all substrings from CFLAGS in the environment.
+  # This is used to generate a value for CFLAGS that's written into the Makefile
+
+  # https://bugzilla.redhat.com/show_bug.cgi?id=588941#c18
+  # The generated Makefile compiles the .c files into assembler (.s), rather
+  # than direct to .o  It then post-processes this assembler to locate
+  # garbage-collection roots (building .lbl.s and .gcmap files, and a
+  # "gcmaptable.s").  (The modified .lbl.s files have extra code injected
+  # within them).
+  # Unfortunately, the code to do this:
+  #   pypy-1.4/pypy/translator/c/gcc/trackgcroot.py
+  # doesn't interract well with the results of using our standard build flags.
+  # For now, filter our CFLAGS of everything that could be conflicting with
+  # pypy.  Need to check these and reenable ones that are okay later.
+  export CFLAGS=$(echo "$RPM_OPT_FLAGS" | sed -e 's/-Wp,-D_FORTIFY_SOURCE=2//' -e 's/-fexceptions//' -e 's/-fstack-protector//' -e 's/--param=ssp-buffer-size=4//' -e 's/-O2//' -e 's/-fasynchronous-unwind-tables//' -e 's/-march=i686//' -e 's/-mtune=atom//')
+
+  # If we're already built the JIT-enabled "pypy", then use it for subsequent
+  # builds (of other configurations):
+  if test -x './pypy' ; then
+    INTERP='./pypy'
+  else
+    INTERP='python'
+  fi
+
+  # Here's where we actually invoke the build:
+  time \
+    RPM_BUILD_ROOT= \
+    PYPY_USESSION_DIR=$(pwd) \
+    PYPY_USESSION_BASENAME=$ExeName \
+    $INTERP translate.py \
+%if 0%{verbose_logs}
+    --translation-verbose \
+%endif
+    --cflags="$CFLAGS" \
+    --batch \
+    --output=$ExeName \
+    $Options
+
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "FINISHED BUILDING: $ExeName"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+
+  popd
+}
+
+%if 0%{with_jit}
+BuildPyPy \
+  pypy \
+  "-Ojit"
+%endif
+
+%if 0%{with_stackless}
+BuildPyPy \
+  pypy-stackless \
+   "--stackless"
+%endif
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+
+# Install the various executables:
+
+InstallPyPy() {
+    ExeName=$1
+
+    install -m 755 %{goal_dir}/$ExeName %{buildroot}/%{_bindir}
+
+    # The generated machine code doesn't need an executable stack,  but
+    # one of the assembler files (gcmaptable.s) doesn't have the necessary
+    # metadata to inform gcc of that, and thus gcc pessimistically assumes
+    # that the built binary does need an executable stack.
+    #
+    # Reported upstream as: https://codespeak.net/issue/pypy-dev/issue610
+    #
+    # I tried various approaches involving fixing the build, but the simplest
+    # approach is to postprocess the ELF file:
+    execstack --clear-execstack %{buildroot}/%{_bindir}/$ExeName
+}
+
+mkdir -p %{buildroot}/%{_bindir}
+
+%if 0%{with_jit}
+InstallPyPy pypy
+%endif
+
+%if 0%{with_stackless}
+InstallPyPy pypy-stackless
+%endif
+
+
+# Install the various support libraries as described at:
+#   http://codespeak.net/pypy/dist/pypy/doc/getting-started-python.html#installation
+# which refers to a "PREFIX" found relative to the location of the binary.
+# Given that the pypy binaries will be in /usr/bin, PREFIX can be
+# "../share/pypy-1.2" relative to that directory, i.e. /usr/share/pypy-1.2
+# 
+# Running "strace" on a built binary indicates that it searches within
+#   PREFIX/lib-python/modified-2.5.2
+# not
+#   PREFIX/lib-python/modified.2.5.2
+# as given on the above page, i.e. it uses '-' not '.'
+
+mkdir -p %{buildroot}/%{pypyprefix}
+cp -a lib-python %{buildroot}/%{pypyprefix}
+
+cp -a lib_pypy %{buildroot}/%{pypyprefix}
+
+# Remove a text file that documents which selftests fail on Win32:
+rm %{buildroot}/%{pypyprefix}/lib-python/win32-failures.txt
+
+# Remove shebang lines from .py files that aren't executable, and
+# remove executability from .py files that don't have a shebang line:
+find \
+  %{buildroot}                                                           \
+  -name "*.py"                                                           \
+    \(                                                                   \
+       \( \! -perm /u+x,g+x,o+x -exec sed -e '/^#!/Q 0' -e 'Q 1' {} \;   \
+             -print -exec sed -i '1d' {} \;                              \
+          \)                                                             \
+       -o                                                                \
+       \(                                                                \
+             -perm /u+x,g+x,o+x ! -exec grep -m 1 -q '^#!' {} \;         \
+             -exec chmod a-x {} \;                                       \
+        \)                                                               \
+    \)
+
+mkdir -p %{buildroot}/%{pypyprefix}/site-packages
+
+
+# pypy uses .pyc files by default (--objspace-usepycfiles), but has a slightly
+# different bytecode format to CPython.  It doesn't use .pyo files: the -O flag
+# is treated as a "dummy optimization flag for compatibility with C Python"
+#
+# pypy-1.4/pypy/module/imp/importing.py has this comment:
+    # XXX picking a magic number is a mess.  So far it works because we
+    # have only two extra opcodes, which bump the magic number by +1 and
+    # +2 respectively, and CPython leaves a gap of 10 when it increases
+    # its own magic number.  To avoid assigning exactly the same numbers
+    # as CPython we always add a +2.  We'll have to think again when we
+    # get at the fourth new opcode :-(
+    #
+    #  * CALL_LIKELY_BUILTIN    +1
+    #  * CALL_METHOD            +2
+    #
+    # In other words:
+    #
+    #     default_magic        -- used by CPython without the -U option
+    #     default_magic + 1    -- used by CPython with the -U option
+    #     default_magic + 2    -- used by PyPy without any extra opcode
+    #     ...
+    #     default_magic + 5    -- used by PyPy with both extra opcodes
+#
+
+# pypy-1.4/pypy/interpreter/pycode.py has:
+#
+#  default_magic = (62141+2) | 0x0a0d0000                  # this PyPy's magic
+#                                                          # (62131=CPython 2.5.1)
+# giving a value for "default_magic" for PyPy of 0xa0df2bf.
+# Note that this corresponds to the "default_magic + 2" from the comment above
+
+# In my builds:
+#   $ ./pypy --info | grep objspace.opcodes
+#                objspace.opcodes.CALL_LIKELY_BUILTIN: False
+#                        objspace.opcodes.CALL_METHOD: True
+# so I'd expect the magic number to be:
+#    0x0a0df2bf + 2 (the flag for CALL_METHOD)
+# giving
+#    0x0a0df2c1
+#
+# I'm seeing
+#   c1 f2 0d 0a
+# as the first four bytes of the .pyc files, which is consistent with this.
+
+
+# Bytecompile all of the .py files we ship, using our pypy binary, giving us
+# .pyc files for pypy.  The script actually does the work twice (passing in -O
+# the second time) but it's simplest to reuse that script.
+#
+# The script has special-casing for .py files below
+#    /usr/lib{64}/python[0-9].[0-9]
+# but given that we're installing into a different path, the supplied "default"
+# implementation gets used instead.
+#
+# Note that some of the test files deliberately contain syntax errors, so
+# we pass 0 for the second argument ("errors_terminate"):
+/usr/lib/rpm/brp-python-bytecompile \
+  %{buildroot}/%{_bindir}/pypy \
+  0
+
+%check
+topdir=$(pwd)
+
+SkipTest() {
+    # Append the given test name to TESTS_TO_SKIP
+    TEST_NAME=$1
+    TESTS_TO_SKIP="$TESTS_TO_SKIP $TEST_NAME"
+}
+
+CheckPyPy() {
+    # We'll be exercising one of the freshly-built binaries using the
+    # test suite from the standard library (overridden in places by pypy's
+    # modified version)
+    ExeName=$1
+
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "STARTING TEST OF: $ExeName"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+
+    pushd %{goal_dir}
+
+    # Gather a list of tests to skip, due to known failures
+    # TODO: report these failures to pypy upstream
+    TESTS_TO_SKIP=""
+
+    # Test failures relating to missing codecs
+    # Hopefully when pypy merges to 2.7 support we'll gain these via a
+    # refreshed stdlib:
+      # test_codecencodings_cn:
+      #   all tests fail, with one of
+      #     unknown encoding: gb18030
+      #     unknown encoding: gb2312
+      #     unknown encoding: gbk
+      SkipTest test_codecencodings_cn
+
+      # test_codecencodings_hk:
+      #   all tests fail, with:
+      #     unknown encoding: big5hkscs
+      SkipTest test_codecencodings_hk
+
+      # test_codecencodings_jp:
+      #   all tests fail, with one of:
+      #     unknown encoding: cp932
+      #     unknown encoding: euc_jisx0213
+      #     unknown encoding: euc_jp
+      #     unknown encoding: shift_jis
+      #     unknown encoding: shift_jisx0213
+      SkipTest test_codecencodings_jp
+
+      # test_codecencodings_kr:
+      #   all tests fail, with one of:
+      #     unknown encoding: cp949
+      #     unknown encoding: euc_kr
+      #     unknown encoding: johab
+      SkipTest test_codecencodings_kr
+
+      # test_codecencodings_tw:
+      #    all tests fail, with:
+      #      unknown encoding: big5
+      SkipTest test_codecencodings_tw
+
+      # test_multibytecodec:
+      #   14 failures out of 15, due to:
+      #     unknown encoding: euc-kr
+      #     unknown encoding: gb2312
+      #     unknown encoding: jisx0213
+      #     unknown encoding: cp949
+      #     unknown encoding: iso2022-jp
+      #     unknown encoding: gb18030
+      SkipTest test_multibytecodec
+
+    #
+    # Other failures:
+    #
+      # test_asynchat:
+      #   seems to hang on this test, within test_line_terminator
+      SkipTest test_asynchat
+
+      # test_compiler:
+      #   4 errors out of 13:
+      #     testSourceCodeEncodingsError
+      #     testWith
+      #     testWithAss
+      #     testYieldExpr
+      SkipTest test_compiler
+
+      # test_ctypes:
+      #   failures=17, errors=20, out of 132 tests
+      SkipTest test_ctypes
+
+      # test_frozen:
+      #   TestFailed: import __hello__ failed:No module named __hello__
+      SkipTest test_frozen
+
+      # test_iterlen:
+      #   24 failures out of 25, apparently all due to TypeError
+      SkipTest test_iterlen
+
+      # test_parser:
+      #   12 failures out of 15
+      SkipTest test_parser
+
+      # test_platform:
+      #   Koji builds show:
+      #    test test_platform failed -- errors occurred in test.test_platform.PlatformTest
+      SkipTest test_platform
+
+      # test_socket:
+      #   testSockName can fail in Koji with:
+      #       my_ip_addr = socket.gethostbyname(socket.gethostname())
+      #     gaierror: (-3, 'Temporary failure in name resolution')
+      SkipTest test_socket
+
+      # test_sort:
+      #   some failures
+      SkipTest test_sort
+
+      # test_sqlite:
+      #   3 of the sqlite3.test.dbapi.ExtensionTests raise:
+      #     ProgrammingError: Incomplete statement ''
+      SkipTest test_sqlite
+
+      # test_traceback:
+      #   works when run standalone; failures seen when run as part of a suite
+      SkipTest test_traceback
+
+      # test_zlib:
+      #   failure seen in Koji, not sure of reason why:
+      #     test test_zlib failed -- Traceback (most recent call last):
+      #     File "/builddir/build/BUILD/pypy-1.4.1-src/lib-python/2.5.2/test/test_zlib.py", line 72, in test_baddecompressobj
+      #       self.assertRaises(ValueError, zlib.decompressobj, 0)
+      #     AssertionError: ValueError not raised
+      SkipTest test_zlib
+
+
+    # Run the built binary through the selftests:
+    time ./$ExeName -m test.regrtest -x $TESTS_TO_SKIP
+
+    popd
+
+    # Doublecheck pypy's own test suite, using the built pypy binary:
+
+    # Disabled for now:
+    #   x86_64 shows various failures inside:
+    #     jit/backend/x86/test
+    #   followed by a segfault inside
+    #     jit/backend/x86/test/test_runner.py
+    #
+    #   i686 shows various failures inside:
+    #     jit/backend/x86/test
+    #   with the x86_64 failure leading to cancellation of the i686 build
+
+    # Here's the disabled code:
+    #    pushd pypy
+    #    time translator/goal/$ExeName test_all.py
+    #    popd
+
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "FINISHED TESTING: $ExeName"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+}
+
+%if 0%{with_jit}
+CheckPyPy pypy
+%endif
+
+%if 0%{with_stackless}
+CheckPyPy pypy-stackless
+%endif
+
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files libs
+%defattr(-,root,root,-)
+%doc LICENSE README demo
+
+%dir %{pypyprefix}
+%dir %{pypyprefix}/lib-python
+%{pypyprefix}/lib-python/%{pylibver}/
+%{pypyprefix}/lib-python/modified-%{pylibver}/
+%{pypyprefix}/lib-python/conftest.py*
+%{pypyprefix}/lib_pypy/
+%{pypyprefix}/site-packages/
+
+%if 0%{with_jit}
+%files
+%defattr(-,root,root,-)
+%doc LICENSE README
+%{_bindir}/pypy
+%endif
+
+%if 0%{with_stackless}
+%files stackless
+%defattr(-,root,root,-)
+%doc LICENSE README
+%{_bindir}/pypy-stackless
+%endif
+
+
+%changelog
+* Wed Dec 22 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-3
+- try to respect the FHS by installing libraries below libdir, rather than
+datadir; patch app_main.py to look in this installation location first when
+scanning for the pypy library directories.
+- clarifications and corrections to the comments in the specfile
+
+* Wed Dec 22 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-2
+- remove .svn directories
+- disable verbose logging
+- add a %%check section
+- introduce %%goal_dir variable, to avoid repetition
+- remove shebang line from demo/bpnn.py, as we're treating this as a
+documentation file
+- regenerate patch 2 to apply without generating a .orig file
+
+* Tue Dec 21 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-1
+- 1.4.1; fixup %%setup to reflect change in toplevel directory in upstream
+source tarball
+- apply SELinux fix to the bundled test_commands.py (patch 2)
+
+* Wed Dec 15 2010 David Malcolm <dmalcolm at redhat.com> - 1.4-4
+- rename the jit build and subpackge to just "pypy", and remove the nojit and
+sandbox builds, as upstream now seems to be focussing on the JIT build (with
+only stackless called out in the getting-started-python docs); disable
+stackless for now
+- add a verbose_logs specfile boolean; leave it enabled for now (whilst fixing
+build issues)
+- add more comments, and update others to reflect 1.2 -> 1.4 changes
+- re-enable debuginfo within CFLAGS ("-g")
+- add the LICENSE and README to all subpackages
+- ensure the built binaries don't have the "I need an executable stack" flag
+- remove DOS batch files during %%prep (idlelib.bat)
+- remove shebang lines from .py files that aren't executable, and remove
+executability from .py files that don't have a shebang line (taken from
+our python3.spec)
+- bytecompile the .py files into .pyc files in pypy's bytecode format
+
+* Sun Nov 28 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-3
+- BuildRequire valgrind-devel
+- Install pypy library from the new directory
+- Disable building with our CFLAGS for now because they are causing a build failure.
+- Include site-packages directory
+
+* Sat Nov 27 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-2
+- Add patch to configure the build to use our CFLAGS and link libffi
+  dynamically
+
+* Sat Nov 27 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-1
+- Update to 1.4
+- Drop patch for py2.6 that's in this build
+- Switch to building pypy with itself once pypy is built once as recommended by
+  upstream
+- Remove bundled, prebuilt java libraries
+- Fix license tag
+- Fix source url
+- Version pypy-libs Req
+
+* Tue May  4 2010 David Malcolm <dmalcolm at redhat.com> - 1.2-2
+- cherrypick r72073 from upstream SVN in order to fix the build against
+python 2.6.5 (patch 2)
+
+* Wed Apr 28 2010 David Malcolm <dmalcolm at redhat.com> - 1.2-1
+- initial packaging
+
diff --git a/sources b/sources
index e69de29..90f34be 100644
--- a/sources
+++ b/sources
@@ -0,0 +1 @@
+ebbbb156b1eb842e9e65d909ed5f9f6d  pypy-1.4.1-src.tar.bz2
-- 
cgit v0.10.2


From 00e57e74f81587a2c49341341a7a291a54e22dc8 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Thu, 6 Jan 2011 17:09:03 -0500
Subject: * Wed Jan  5 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-4 -
 rebuild pypy using itself, for speed, with a boolean to break this cycle in
 the build-requirement graph (falling back to using "python-devel" aka
 CPython) - add work-in-progress patch to try to make generated c more
 readable (rhbz#666963) - capture the RPython source code files from the build
 within the debuginfo package (rhbz#666975)


diff --git a/pypy-1.4.1-more-readable-c-code.patch b/pypy-1.4.1-more-readable-c-code.patch
new file mode 100644
index 0000000..45fa534
--- /dev/null
+++ b/pypy-1.4.1-more-readable-c-code.patch
@@ -0,0 +1,695 @@
+diff -r cd083843b67a pypy/interpreter/pycode.py
+--- a/pypy/interpreter/pycode.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/interpreter/pycode.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -14,6 +14,7 @@
+ from pypy.interpreter.astcompiler.consts import (CO_OPTIMIZED,
+     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
+     CO_GENERATOR, CO_CONTAINSGLOBALS)
++from pypy.interpreter.pytraceback import offset2lineno
+ from pypy.rlib.rarithmetic import intmask
+ from pypy.rlib.debug import make_sure_not_resized
+ from pypy.rlib import jit
+@@ -81,6 +82,7 @@
+         self.hidden_applevel = hidden_applevel
+         self.magic = magic
+         self._signature = cpython_code_signature(self)
++        self._cached_source = None
+         self._initialize()
+ 
+     def _initialize(self):
+@@ -403,3 +405,25 @@
+     def repr(self, space):
+         return space.wrap(self.get_repr())
+     repr.unwrap_spec = ['self', ObjSpace]
++
++    def get_linenum_for_offset(self, offset):
++        # Given a bytecode offset, return a 1-based index into the lines of the
++        # source code
++        return offset2lineno(self, offset)
++
++    def _ensure_source(self):
++        # Lazily grab the source lines into self._cached_source (or raise
++        # an IOError)
++        if not self._cached_source:
++            f = open(self.co_filename, 'r')
++            source = [line.rstrip() for line in f.readlines()]
++            f.close()
++            self._cached_source = source
++    
++    def get_source_text(self, linenum):
++        # Given a 1-based index, get the corresponding line of source code (or
++        # raise an IOError)
++        self._ensure_source()
++        return self._cached_source[linenum - 1]
++
++        
+diff -r cd083843b67a pypy/objspace/flow/model.py
+--- a/pypy/objspace/flow/model.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/objspace/flow/model.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -31,6 +31,120 @@
+ 
+ __metaclass__ = type
+ 
++class SourceLoc(object):
++    # A srcloc is a specific location within the RPython source code,
++    # intended for human display
++    __slots__ = ('code', # code object
++                 'linenum' # 1-based index, as displayed to a user
++                 )
++    def __init__(self, code, linenum):
++        self.code = code
++        self.linenum = linenum
++
++    def get_text(self):
++        # Get the actual source text of this line
++        return self.code.get_source_text(self.linenum)
++
++    def __eq__(self, other):
++        return self.code == other.code and self.linenum == other.linenum
++
++    def __ne__(self, other):
++        if other:
++            return self.code != other.code or self.linenum != other.linenum
++        else:
++            return True
++
++class CodeLoc(object):
++    # A codeloc is a specific location within the RPython bytecode
++    __slots__ = ('code', # code object
++                 'offset' # int index into bytecode, or -1
++                 )
++
++    def __init__(self, code, offset):
++        self.code = code
++        self.offset = offset
++
++    def __str__(self):
++        if self.offset >= 0:
++            return "%s@%d" % (self.code.co_name, self.offset)
++        else:
++            return ""
++
++    def __ne__(self, other):
++        if other:
++            return self.code != other.code or self.offset != other.offset
++        else:
++            return True
++
++    def __cmp__(self, other):
++        # Partial ordering, for those locations that have an offset:
++        if other:
++            if self.offset >= 0 and other.offset >= 0:
++                return self.offset - other.offset
++        return 0
++
++    def get_source_loc(self):
++        # Convert to a SourceLoc:
++        return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset))
++
++class OperationLoc(object):
++    # An oploc is the location within the RPython source code of a given
++    # operation
++    # 
++    # This is a list consisting of CodeLoc instances, some of which may be None
++    #
++    # For the simple case, this is list of length 1 with a single CodeLoc
++    #
++    # For an operation inside an inlined callsite, we have a list of length 2:
++    #    [codeloc of callsite,
++    #     codeloc of operation within inlined body]
++    #
++    # For more interesting inlined cases, we have a chain of source locations:
++    #    [codeloc of callsite,
++    #     codeloc of inner callsite,
++    #     ... ,
++    #     codeloc of innermost inlined callsite,
++    #     codeloc of operation within inlined body]
++    #
++
++    __slots__ = ('codelocs', )
++
++    def __init__(self, codelocs):
++        self.codelocs = codelocs
++
++    def __str__(self):
++        return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']'
++
++    def __cmp__(self, other):
++        return cmp(self.codelocs, other.codelocs)
++
++def block_comparator(blk0, blk1):
++    '''
++    Sort function for blocks, putting them in an ordering that attempts to
++    maximize readability of the generated C code
++    '''
++    # print 'comparing %r and %r' % (blk0, blk1)
++    # Put the start/end block at the top/bottom:
++    if blk0.isstartblock:
++        return -1
++
++    if blk1.isstartblock:
++        return 1
++
++    # Order blocks by the offset, where present:
++    if blk0.operations:
++        if blk1.operations:
++            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
++        else:
++            return -1
++    else:
++        if blk1.operations:
++            return 1
++        else:
++            return 0
++
++def edge_comparator(edge0, edge1):
++    return block_comparator(edge0.target, edge1.target)
+ 
+ class FunctionGraph(object):
+     __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__']
+@@ -94,6 +208,21 @@
+                 seen[block] = True
+                 stack += block.exits[::-1]
+ 
++    def iterblocks_by_source(self):
++        # Try to preserve logical source ordering in the blocks
++        block = self.startblock
++        yield block
++        seen = {block: True}
++        stack = list(block.exits[::-1])
++        stack.sort(edge_comparator)
++        while stack:
++            block = stack.pop().target
++            if block not in seen:
++                yield block
++                seen[block] = True
++                stack += block.exits[::-1]
++                stack.sort(edge_comparator)
++
+     def iterlinks(self):
+         block = self.startblock
+         seen = {block: True}
+@@ -183,14 +312,14 @@
+         self.exits      = []              # list of Link(s)
+ 
+     def at(self):
+-        if self.operations and self.operations[0].offset >= 0:
+-            return "@%d" % self.operations[0].offset
++        if self.operations:
++            return str(self.operations[0].oploc)
+         else:
+             return ""
+ 
+     def __str__(self):
+         if self.operations:
+-            txt = "block@%d" % self.operations[0].offset
++            txt = "block%s" % self.operations[0].oploc
+         else:
+             if (not self.exits) and len(self.inputargs) == 1:
+                 txt = "return block"
+@@ -245,6 +374,21 @@
+         from pypy.translator.tool.graphpage import try_show
+         try_show(self)
+ 
++    def isreturnblock(self):
++        return (not self.operations) and (not self.exits) and len(self.inputargs) == 1
++
++    def get_base_label(self, blocknum):
++        # Generate a more friendly C label for this block
++        if self.operations:
++            txt = "block"
++        elif (not self.exits) and len(self.inputargs) == 1:
++            txt = "return_block"
++        elif (not self.exits) and len(self.inputargs) == 2:
++            txt = "raise_block"
++        else:
++            txt = "codeless_block"
++        return '%s%d' % (txt, blocknum)
++
+ 
+ class Variable(object):
+     __slots__ = ["_name", "_nr", "concretetype"]
+@@ -331,13 +475,15 @@
+ 
+ 
+ class SpaceOperation(object):
+-    __slots__ = "opname args result offset".split()
++    __slots__ = "opname args result oploc".split()
+ 
+-    def __init__(self, opname, args, result, offset=-1):
++    def __init__(self, opname, args, result, oploc=None):
+         self.opname = intern(opname)      # operation name
+         self.args   = list(args)  # mixed list of var/const
+         self.result = result      # either Variable or Constant instance
+-        self.offset = offset      # offset in code string
++        if oploc is None:
++            oploc = OperationLoc([None])
++        self.oploc = oploc
+ 
+     def __eq__(self, other):
+         return (self.__class__ is other.__class__ and 
+@@ -352,8 +498,9 @@
+         return hash((self.opname,tuple(self.args),self.result))
+ 
+     def __repr__(self):
+-        return "%r = %s(%s)" % (self.result, self.opname,
+-                                ", ".join(map(repr, self.args)))
++        return "%r = %s(%s) (%s)" % (self.result, self.opname,
++                                     ", ".join(map(repr, self.args)),
++                                     self.oploc)
+ 
+ class Atom(object):
+     def __init__(self, name):
+@@ -448,8 +595,7 @@
+                 for op in oplist:
+                     copyop = SpaceOperation(op.opname,
+                                             [copyvar(v) for v in op.args],
+-                                            copyvar(op.result), op.offset)
+-                    #copyop.offset = op.offset
++                                            copyvar(op.result), op.oploc)
+                     result.append(copyop)
+                 return result
+             newblock.operations = copyoplist(block.operations)
+diff -r cd083843b67a pypy/objspace/flow/objspace.py
+--- a/pypy/objspace/flow/objspace.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/objspace/flow/objspace.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -310,7 +310,9 @@
+     def do_operation(self, name, *args_w):
+         spaceop = SpaceOperation(name, args_w, Variable())
+         if hasattr(self, 'executioncontext'):  # not here during bootstrapping
+-            spaceop.offset = self.executioncontext.crnt_offset
++            codeloc = CodeLoc(self.executioncontext.code,
++                              self.executioncontext.crnt_offset)
++            spaceop.oploc = OperationLoc([codeloc])
+             self.executioncontext.recorder.append(spaceop)
+         return spaceop.result
+ 
+diff -r cd083843b67a pypy/objspace/flow/test/test_model.py
+--- a/pypy/objspace/flow/test/test_model.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/objspace/flow/test/test_model.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -132,3 +132,25 @@
+     assert v2.renamed
+     assert v2.name.startswith("foobar_") and v2.name != v.name
+     assert v2.name.split('_', 1)[1].isdigit()
++
++def test_source_locations():
++    # Invent some random offsets into the code:
++    co = sample_function.__code__
++    codelocA = CodeLoc(co, 42)
++    codelocB = CodeLoc(co, 87)
++
++    assert str(codelocA) == 'sample_function at 42'
++    assert str(codelocB) == 'sample_function at 87'
++
++    assert cmp(codelocA, codelocB) < 0
++    assert cmp(codelocB, codelocA) > 0
++    
++    oplocA = OperationLoc([codelocA])
++    oplocB = OperationLoc([codelocB])
++
++    assert str(oplocA) == '[sample_function at 42]'
++    assert str(oplocB) == '[sample_function at 87]'
++
++    assert cmp(oplocA, oplocB) < 0
++    assert cmp(oplocB, oplocA) > 0
++
+diff -r cd083843b67a pypy/rpython/rtyper.py
+--- a/pypy/rpython/rtyper.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/rpython/rtyper.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -800,7 +800,7 @@
+         return vars
+ 
+     def genop(self, opname, args_v, resulttype=None):
+-        return self.llops.genop(opname, args_v, resulttype)
++        return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc)
+ 
+     def gendirectcall(self, ll_function, *args_v):
+         return self.llops.gendirectcall(ll_function, *args_v)
+@@ -935,7 +935,7 @@
+                                                     v.concretetype))
+         return v
+ 
+-    def genop(self, opname, args_v, resulttype=None):
++    def genop(self, opname, args_v, resulttype=None, oploc=None):
+         try:
+             for v in args_v:
+                 v.concretetype
+@@ -944,7 +944,7 @@
+                                  " and pass its result to genop(),"
+                                  " never hop.args_v directly.")
+         vresult = Variable()
+-        self.append(SpaceOperation(opname, args_v, vresult))
++        self.append(SpaceOperation(opname, args_v, vresult, oploc))
+         if resulttype is None:
+             vresult.concretetype = Void
+             return None
+diff -r cd083843b67a pypy/translator/backendopt/inline.py
+--- a/pypy/translator/backendopt/inline.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/backendopt/inline.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -4,6 +4,7 @@
+ from pypy.translator.unsimplify import copyvar
+ from pypy.objspace.flow.model import Variable, Constant, Block, Link
+ from pypy.objspace.flow.model import SpaceOperation, c_last_exception
++from pypy.objspace.flow.model import OperationLoc
+ from pypy.objspace.flow.model import FunctionGraph
+ from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph
+ from pypy.annotation import model as annmodel
+@@ -231,6 +232,7 @@
+         self.varmap = {}
+         self._copied_blocks = {}
+         self.op = block.operations[index_operation]
++        self.callsite_oploc = self.op.oploc
+         self.graph_to_inline = self.get_graph_from_op(self.op)
+         self.exception_guarded = False
+         if (block.exitswitch == c_last_exception and
+@@ -297,7 +299,9 @@
+         
+     def copy_operation(self, op):
+         args = [self.get_new_name(arg) for arg in op.args]
+-        result = SpaceOperation(op.opname, args, self.get_new_name(op.result))
++        new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:])
++        result = SpaceOperation(op.opname, args, self.get_new_name(op.result), 
++                                new_oploc)
+         return result
+ 
+     def copy_block(self, block):
+diff -r cd083843b67a pypy/translator/c/funcgen.py
+--- a/pypy/translator/c/funcgen.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/c/funcgen.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -1,4 +1,6 @@
+ import sys
++import inspect
++import dis
+ from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
+ from pypy.translator.c.support import cdecl
+ from pypy.translator.c.support import llvalue_from_constant, gen_assignments
+@@ -22,6 +24,38 @@
+ 
+ KEEP_INLINED_GRAPHS = False
+ 
++def block_comparator(blk0, blk1):
++    '''
++    Sort function for blocks, putting them in an ordering that attempts to
++    maximize readability of the generated C code
++    '''
++    # print 'comparing %r and %r' % (blk0, blk1)
++    # Put the start/end block at the top/bottom:
++    if blk0.isstartblock:
++        return -1
++
++    if blk1.isstartblock:
++        return 1
++
++    # Order blocks by the offset, where present:
++    if blk0.operations:
++        if blk1.operations:
++            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
++        else:
++            return -1
++    else:
++        if blk1.operations:
++            return 1
++        else:
++            return 0
++
++def escape_c_comments(py_src):
++    # Escape C comments within RPython source, to avoid generating bogus
++    # comments in our generated C source:
++    py_src = py_src.replace('/*', '')
++    py_src = py_src.replace('*/', '')
++    return py_src
++
+ class FunctionCodeGenerator(object):
+     """
+     Collects information about a function which we have to generate
+@@ -210,14 +244,57 @@
+ 
+     def cfunction_body(self):
+         graph = self.graph
+-        yield 'goto block0;'    # to avoid a warning "this label is not used"
++        # Try to print python source code:
++        if hasattr(graph, 'func'):
++            filename = inspect.getfile(graph.func)
++            #yield '/* name: %r */' % filename
++            try:
++                src, startline = inspect.getsourcelines(graph.func)
++            except IOError:
++                pass # No source found
++            except IndexError:
++                pass # Bulletproofing
++            else:
++                yield '/* Python source %r' % filename
++                for i, line in enumerate(src):
++                    line = line.rstrip()
++                    line = escape_c_comments(line)
++                    # FuncNode.funcgen_implementation treats lines ending in ':'
++                    # as C blocks, which messes up the formatting.
++                    # Work around this:
++                    if line.endswith(':'):
++                        line += ' '
++                    yield ' * %4d : %s' % (startline + i, line)
++                yield ' */'
++
++        label = graph.startblock.get_base_label(self.blocknum[graph.startblock])
++        yield 'goto %s;' % label # to avoid a warning "this label is not used"
++
++        # Sort the blocks into a (hopefully) readable order:
++        blocks = list(graph.iterblocks_by_source())
++        blocks.sort(block_comparator)
+ 
+         # generate the body of each block
+-        for block in graph.iterblocks():
++        for block in blocks:
++            cursrcloc = None
+             myblocknum = self.blocknum[block]
+             yield ''
+-            yield 'block%d:' % myblocknum
++            yield '%s:' % block.get_base_label(myblocknum)
++            #yield "/* repr(block): %r */" % (block, )
++            #yield "/* type(block): %r */" % (type(block), )
+             for i, op in enumerate(block.operations):
++                #yield "/* type(op): %r */" % (type(op), )
++                #yield "/* op.oploc: %s */" % (op.oploc, )
++                codeloc = op.oploc.codelocs[-1]
++                if codeloc:
++                    srcloc = codeloc.get_source_loc()
++                    if srcloc != cursrcloc:
++                        try:
++                            yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text()))
++                            cursrcloc = srcloc
++                        except IOError:
++                            pass
++
+                 for line in self.gen_op(op):
+                     yield line
+             if len(block.exits) == 0:
+@@ -310,7 +387,7 @@
+             assignments.append((a2typename, dest, src))
+         for line in gen_assignments(assignments):
+             yield line
+-        label = 'block%d' % self.blocknum[link.target]
++        label = link.target.get_base_label(self.blocknum[link.target])
+         if link.target in self.innerloops:
+             loop = self.innerloops[link.target]
+             if link is loop.links[-1]:   # link that ends a loop
+diff -r cd083843b67a pypy/translator/c/test/test_genc.py
+--- a/pypy/translator/c/test/test_genc.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/c/test/test_genc.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -1,4 +1,5 @@
+ import autopath, sys, os, py
++import re
+ from pypy.rpython.lltypesystem.lltype import *
+ from pypy.annotation import model as annmodel
+ from pypy.translator.translator import TranslationContext
+@@ -498,3 +499,130 @@
+     else:
+         assert 0, "the call was not found in the C source"
+     assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1]
++
++def get_generated_c_source(fn, types):
++    # Return a (optimized fn, c source code, c source filename) 3-tuple
++    t = Translation(fn)
++    t.annotate(types)
++    c_filename_path = t.source_c()
++    h = c_filename_path.open()
++    src = h.read()
++    h.close()
++    c_fn = t.compile_c()
++    return (c_fn, src, c_filename_path)
++
++def extract_c_function(c_src, fname):
++    # Extract the source for a given C function out of a the given src string
++    # Makes assumptions about the layout of the source
++    pattern = '^(.+) \**%s\(.*\) {$' % fname
++    within_fn = False
++    result = ''
++    for line in c_src.splitlines():
++        if within_fn:
++            result += line + '\n'
++            if line.startswith('}'):
++                return result
++        else:
++            m = re.match(pattern, line)
++            if m:
++                within_fn = True
++                result += line + '\n'
++    return result
++    
++    
++
++def test_generated_c_source():
++    # Verify that generate C source "looks good"
++    # We'll use is_perfect_number, as it contains a loop and a conditional
++
++    # Generate C source code
++    from pypy.translator.test.snippet import is_perfect_number
++    c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number,
++                                                        [int])
++
++    # Locate the C source for the type-specialized function:
++    c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number')
++    
++    # Verify that the C source contains embedded comments containing the lines
++    # of the python source:
++    expected_comment_lines = [
++        '/* is_perfect_number:31 :     while div < n: */',
++        '/* is_perfect_number:32 :         if n % div == 0: */',
++        '/* is_perfect_number:33 :             sum += div */',
++        '/* is_perfect_number:34 :         div += 1 */',
++        '/* is_perfect_number:35 :     return n == sum */']
++    for exp_line in expected_comment_lines:
++        assert exp_line in c_fn_src
++        
++    # Verify that the lines occur in the correct order
++    # ...we do this by filtering the function's generated C source to just
++    # those lines containing our comments (and dropping whitespace):
++    lines = c_fn_src.splitlines()
++    lines = [line.strip()
++             for line in lines
++             if '/* is_perfect_number:' in line]
++
++    # ...we should now have exact equality: the ordering should be as expected,
++    # and each comment should appear exactly once:
++    assert lines == expected_comment_lines
++
++    # Ensure that the generated C function does the right thing:
++    assert c_fn(5) == False
++    assert c_fn(6) == True
++    assert c_fn(7) == False
++
++    assert c_fn(5.0) == False
++    assert c_fn(6.0) == True
++    assert c_fn(7.0) == False
++
++    assert c_fn(5L) == False
++    assert c_fn(6L) == True
++    assert c_fn(7L) == False
++
++    try:
++        c_fn('hello world')
++    except:
++        pass
++    else:
++        raise 'Was expected exception'
++    
++def test_escaping_c_comments():
++    # Ensure that c comments within RPython code get escaped when we generate
++    # our .c code (to avoid generating bogus C)
++    # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a
++    # docstring embedding a C comment
++    def c_style_comment(a, b):
++        '''Here is a C-style comment within an RPython docstring:
++                /* hello world */
++        '''
++        # and here's one in a string literal:
++        return '/* hello world a:%s b:%s */' % (a, b)
++
++    def cplusplus_style_comment(a, b):
++        '''Here is a C++-style comment within an RPython docstring:
++                // hello world
++        '''
++        # and here are some in string literals, and one as the floor division
++        # operator:
++        return '// hello world: a // b = %s' % (a // b)
++
++    for fn_name, exp_output in [('c_style_comment',
++                                 '/* hello world a:6 b:3 */'),
++                                ('cplusplus_style_comment',
++                                 '// hello world: a // b = 2')]:
++        fn = locals()[fn_name]
++
++        c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int])
++        # If the above survived, then the C compiler managed to handle
++        # the generated C code
++
++        # Verify that the generated code works (i.e. that we didn't
++        # accidentally change the meaning):
++        assert c_fn(6, 3) == exp_output
++
++        # Ensure that at least part of the docstrings made it into the C
++        # code:
++        c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name)
++        assert 'Here is a ' in c_fn_src
++        assert 'style comment within an RPython docstring' in c_fn_src
++        
+diff -r cd083843b67a pypy/translator/driver.py
+--- a/pypy/translator/driver.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/driver.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -539,6 +539,7 @@
+             dstname = self.compute_exe_name() + '.staticdata.info'
+             shutil.copy(str(fname), str(dstname))
+             self.log.info('Static data info written to %s' % dstname)
++        return c_source_filename
+ 
+     #
+     task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
+diff -r cd083843b67a pypy/translator/gensupp.py
+--- a/pypy/translator/gensupp.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/gensupp.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -16,8 +16,8 @@
+     def visit(block):
+         if isinstance(block, Block):
+             # first we order by offset in the code string
+-            if block.operations:
+-                ofs = block.operations[0].offset
++            if block.operations and block.operations[0].oploc.codelocs[0]:
++                ofs = block.operations[0].oploc.codelocs[0].offset
+             else:
+                 ofs = sys.maxint
+             # then we order by input variable name or value
+diff -r cd083843b67a pypy/translator/interactive.py
+--- a/pypy/translator/interactive.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/interactive.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -138,7 +138,7 @@
+     def source_c(self, argtypes=None, **kwds):
+         self.update_options(argtypes, kwds)
+         self.ensure_backend('c')
+-        self.driver.source_c()
++        return self.driver.source_c()
+ 
+     def source_cl(self, argtypes=None, **kwds):
+         self.update_options(argtypes, kwds)
+diff -r cd083843b67a pypy/translator/llsupport/wrapper.py
+--- a/pypy/translator/llsupport/wrapper.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/llsupport/wrapper.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -59,6 +59,8 @@
+     # "return result"
+     block = Block(wrapper_inputargs)
+     wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
++    if hasattr(graph, 'func'):
++        wgraph.func = graph.func
+     translator.update_call_graph(wgraph, graph, object())
+     translator.graphs.append(wgraph)
+     block.operations[:] = newops
+diff -r cd083843b67a pypy/translator/simplify.py
+--- a/pypy/translator/simplify.py	Mon Dec 20 17:17:45 2010 +0100
++++ b/pypy/translator/simplify.py	Wed Jan 05 16:14:35 2011 -0500
+@@ -294,7 +294,7 @@
+                 return renaming.get(v, v)
+             def rename_op(op):
+                 args = [rename(a) for a in op.args]
+-                op = SpaceOperation(op.opname, args, rename(op.result), op.offset)
++                op = SpaceOperation(op.opname, args, rename(op.result), op.oploc)
+                 # special case...
+                 if op.opname == 'indirect_call':
+                     if isinstance(op.args[0], Constant):
diff --git a/pypy.spec b/pypy.spec
index 96354e2..162ed5f 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.4.1
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -136,9 +136,33 @@ Patch2: fix-test_commands-expected-ls-output-issue7108.patch
 #   https://codespeak.net/issue/pypy-dev/issue614
 Patch3: pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
 
+# Try to improve the readability of the generated .c code, by adding in the
+# RPython source as comments where possible.
+# A version of this was sent upstream as:
+#  http://codespeak.net/pipermail/pypy-dev/2010q4/006532.html
+# TODO: get this into the upstream bug tracker, and finish inlining
+# support (rhbz#666963)
+Patch4: pypy-1.4.1-more-readable-c-code.patch
+
+
 # Build-time requirements:
 
-BuildRequires:  python-devel
+# pypy's can be rebuilt using itself, rather than with CPython; doing so
+# halves the build time.
+#
+# Turn it off with this boolean, to revert back to rebuilding using CPython
+# and avoid a cycle in the build-time dependency graph:
+#
+%global use_self_when_building 1
+%if 0%{use_self_when_building}
+BuildRequires: pypy
+%global bootstrap_python_interp pypy
+%else
+BuildRequires: python-devel
+%global bootstrap_python_interp python
+%endif
+
+
 
 # FIXME: I'm seeing errors like this in the logs:
 #   [translation:WARNING] The module '_rawffi' is disabled
@@ -215,6 +239,8 @@ sed -i \
   -e 's|LIBRARY_INSTALLATION_PATH|"%{pypyprefix}"|' \
   pypy/translator/goal/app_main.py
 
+%patch4 -p1 -b .more-readable-c-code
+
 
 # Replace /usr/local/bin/python shebangs with /usr/bin/python:
 find -name "*.py" -exec \
@@ -304,6 +330,7 @@ BuildPyPy() {
   # doesn't interract well with the results of using our standard build flags.
   # For now, filter our CFLAGS of everything that could be conflicting with
   # pypy.  Need to check these and reenable ones that are okay later.
+  # Filed as https://bugzilla.redhat.com/show_bug.cgi?id=666966
   export CFLAGS=$(echo "$RPM_OPT_FLAGS" | sed -e 's/-Wp,-D_FORTIFY_SOURCE=2//' -e 's/-fexceptions//' -e 's/-fstack-protector//' -e 's/--param=ssp-buffer-size=4//' -e 's/-O2//' -e 's/-fasynchronous-unwind-tables//' -e 's/-march=i686//' -e 's/-mtune=atom//')
 
   # If we're already built the JIT-enabled "pypy", then use it for subsequent
@@ -311,7 +338,10 @@ BuildPyPy() {
   if test -x './pypy' ; then
     INTERP='./pypy'
   else
-    INTERP='python'
+    # First pypy build within this rpm build?
+    # Fall back to using the bootstrap python interpreter, which might be a
+    # system copy of pypy from an earlier rpm, or be cpython's /usr/bin/python:
+    INTERP='%{bootstrap_python_interp}'
   fi
 
   # Here's where we actually invoke the build:
@@ -484,6 +514,34 @@ mkdir -p %{buildroot}/%{pypyprefix}/site-packages
   %{buildroot}/%{_bindir}/pypy \
   0
 
+# Capture the RPython source code files from the build within the debuginfo
+# package (rhbz#666975)
+%global pypy_debuginfo_dir /usr/src/debug/pypy-%{version}-src
+mkdir -p %{buildroot}%{pypy_debuginfo_dir}
+
+# copy over everything:
+cp -a pypy %{buildroot}%{pypy_debuginfo_dir}
+
+# ...then delete files that aren't .py files:
+find \
+  %{buildroot}%{pypy_debuginfo_dir} \
+  \( -type f                        \
+     -a                             \
+     \! -name "*.py"                \
+  \)                                \
+  -delete
+
+# We don't need bytecode for these files; they are being included for reference
+# purposes.
+# There are some rpmlint warnings from these files:
+#   non-executable-script
+#   wrong-script-interpreter
+#   zero-length
+#   script-without-shebang
+#   dangling-symlink
+# but given that the objective is to preserve a copy of the source code, those
+# are acceptable.
+
 %check
 topdir=$(pwd)
 
@@ -511,6 +569,7 @@ CheckPyPy() {
 
     # Gather a list of tests to skip, due to known failures
     # TODO: report these failures to pypy upstream
+    # See also rhbz#666967 and rhbz#666969
     TESTS_TO_SKIP=""
 
     # Test failures relating to missing codecs
@@ -622,6 +681,14 @@ CheckPyPy() {
       #     AssertionError: ValueError not raised
       SkipTest test_zlib
 
+    %if 0%{use_self_when_building}
+    # Patch 3 prioritizes the installed copy of pypy's libraries over the
+    # build copy.
+    # This leads to test failures of test_pep263 and test_tarfile
+    # For now, suppress these when building using pypy itself:
+    SkipTest test_pep263   # on-disk encoding issues
+    SkipTest test_tarfile  # permissions issues
+    %endif
 
     # Run the built binary through the selftests:
     time ./$ExeName -m test.regrtest -x $TESTS_TO_SKIP
@@ -696,6 +763,14 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Wed Jan  5 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-4
+- rebuild pypy using itself, for speed, with a boolean to break this cycle in
+the build-requirement graph (falling back to using "python-devel" aka CPython)
+- add work-in-progress patch to try to make generated c more readable
+(rhbz#666963)
+- capture the RPython source code files from the build within the debuginfo
+package (rhbz#666975)
+
 * Wed Dec 22 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-3
 - try to respect the FHS by installing libraries below libdir, rather than
 datadir; patch app_main.py to look in this installation location first when
-- 
cgit v0.10.2


From d39359a3af6a0dee27f50e4a4fe52860f9c6b426 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Hor=C3=A1k?= <dan at danny.cz>
Date: Fri, 7 Jan 2011 17:56:06 +0100
Subject: - valgrind available only on selected architectures


diff --git a/pypy.spec b/pypy.spec
index 162ed5f..4d66f89 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.4.1
-Release:        4%{?dist}
+Release:        5%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -176,7 +176,9 @@ BuildRequires:  bzip2-devel
 BuildRequires:  ncurses-devel
 BuildRequires:  expat-devel
 BuildRequires:  openssl-devel
+%ifarch %{ix86} x86_64 ppc ppc64 s390x
 BuildRequires:  valgrind-devel
+%endif
 
 # Used by the selftests, though not by the build:
 BuildRequires:  gc-devel
@@ -763,6 +765,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Fri Jan  7 2011 Dan Horák <dan[at]danny.cz> - 1.4.1-5
+- valgrind available only on selected architectures
+
 * Wed Jan  5 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-4
 - rebuild pypy using itself, for speed, with a boolean to break this cycle in
 the build-requirement graph (falling back to using "python-devel" aka CPython)
-- 
cgit v0.10.2


From 0a81116e89104e6bd77075151eadf5bde029085d Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Thu, 13 Jan 2011 19:51:26 -0500
Subject: Add a pypy-devel subpackage; rerun failed selftests in verbose mode

* Thu Jan 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-6
- add a "pypy-devel" subpackage, and install the header files there
- in %%check, re-run failed tests in verbose mode

diff --git a/pypy.spec b/pypy.spec
index 4d66f89..71b2db6 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.4.1
-Release:        5%{?dist}
+Release:        6%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -205,6 +205,16 @@ Summary:  Run-time libraries used by PyPy implementations of Python
 %description libs
 Libraries required by the various PyPy implementations of Python.
 
+
+%package devel
+Group:    Development/Languages
+Summary:  Development tools for working with PyPy
+%description devel
+Header files for building C extension modules against PyPy
+
+Requires: pypy = %{version}-%{release}
+
+
 %if 0%{with_stackless}
 %package stackless
 Group:    Development/Languages
@@ -516,6 +526,22 @@ mkdir -p %{buildroot}/%{pypyprefix}/site-packages
   %{buildroot}/%{_bindir}/pypy \
   0
 
+
+# Header files for C extension modules.
+# Upstream's packaging process (pypy/tool/release/package.py)
+# creates an "include" subdir and copies all *.h/*.inl from "include" there
+# (it also has an apparently out-of-date comment about copying them from
+# pypy/_interfaces, but this directory doesn't seem to exist, and it doesn't
+# seem to do this as of 2011-01-13)
+
+# FIXME: arguably these should be instead put into a subdir below /usr/include,
+# it's not yet clear to me how upstream plan to deal with the C extension
+# interface going forward, so let's just mimic upstream for now.
+%global pypy_include_dir  %{pypyprefix}/include
+mkdir -p %{buildroot}/%{pypy_include_dir}
+cp include/*.h include/*.inl %{buildroot}/%{pypy_include_dir}
+
+
 # Capture the RPython source code files from the build within the debuginfo
 # package (rhbz#666975)
 %global pypy_debuginfo_dir /usr/src/debug/pypy-%{version}-src
@@ -692,8 +718,9 @@ CheckPyPy() {
     SkipTest test_tarfile  # permissions issues
     %endif
 
-    # Run the built binary through the selftests:
-    time ./$ExeName -m test.regrtest -x $TESTS_TO_SKIP
+    # Run the built binary through the selftests
+    # "-w" : re-run failed tests in verbose mode
+    time ./$ExeName -m test.regrtest -w -x $TESTS_TO_SKIP
 
     popd
 
@@ -756,6 +783,12 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/pypy
 %endif
 
+%files devel
+%defattr(-,root,root,-)
+%dir %{pypy_include_dir}
+%{pypy_include_dir}/*.h
+%{pypy_include_dir}/*.inl
+
 %if 0%{with_stackless}
 %files stackless
 %defattr(-,root,root,-)
@@ -765,6 +798,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Jan 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-6
+- add a "pypy-devel" subpackage, and install the header files there
+- in %%check, re-run failed tests in verbose mode
+
 * Fri Jan  7 2011 Dan Horák <dan[at]danny.cz> - 1.4.1-5
 - valgrind available only on selected architectures
 
-- 
cgit v0.10.2


From 7632349386659a82412f3dfbd37e714bf56aa152 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Fri, 14 Jan 2011 11:06:07 -0500
Subject: skip test_ioctl for now


diff --git a/pypy.spec b/pypy.spec
index 71b2db6..9c8134d 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.4.1
-Release:        6%{?dist}
+Release:        7%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -669,6 +669,25 @@ CheckPyPy() {
       #   TestFailed: import __hello__ failed:No module named __hello__
       SkipTest test_frozen
 
+      # test_ioctl:
+      #   Failing in Koji with dist-f15 with:
+      #     ======================================================================
+      #     FAIL: test_ioctl (test.test_ioctl.IoctlTests)
+      #     ----------------------------------------------------------------------
+      #     Traceback (most recent call last):
+      #       File "/usr/lib/pypy-1.4.1/lib-python/2.5.2/test/test_ioctl.py", line 25, in test_ioctl
+      #         self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
+      #     AssertionError: 0 not in (8304, 17737)
+      #     ======================================================================
+      #     FAIL: test_ioctl_mutate (test.test_ioctl.IoctlTests)
+      #     ----------------------------------------------------------------------
+      #     Traceback (most recent call last):
+      #       File "/usr/lib/pypy-1.4.1/lib-python/2.5.2/test/test_ioctl.py", line 35, in test_ioctl_mutate
+      #         self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
+      #     AssertionError: 0 not in (8304, 17737)
+      #     ----------------------------------------------------------------------
+      SkipTest test_ioctl
+
       # test_iterlen:
       #   24 failures out of 25, apparently all due to TypeError
       SkipTest test_iterlen
@@ -798,6 +817,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Fri Jan 14 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-7
+- skip test_ioctl for now
+
 * Thu Jan 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-6
 - add a "pypy-devel" subpackage, and install the header files there
 - in %%check, re-run failed tests in verbose mode
-- 
cgit v0.10.2


From c225b1c0921c528b804bdce231951a10f040cb6c Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Fri, 14 Jan 2011 11:58:45 -0500
Subject: Disable self-hosting for now, due to fatal error seen JIT-compiling
 the translator


diff --git a/pypy.spec b/pypy.spec
index 9c8134d..6f44a9a 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.4.1
-Release:        7%{?dist}
+Release:        8%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -152,8 +152,38 @@ Patch4: pypy-1.4.1-more-readable-c-code.patch
 #
 # Turn it off with this boolean, to revert back to rebuilding using CPython
 # and avoid a cycle in the build-time dependency graph:
+
+# I'm disabling the self-hosting for now, due to a fatal error seen inside the
+# JIT, presumably whilst JIT-compiling something within the translator's
+# inliner.
+# 
+# Specifically, building pypy-1.4.1-7.fc15.src.rpm on x86_64 using pypy-1.4.1-5.fc15.x86_64 
+#   http://koji.fedoraproject.org/koji/taskinfo?taskID=2721517
+# failed with this RPython traceback:
+#     ... snip ...
+#   [rtyper:WARNING] prebuilt instance <pypy.rpython.memory.gctransform.asmgcroot.ShapeDecompressor instance at 0x00000000f0b5bc80> has no attribute 'addr'
+#   [rtyper] specializing: 179300 / 180508 blocks   (99%)
+#   [rtyper] specializing: 180500 / 180566 blocks   (99%)
+#   [rtyper] -=- specialized 1363 more blocks -=-
+#   [rtyper] specializing: 180600 / 180777 blocks   (99%)
+#   [rtyper] -=- specialized 211 more blocks -=-
+#   [backendopt:inlining] phase with threshold factor: 32.4
+#   [backendopt:inlining] heuristic: pypy.translator.backendopt.inline.inlining_heuristic
+#   [x86/regalloc] Bogus arg in operation 76 at 0
+#   RPython traceback:
+#     File "implement_62.c", line 39979, in send_bridge_to_backend
+#     File "implement_69.c", line 65301, in Assembler386_assemble_bridge
+#     File "implement_72.c", line 8078, in RegAlloc_prepare_bridge
+#     File "implement_40.c", line 53061, in RegAlloc__prepare
+#     File "implement_44.c", line 14305, in RegAlloc__compute_vars_longevity
+#   Fatal RPython error: NotImplementedError
 #
-%global use_self_when_building 1
+# This appears to be deep within pypy/jit/backend/x86/regalloc.py which has
+# called "not_implemented" to emit this message to stderr, before raising the
+# exception:
+#   [x86/regalloc] Bogus arg in operation 76 at 0
+
+%global use_self_when_building 0
 %if 0%{use_self_when_building}
 BuildRequires: pypy
 %global bootstrap_python_interp pypy
@@ -817,6 +847,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Fri Jan 14 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-8
+- disable self-hosting for now, due to fatal error seen JIT-compiling the
+translator
+
 * Fri Jan 14 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-7
 - skip test_ioctl for now
 
-- 
cgit v0.10.2


From d853ff6a5bdd4ce40976333f048aba1616374604 Mon Sep 17 00:00:00 2001
From: Dennis Gilmore <dennis at ausil.us>
Date: Tue, 8 Feb 2011 20:23:05 -0600
Subject: - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild


diff --git a/pypy.spec b/pypy.spec
index 6f44a9a..ca09b94 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.4.1
-Release:        8%{?dist}
+Release:        9%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -847,6 +847,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.4.1-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
 * Fri Jan 14 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-8
 - disable self-hosting for now, due to fatal error seen JIT-compiling the
 translator
-- 
cgit v0.10.2


From 3ca83f1944c99711e69be7a733f36a976d1fcec2 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Sat, 30 Apr 2011 18:24:07 -0400
Subject: Fix the build on architectures that the JIT doesn't support

- build a /usr/bin/pypy (but without the JIT compiler) on architectures that
don't support the JIT, so that they do at least have something that runs

diff --git a/pypy.spec b/pypy.spec
index ca09b94..c69893a 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.4.1
-Release:        9%{?dist}
+Release:        10%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -74,7 +74,10 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 #  [Timer] Total:                         --- 5215.3 s
 
 
-# Should we build a "pypy" binary? (with jit)
+# We will build a "pypy" binary.
+#
+# Unfortunately, the JIT support is only available on some architectures.
+#
 # pypy-1.4/pypy/jit/backend/detect_cpu.py:getcpuclassname currently supports the
 # following options:
 #  'i386', 'x86'
@@ -82,6 +85,11 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 #  'x86_64'
 #  'cli'
 #  'llvm'
+#
+# We will only build with JIT support on those architectures, and build without
+# it on the other archs.  The resulting binary will typically be slower than
+# CPython for the latter case.
+#
 %ifarch %{ix86} x86_64
 # FIXME: is there a better way of expressing "intel" here?
 %global with_jit 1
@@ -225,8 +233,16 @@ BuildRequires:  /usr/bin/execstack
 Requires: pypy-libs = %{version}-%{release}
 
 %description
-PyPy's implementation of Python, featuring a Just-In-Time compiler, and various
-optimized implementations of the standard types (strings, dictionaries, etc)
+PyPy's implementation of Python, featuring a Just-In-Time compiler on some CPU
+architectures, and various optimized implementations of the standard types
+(strings, dictionaries, etc)
+
+%if 0%{with_jit}
+This build of PyPy has JIT-compilation enabled.
+%else
+This build of PyPy has JIT-compilation disabled, as it is not supported on this
+CPU architecture.
+%endif
 
 
 %package libs
@@ -411,11 +427,12 @@ BuildPyPy() {
   popd
 }
 
-%if 0%{with_jit}
 BuildPyPy \
   pypy \
-  "-Ojit"
+%if 0%{with_jit}
+  "-Ojit" \
 %endif
+  %{nil}
 
 %if 0%{with_stackless}
 BuildPyPy \
@@ -448,9 +465,7 @@ InstallPyPy() {
 
 mkdir -p %{buildroot}/%{_bindir}
 
-%if 0%{with_jit}
 InstallPyPy pypy
-%endif
 
 %if 0%{with_stackless}
 InstallPyPy pypy-stackless
@@ -799,9 +814,7 @@ CheckPyPy() {
     echo "--------------------------------------------------------------"
 }
 
-%if 0%{with_jit}
 CheckPyPy pypy
-%endif
 
 %if 0%{with_stackless}
 CheckPyPy pypy-stackless
@@ -825,12 +838,10 @@ rm -rf $RPM_BUILD_ROOT
 %{pypyprefix}/lib_pypy/
 %{pypyprefix}/site-packages/
 
-%if 0%{with_jit}
 %files
 %defattr(-,root,root,-)
 %doc LICENSE README
 %{_bindir}/pypy
-%endif
 
 %files devel
 %defattr(-,root,root,-)
@@ -847,6 +858,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Wed Apr 20 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-10
+- build a /usr/bin/pypy (but without the JIT compiler) on architectures that
+don't support the JIT, so that they do at least have something that runs
+
 * Tue Feb 08 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.4.1-9
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
 
-- 
cgit v0.10.2


From 169de85aca1a527ea42ef102aa32a40ba1740168 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Mon, 2 May 2011 14:46:32 -0400
Subject: Rebase to 1.5 (rhbz#701121)

Update patches:
  patch 0: pypy-1.4-config.patch -> pypy-1.5-config.patch
  patch 4: pypy-1.4.1-more-readable-c-code.patch -> pypy-1.5-more-readable-c-code.patch

Remove references to *.inl files, no longer present

Add the following tests to the skip list:
  test_audioop, test_capi, test_distutils, test_gc, test_gdb, test_generators,
  test_getargs2, test_hotshot, test_io, test_multiprocessing, test_posix,
  test_readline, test_scope, test_strop, test_structmembers, test_subprocess,
  test_symtable, test_sys_settrace, test_tempfile, test_thread, test_uuid,
  test_zipimport_support

Add a couple of text files to the payload (TODO, stdlib-version.txt)

diff --git a/.gitignore b/.gitignore
index 2878978..017cf34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 /pypy-1.4.1-src.tar.bz2
+/pypy-1.5-src.tar.bz2
diff --git a/pypy-1.4-config.patch b/pypy-1.4-config.patch
deleted file mode 100644
index 0b82ac8..0000000
--- a/pypy-1.4-config.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-Index: pypy-1.4/pypy/translator/platform/linux.py
-===================================================================
---- pypy-1.4.orig/pypy/translator/platform/linux.py
-+++ pypy-1.4/pypy/translator/platform/linux.py
-@@ -3,17 +3,22 @@ import py, os
- from pypy.translator.platform import _run_subprocess
- from pypy.translator.platform.posix import BasePosix
- 
-+CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
-+          '-Wall', '-Wno-unused']
-+if os.environ.get('CFLAGS', None):
-+    CFLAGS.extend(os.environ['CFLAGS'].split())
-+CFLAGS = tuple(CFLAGS)
-+
- class BaseLinux(BasePosix):
-     name = "linux"
-     
-     link_flags = ('-pthread', '-lrt')
--    cflags = ('-O3', '-pthread', '-fomit-frame-pointer',
--              '-Wall', '-Wno-unused')
-+    cflags = CFLAGS
-     standalone_only = ()
-     shared_only = ('-fPIC',)
-     so_ext = 'so'
-     so_prefixes = ('lib', '')
--    
-+
-     def _args_for_shared(self, args):
-         return ['-shared'] + args
- 
-@@ -29,9 +34,10 @@ class BaseLinux(BasePosix):
- class Linux(BaseLinux):
-     shared_only = ()    # it seems that on 32-bit linux, compiling with -fPIC
-                         # gives assembler that asmgcc is not happy about.
--    def library_dirs_for_libffi_a(self):
--        # places where we need to look for libffi.a
--        return self.library_dirs_for_libffi() + ['/usr/lib']
-+    # Fedora Linux, at least, has the shared version but not the static
-+    #def library_dirs_for_libffi_a(self):
-+    #    # places where we need to look for libffi.a
-+    #    return self.library_dirs_for_libffi() + ['/usr/lib']
- 
- 
- class Linux64(BaseLinux):
diff --git a/pypy-1.4.1-more-readable-c-code.patch b/pypy-1.4.1-more-readable-c-code.patch
deleted file mode 100644
index 45fa534..0000000
--- a/pypy-1.4.1-more-readable-c-code.patch
+++ /dev/null
@@ -1,695 +0,0 @@
-diff -r cd083843b67a pypy/interpreter/pycode.py
---- a/pypy/interpreter/pycode.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/interpreter/pycode.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -14,6 +14,7 @@
- from pypy.interpreter.astcompiler.consts import (CO_OPTIMIZED,
-     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
-     CO_GENERATOR, CO_CONTAINSGLOBALS)
-+from pypy.interpreter.pytraceback import offset2lineno
- from pypy.rlib.rarithmetic import intmask
- from pypy.rlib.debug import make_sure_not_resized
- from pypy.rlib import jit
-@@ -81,6 +82,7 @@
-         self.hidden_applevel = hidden_applevel
-         self.magic = magic
-         self._signature = cpython_code_signature(self)
-+        self._cached_source = None
-         self._initialize()
- 
-     def _initialize(self):
-@@ -403,3 +405,25 @@
-     def repr(self, space):
-         return space.wrap(self.get_repr())
-     repr.unwrap_spec = ['self', ObjSpace]
-+
-+    def get_linenum_for_offset(self, offset):
-+        # Given a bytecode offset, return a 1-based index into the lines of the
-+        # source code
-+        return offset2lineno(self, offset)
-+
-+    def _ensure_source(self):
-+        # Lazily grab the source lines into self._cached_source (or raise
-+        # an IOError)
-+        if not self._cached_source:
-+            f = open(self.co_filename, 'r')
-+            source = [line.rstrip() for line in f.readlines()]
-+            f.close()
-+            self._cached_source = source
-+    
-+    def get_source_text(self, linenum):
-+        # Given a 1-based index, get the corresponding line of source code (or
-+        # raise an IOError)
-+        self._ensure_source()
-+        return self._cached_source[linenum - 1]
-+
-+        
-diff -r cd083843b67a pypy/objspace/flow/model.py
---- a/pypy/objspace/flow/model.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/objspace/flow/model.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -31,6 +31,120 @@
- 
- __metaclass__ = type
- 
-+class SourceLoc(object):
-+    # A srcloc is a specific location within the RPython source code,
-+    # intended for human display
-+    __slots__ = ('code', # code object
-+                 'linenum' # 1-based index, as displayed to a user
-+                 )
-+    def __init__(self, code, linenum):
-+        self.code = code
-+        self.linenum = linenum
-+
-+    def get_text(self):
-+        # Get the actual source text of this line
-+        return self.code.get_source_text(self.linenum)
-+
-+    def __eq__(self, other):
-+        return self.code == other.code and self.linenum == other.linenum
-+
-+    def __ne__(self, other):
-+        if other:
-+            return self.code != other.code or self.linenum != other.linenum
-+        else:
-+            return True
-+
-+class CodeLoc(object):
-+    # A codeloc is a specific location within the RPython bytecode
-+    __slots__ = ('code', # code object
-+                 'offset' # int index into bytecode, or -1
-+                 )
-+
-+    def __init__(self, code, offset):
-+        self.code = code
-+        self.offset = offset
-+
-+    def __str__(self):
-+        if self.offset >= 0:
-+            return "%s@%d" % (self.code.co_name, self.offset)
-+        else:
-+            return ""
-+
-+    def __ne__(self, other):
-+        if other:
-+            return self.code != other.code or self.offset != other.offset
-+        else:
-+            return True
-+
-+    def __cmp__(self, other):
-+        # Partial ordering, for those locations that have an offset:
-+        if other:
-+            if self.offset >= 0 and other.offset >= 0:
-+                return self.offset - other.offset
-+        return 0
-+
-+    def get_source_loc(self):
-+        # Convert to a SourceLoc:
-+        return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset))
-+
-+class OperationLoc(object):
-+    # An oploc is the location within the RPython source code of a given
-+    # operation
-+    # 
-+    # This is a list consisting of CodeLoc instances, some of which may be None
-+    #
-+    # For the simple case, this is list of length 1 with a single CodeLoc
-+    #
-+    # For an operation inside an inlined callsite, we have a list of length 2:
-+    #    [codeloc of callsite,
-+    #     codeloc of operation within inlined body]
-+    #
-+    # For more interesting inlined cases, we have a chain of source locations:
-+    #    [codeloc of callsite,
-+    #     codeloc of inner callsite,
-+    #     ... ,
-+    #     codeloc of innermost inlined callsite,
-+    #     codeloc of operation within inlined body]
-+    #
-+
-+    __slots__ = ('codelocs', )
-+
-+    def __init__(self, codelocs):
-+        self.codelocs = codelocs
-+
-+    def __str__(self):
-+        return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']'
-+
-+    def __cmp__(self, other):
-+        return cmp(self.codelocs, other.codelocs)
-+
-+def block_comparator(blk0, blk1):
-+    '''
-+    Sort function for blocks, putting them in an ordering that attempts to
-+    maximize readability of the generated C code
-+    '''
-+    # print 'comparing %r and %r' % (blk0, blk1)
-+    # Put the start/end block at the top/bottom:
-+    if blk0.isstartblock:
-+        return -1
-+
-+    if blk1.isstartblock:
-+        return 1
-+
-+    # Order blocks by the offset, where present:
-+    if blk0.operations:
-+        if blk1.operations:
-+            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
-+        else:
-+            return -1
-+    else:
-+        if blk1.operations:
-+            return 1
-+        else:
-+            return 0
-+
-+def edge_comparator(edge0, edge1):
-+    return block_comparator(edge0.target, edge1.target)
- 
- class FunctionGraph(object):
-     __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__']
-@@ -94,6 +208,21 @@
-                 seen[block] = True
-                 stack += block.exits[::-1]
- 
-+    def iterblocks_by_source(self):
-+        # Try to preserve logical source ordering in the blocks
-+        block = self.startblock
-+        yield block
-+        seen = {block: True}
-+        stack = list(block.exits[::-1])
-+        stack.sort(edge_comparator)
-+        while stack:
-+            block = stack.pop().target
-+            if block not in seen:
-+                yield block
-+                seen[block] = True
-+                stack += block.exits[::-1]
-+                stack.sort(edge_comparator)
-+
-     def iterlinks(self):
-         block = self.startblock
-         seen = {block: True}
-@@ -183,14 +312,14 @@
-         self.exits      = []              # list of Link(s)
- 
-     def at(self):
--        if self.operations and self.operations[0].offset >= 0:
--            return "@%d" % self.operations[0].offset
-+        if self.operations:
-+            return str(self.operations[0].oploc)
-         else:
-             return ""
- 
-     def __str__(self):
-         if self.operations:
--            txt = "block@%d" % self.operations[0].offset
-+            txt = "block%s" % self.operations[0].oploc
-         else:
-             if (not self.exits) and len(self.inputargs) == 1:
-                 txt = "return block"
-@@ -245,6 +374,21 @@
-         from pypy.translator.tool.graphpage import try_show
-         try_show(self)
- 
-+    def isreturnblock(self):
-+        return (not self.operations) and (not self.exits) and len(self.inputargs) == 1
-+
-+    def get_base_label(self, blocknum):
-+        # Generate a more friendly C label for this block
-+        if self.operations:
-+            txt = "block"
-+        elif (not self.exits) and len(self.inputargs) == 1:
-+            txt = "return_block"
-+        elif (not self.exits) and len(self.inputargs) == 2:
-+            txt = "raise_block"
-+        else:
-+            txt = "codeless_block"
-+        return '%s%d' % (txt, blocknum)
-+
- 
- class Variable(object):
-     __slots__ = ["_name", "_nr", "concretetype"]
-@@ -331,13 +475,15 @@
- 
- 
- class SpaceOperation(object):
--    __slots__ = "opname args result offset".split()
-+    __slots__ = "opname args result oploc".split()
- 
--    def __init__(self, opname, args, result, offset=-1):
-+    def __init__(self, opname, args, result, oploc=None):
-         self.opname = intern(opname)      # operation name
-         self.args   = list(args)  # mixed list of var/const
-         self.result = result      # either Variable or Constant instance
--        self.offset = offset      # offset in code string
-+        if oploc is None:
-+            oploc = OperationLoc([None])
-+        self.oploc = oploc
- 
-     def __eq__(self, other):
-         return (self.__class__ is other.__class__ and 
-@@ -352,8 +498,9 @@
-         return hash((self.opname,tuple(self.args),self.result))
- 
-     def __repr__(self):
--        return "%r = %s(%s)" % (self.result, self.opname,
--                                ", ".join(map(repr, self.args)))
-+        return "%r = %s(%s) (%s)" % (self.result, self.opname,
-+                                     ", ".join(map(repr, self.args)),
-+                                     self.oploc)
- 
- class Atom(object):
-     def __init__(self, name):
-@@ -448,8 +595,7 @@
-                 for op in oplist:
-                     copyop = SpaceOperation(op.opname,
-                                             [copyvar(v) for v in op.args],
--                                            copyvar(op.result), op.offset)
--                    #copyop.offset = op.offset
-+                                            copyvar(op.result), op.oploc)
-                     result.append(copyop)
-                 return result
-             newblock.operations = copyoplist(block.operations)
-diff -r cd083843b67a pypy/objspace/flow/objspace.py
---- a/pypy/objspace/flow/objspace.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/objspace/flow/objspace.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -310,7 +310,9 @@
-     def do_operation(self, name, *args_w):
-         spaceop = SpaceOperation(name, args_w, Variable())
-         if hasattr(self, 'executioncontext'):  # not here during bootstrapping
--            spaceop.offset = self.executioncontext.crnt_offset
-+            codeloc = CodeLoc(self.executioncontext.code,
-+                              self.executioncontext.crnt_offset)
-+            spaceop.oploc = OperationLoc([codeloc])
-             self.executioncontext.recorder.append(spaceop)
-         return spaceop.result
- 
-diff -r cd083843b67a pypy/objspace/flow/test/test_model.py
---- a/pypy/objspace/flow/test/test_model.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/objspace/flow/test/test_model.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -132,3 +132,25 @@
-     assert v2.renamed
-     assert v2.name.startswith("foobar_") and v2.name != v.name
-     assert v2.name.split('_', 1)[1].isdigit()
-+
-+def test_source_locations():
-+    # Invent some random offsets into the code:
-+    co = sample_function.__code__
-+    codelocA = CodeLoc(co, 42)
-+    codelocB = CodeLoc(co, 87)
-+
-+    assert str(codelocA) == 'sample_function at 42'
-+    assert str(codelocB) == 'sample_function at 87'
-+
-+    assert cmp(codelocA, codelocB) < 0
-+    assert cmp(codelocB, codelocA) > 0
-+    
-+    oplocA = OperationLoc([codelocA])
-+    oplocB = OperationLoc([codelocB])
-+
-+    assert str(oplocA) == '[sample_function at 42]'
-+    assert str(oplocB) == '[sample_function at 87]'
-+
-+    assert cmp(oplocA, oplocB) < 0
-+    assert cmp(oplocB, oplocA) > 0
-+
-diff -r cd083843b67a pypy/rpython/rtyper.py
---- a/pypy/rpython/rtyper.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/rpython/rtyper.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -800,7 +800,7 @@
-         return vars
- 
-     def genop(self, opname, args_v, resulttype=None):
--        return self.llops.genop(opname, args_v, resulttype)
-+        return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc)
- 
-     def gendirectcall(self, ll_function, *args_v):
-         return self.llops.gendirectcall(ll_function, *args_v)
-@@ -935,7 +935,7 @@
-                                                     v.concretetype))
-         return v
- 
--    def genop(self, opname, args_v, resulttype=None):
-+    def genop(self, opname, args_v, resulttype=None, oploc=None):
-         try:
-             for v in args_v:
-                 v.concretetype
-@@ -944,7 +944,7 @@
-                                  " and pass its result to genop(),"
-                                  " never hop.args_v directly.")
-         vresult = Variable()
--        self.append(SpaceOperation(opname, args_v, vresult))
-+        self.append(SpaceOperation(opname, args_v, vresult, oploc))
-         if resulttype is None:
-             vresult.concretetype = Void
-             return None
-diff -r cd083843b67a pypy/translator/backendopt/inline.py
---- a/pypy/translator/backendopt/inline.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/backendopt/inline.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -4,6 +4,7 @@
- from pypy.translator.unsimplify import copyvar
- from pypy.objspace.flow.model import Variable, Constant, Block, Link
- from pypy.objspace.flow.model import SpaceOperation, c_last_exception
-+from pypy.objspace.flow.model import OperationLoc
- from pypy.objspace.flow.model import FunctionGraph
- from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph
- from pypy.annotation import model as annmodel
-@@ -231,6 +232,7 @@
-         self.varmap = {}
-         self._copied_blocks = {}
-         self.op = block.operations[index_operation]
-+        self.callsite_oploc = self.op.oploc
-         self.graph_to_inline = self.get_graph_from_op(self.op)
-         self.exception_guarded = False
-         if (block.exitswitch == c_last_exception and
-@@ -297,7 +299,9 @@
-         
-     def copy_operation(self, op):
-         args = [self.get_new_name(arg) for arg in op.args]
--        result = SpaceOperation(op.opname, args, self.get_new_name(op.result))
-+        new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:])
-+        result = SpaceOperation(op.opname, args, self.get_new_name(op.result), 
-+                                new_oploc)
-         return result
- 
-     def copy_block(self, block):
-diff -r cd083843b67a pypy/translator/c/funcgen.py
---- a/pypy/translator/c/funcgen.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/c/funcgen.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -1,4 +1,6 @@
- import sys
-+import inspect
-+import dis
- from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
- from pypy.translator.c.support import cdecl
- from pypy.translator.c.support import llvalue_from_constant, gen_assignments
-@@ -22,6 +24,38 @@
- 
- KEEP_INLINED_GRAPHS = False
- 
-+def block_comparator(blk0, blk1):
-+    '''
-+    Sort function for blocks, putting them in an ordering that attempts to
-+    maximize readability of the generated C code
-+    '''
-+    # print 'comparing %r and %r' % (blk0, blk1)
-+    # Put the start/end block at the top/bottom:
-+    if blk0.isstartblock:
-+        return -1
-+
-+    if blk1.isstartblock:
-+        return 1
-+
-+    # Order blocks by the offset, where present:
-+    if blk0.operations:
-+        if blk1.operations:
-+            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
-+        else:
-+            return -1
-+    else:
-+        if blk1.operations:
-+            return 1
-+        else:
-+            return 0
-+
-+def escape_c_comments(py_src):
-+    # Escape C comments within RPython source, to avoid generating bogus
-+    # comments in our generated C source:
-+    py_src = py_src.replace('/*', '')
-+    py_src = py_src.replace('*/', '')
-+    return py_src
-+
- class FunctionCodeGenerator(object):
-     """
-     Collects information about a function which we have to generate
-@@ -210,14 +244,57 @@
- 
-     def cfunction_body(self):
-         graph = self.graph
--        yield 'goto block0;'    # to avoid a warning "this label is not used"
-+        # Try to print python source code:
-+        if hasattr(graph, 'func'):
-+            filename = inspect.getfile(graph.func)
-+            #yield '/* name: %r */' % filename
-+            try:
-+                src, startline = inspect.getsourcelines(graph.func)
-+            except IOError:
-+                pass # No source found
-+            except IndexError:
-+                pass # Bulletproofing
-+            else:
-+                yield '/* Python source %r' % filename
-+                for i, line in enumerate(src):
-+                    line = line.rstrip()
-+                    line = escape_c_comments(line)
-+                    # FuncNode.funcgen_implementation treats lines ending in ':'
-+                    # as C blocks, which messes up the formatting.
-+                    # Work around this:
-+                    if line.endswith(':'):
-+                        line += ' '
-+                    yield ' * %4d : %s' % (startline + i, line)
-+                yield ' */'
-+
-+        label = graph.startblock.get_base_label(self.blocknum[graph.startblock])
-+        yield 'goto %s;' % label # to avoid a warning "this label is not used"
-+
-+        # Sort the blocks into a (hopefully) readable order:
-+        blocks = list(graph.iterblocks_by_source())
-+        blocks.sort(block_comparator)
- 
-         # generate the body of each block
--        for block in graph.iterblocks():
-+        for block in blocks:
-+            cursrcloc = None
-             myblocknum = self.blocknum[block]
-             yield ''
--            yield 'block%d:' % myblocknum
-+            yield '%s:' % block.get_base_label(myblocknum)
-+            #yield "/* repr(block): %r */" % (block, )
-+            #yield "/* type(block): %r */" % (type(block), )
-             for i, op in enumerate(block.operations):
-+                #yield "/* type(op): %r */" % (type(op), )
-+                #yield "/* op.oploc: %s */" % (op.oploc, )
-+                codeloc = op.oploc.codelocs[-1]
-+                if codeloc:
-+                    srcloc = codeloc.get_source_loc()
-+                    if srcloc != cursrcloc:
-+                        try:
-+                            yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text()))
-+                            cursrcloc = srcloc
-+                        except IOError:
-+                            pass
-+
-                 for line in self.gen_op(op):
-                     yield line
-             if len(block.exits) == 0:
-@@ -310,7 +387,7 @@
-             assignments.append((a2typename, dest, src))
-         for line in gen_assignments(assignments):
-             yield line
--        label = 'block%d' % self.blocknum[link.target]
-+        label = link.target.get_base_label(self.blocknum[link.target])
-         if link.target in self.innerloops:
-             loop = self.innerloops[link.target]
-             if link is loop.links[-1]:   # link that ends a loop
-diff -r cd083843b67a pypy/translator/c/test/test_genc.py
---- a/pypy/translator/c/test/test_genc.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/c/test/test_genc.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -1,4 +1,5 @@
- import autopath, sys, os, py
-+import re
- from pypy.rpython.lltypesystem.lltype import *
- from pypy.annotation import model as annmodel
- from pypy.translator.translator import TranslationContext
-@@ -498,3 +499,130 @@
-     else:
-         assert 0, "the call was not found in the C source"
-     assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1]
-+
-+def get_generated_c_source(fn, types):
-+    # Return a (optimized fn, c source code, c source filename) 3-tuple
-+    t = Translation(fn)
-+    t.annotate(types)
-+    c_filename_path = t.source_c()
-+    h = c_filename_path.open()
-+    src = h.read()
-+    h.close()
-+    c_fn = t.compile_c()
-+    return (c_fn, src, c_filename_path)
-+
-+def extract_c_function(c_src, fname):
-+    # Extract the source for a given C function out of a the given src string
-+    # Makes assumptions about the layout of the source
-+    pattern = '^(.+) \**%s\(.*\) {$' % fname
-+    within_fn = False
-+    result = ''
-+    for line in c_src.splitlines():
-+        if within_fn:
-+            result += line + '\n'
-+            if line.startswith('}'):
-+                return result
-+        else:
-+            m = re.match(pattern, line)
-+            if m:
-+                within_fn = True
-+                result += line + '\n'
-+    return result
-+    
-+    
-+
-+def test_generated_c_source():
-+    # Verify that generate C source "looks good"
-+    # We'll use is_perfect_number, as it contains a loop and a conditional
-+
-+    # Generate C source code
-+    from pypy.translator.test.snippet import is_perfect_number
-+    c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number,
-+                                                        [int])
-+
-+    # Locate the C source for the type-specialized function:
-+    c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number')
-+    
-+    # Verify that the C source contains embedded comments containing the lines
-+    # of the python source:
-+    expected_comment_lines = [
-+        '/* is_perfect_number:31 :     while div < n: */',
-+        '/* is_perfect_number:32 :         if n % div == 0: */',
-+        '/* is_perfect_number:33 :             sum += div */',
-+        '/* is_perfect_number:34 :         div += 1 */',
-+        '/* is_perfect_number:35 :     return n == sum */']
-+    for exp_line in expected_comment_lines:
-+        assert exp_line in c_fn_src
-+        
-+    # Verify that the lines occur in the correct order
-+    # ...we do this by filtering the function's generated C source to just
-+    # those lines containing our comments (and dropping whitespace):
-+    lines = c_fn_src.splitlines()
-+    lines = [line.strip()
-+             for line in lines
-+             if '/* is_perfect_number:' in line]
-+
-+    # ...we should now have exact equality: the ordering should be as expected,
-+    # and each comment should appear exactly once:
-+    assert lines == expected_comment_lines
-+
-+    # Ensure that the generated C function does the right thing:
-+    assert c_fn(5) == False
-+    assert c_fn(6) == True
-+    assert c_fn(7) == False
-+
-+    assert c_fn(5.0) == False
-+    assert c_fn(6.0) == True
-+    assert c_fn(7.0) == False
-+
-+    assert c_fn(5L) == False
-+    assert c_fn(6L) == True
-+    assert c_fn(7L) == False
-+
-+    try:
-+        c_fn('hello world')
-+    except:
-+        pass
-+    else:
-+        raise 'Was expected exception'
-+    
-+def test_escaping_c_comments():
-+    # Ensure that c comments within RPython code get escaped when we generate
-+    # our .c code (to avoid generating bogus C)
-+    # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a
-+    # docstring embedding a C comment
-+    def c_style_comment(a, b):
-+        '''Here is a C-style comment within an RPython docstring:
-+                /* hello world */
-+        '''
-+        # and here's one in a string literal:
-+        return '/* hello world a:%s b:%s */' % (a, b)
-+
-+    def cplusplus_style_comment(a, b):
-+        '''Here is a C++-style comment within an RPython docstring:
-+                // hello world
-+        '''
-+        # and here are some in string literals, and one as the floor division
-+        # operator:
-+        return '// hello world: a // b = %s' % (a // b)
-+
-+    for fn_name, exp_output in [('c_style_comment',
-+                                 '/* hello world a:6 b:3 */'),
-+                                ('cplusplus_style_comment',
-+                                 '// hello world: a // b = 2')]:
-+        fn = locals()[fn_name]
-+
-+        c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int])
-+        # If the above survived, then the C compiler managed to handle
-+        # the generated C code
-+
-+        # Verify that the generated code works (i.e. that we didn't
-+        # accidentally change the meaning):
-+        assert c_fn(6, 3) == exp_output
-+
-+        # Ensure that at least part of the docstrings made it into the C
-+        # code:
-+        c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name)
-+        assert 'Here is a ' in c_fn_src
-+        assert 'style comment within an RPython docstring' in c_fn_src
-+        
-diff -r cd083843b67a pypy/translator/driver.py
---- a/pypy/translator/driver.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/driver.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -539,6 +539,7 @@
-             dstname = self.compute_exe_name() + '.staticdata.info'
-             shutil.copy(str(fname), str(dstname))
-             self.log.info('Static data info written to %s' % dstname)
-+        return c_source_filename
- 
-     #
-     task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
-diff -r cd083843b67a pypy/translator/gensupp.py
---- a/pypy/translator/gensupp.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/gensupp.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -16,8 +16,8 @@
-     def visit(block):
-         if isinstance(block, Block):
-             # first we order by offset in the code string
--            if block.operations:
--                ofs = block.operations[0].offset
-+            if block.operations and block.operations[0].oploc.codelocs[0]:
-+                ofs = block.operations[0].oploc.codelocs[0].offset
-             else:
-                 ofs = sys.maxint
-             # then we order by input variable name or value
-diff -r cd083843b67a pypy/translator/interactive.py
---- a/pypy/translator/interactive.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/interactive.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -138,7 +138,7 @@
-     def source_c(self, argtypes=None, **kwds):
-         self.update_options(argtypes, kwds)
-         self.ensure_backend('c')
--        self.driver.source_c()
-+        return self.driver.source_c()
- 
-     def source_cl(self, argtypes=None, **kwds):
-         self.update_options(argtypes, kwds)
-diff -r cd083843b67a pypy/translator/llsupport/wrapper.py
---- a/pypy/translator/llsupport/wrapper.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/llsupport/wrapper.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -59,6 +59,8 @@
-     # "return result"
-     block = Block(wrapper_inputargs)
-     wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
-+    if hasattr(graph, 'func'):
-+        wgraph.func = graph.func
-     translator.update_call_graph(wgraph, graph, object())
-     translator.graphs.append(wgraph)
-     block.operations[:] = newops
-diff -r cd083843b67a pypy/translator/simplify.py
---- a/pypy/translator/simplify.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/simplify.py	Wed Jan 05 16:14:35 2011 -0500
-@@ -294,7 +294,7 @@
-                 return renaming.get(v, v)
-             def rename_op(op):
-                 args = [rename(a) for a in op.args]
--                op = SpaceOperation(op.opname, args, rename(op.result), op.offset)
-+                op = SpaceOperation(op.opname, args, rename(op.result), op.oploc)
-                 # special case...
-                 if op.opname == 'indirect_call':
-                     if isinstance(op.args[0], Constant):
diff --git a/pypy-1.5-config.patch b/pypy-1.5-config.patch
new file mode 100644
index 0000000..82d8fc9
--- /dev/null
+++ b/pypy-1.5-config.patch
@@ -0,0 +1,39 @@
+diff -up pypy-1.5-src/pypy/translator/platform/linux.py.configure-fedora pypy-1.5-src/pypy/translator/platform/linux.py
+--- pypy-1.5-src/pypy/translator/platform/linux.py.configure-fedora	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/platform/linux.py	2011-04-30 18:59:24.041160978 -0400
+@@ -1,13 +1,18 @@
+ """Support for Linux."""
+-
++import os
+ from pypy.translator.platform.posix import BasePosix
+ 
++CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
++          '-Wall', '-Wno-unused']
++if os.environ.get('CFLAGS', None):
++    CFLAGS.extend(os.environ['CFLAGS'].split())
++CFLAGS = tuple(CFLAGS)
++
+ class BaseLinux(BasePosix):
+     name = "linux"
+     
+     link_flags = ('-pthread', '-lrt')
+-    cflags = ('-O3', '-pthread', '-fomit-frame-pointer',
+-              '-Wall', '-Wno-unused')
++    cflags = CFLAGS
+     standalone_only = ()
+     shared_only = ('-fPIC',)
+     so_ext = 'so'
+@@ -29,9 +34,10 @@ class Linux(BaseLinux):
+     shared_only = ()    # it seems that on 32-bit linux, compiling with -fPIC
+                         # gives assembler that asmgcc is not happy about.
+ 
+-    def library_dirs_for_libffi_a(self):
+-        # places where we need to look for libffi.a
+-        return self.library_dirs_for_libffi() + ['/usr/lib']
++    # Fedora Linux, at least, has the shared version but not the static
++    #def library_dirs_for_libffi_a(self):
++    #    # places where we need to look for libffi.a
++    #    return self.library_dirs_for_libffi() + ['/usr/lib']
+ 
+ 
+ class Linux64(BaseLinux):
diff --git a/pypy-1.5-more-readable-c-code.patch b/pypy-1.5-more-readable-c-code.patch
new file mode 100644
index 0000000..b7103e2
--- /dev/null
+++ b/pypy-1.5-more-readable-c-code.patch
@@ -0,0 +1,693 @@
+diff -up pypy-1.5-src/pypy/interpreter/pycode.py.more-readable-c-code pypy-1.5-src/pypy/interpreter/pycode.py
+--- pypy-1.5-src/pypy/interpreter/pycode.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/interpreter/pycode.py	2011-05-02 14:28:33.942161002 -0400
+@@ -13,6 +13,7 @@ from pypy.interpreter.gateway import Non
+ from pypy.interpreter.astcompiler.consts import (CO_OPTIMIZED,
+     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
+     CO_GENERATOR, CO_CONTAINSGLOBALS)
++from pypy.interpreter.pytraceback import offset2lineno
+ from pypy.rlib.rarithmetic import intmask
+ from pypy.rlib.debug import make_sure_not_resized
+ from pypy.rlib import jit
+@@ -80,6 +81,7 @@ class PyCode(eval.Code):
+         self.hidden_applevel = hidden_applevel
+         self.magic = magic
+         self._signature = cpython_code_signature(self)
++        self._cached_source = None
+         self._initialize()
+ 
+     def _initialize(self):
+@@ -396,3 +398,23 @@ class PyCode(eval.Code):
+ 
+     def repr(self, space):
+         return space.wrap(self.get_repr())
++
++    def get_linenum_for_offset(self, offset):
++        # Given a bytecode offset, return a 1-based index into the lines of the
++        # source code
++        return offset2lineno(self, offset)
++
++    def _ensure_source(self):
++        # Lazily grab the source lines into self._cached_source (or raise
++        # an IOError)
++        if not self._cached_source:
++            f = open(self.co_filename, 'r')
++            source = [line.rstrip() for line in f.readlines()]
++            f.close()
++            self._cached_source = source
++    
++    def get_source_text(self, linenum):
++        # Given a 1-based index, get the corresponding line of source code (or
++        # raise an IOError)
++        self._ensure_source()
++        return self._cached_source[linenum - 1]
+diff -up pypy-1.5-src/pypy/objspace/flow/model.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/model.py
+--- pypy-1.5-src/pypy/objspace/flow/model.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/objspace/flow/model.py	2011-05-02 14:28:33.942161002 -0400
+@@ -31,6 +31,120 @@ from pypy.tool.identity_dict import iden
+ 
+ __metaclass__ = type
+ 
++class SourceLoc(object):
++    # A srcloc is a specific location within the RPython source code,
++    # intended for human display
++    __slots__ = ('code', # code object
++                 'linenum' # 1-based index, as displayed to a user
++                 )
++    def __init__(self, code, linenum):
++        self.code = code
++        self.linenum = linenum
++
++    def get_text(self):
++        # Get the actual source text of this line
++        return self.code.get_source_text(self.linenum)
++
++    def __eq__(self, other):
++        return self.code == other.code and self.linenum == other.linenum
++
++    def __ne__(self, other):
++        if other:
++            return self.code != other.code or self.linenum != other.linenum
++        else:
++            return True
++
++class CodeLoc(object):
++    # A codeloc is a specific location within the RPython bytecode
++    __slots__ = ('code', # code object
++                 'offset' # int index into bytecode, or -1
++                 )
++
++    def __init__(self, code, offset):
++        self.code = code
++        self.offset = offset
++
++    def __str__(self):
++        if self.offset >= 0:
++            return "%s@%d" % (self.code.co_name, self.offset)
++        else:
++            return ""
++
++    def __ne__(self, other):
++        if other:
++            return self.code != other.code or self.offset != other.offset
++        else:
++            return True
++
++    def __cmp__(self, other):
++        # Partial ordering, for those locations that have an offset:
++        if other:
++            if self.offset >= 0 and other.offset >= 0:
++                return self.offset - other.offset
++        return 0
++
++    def get_source_loc(self):
++        # Convert to a SourceLoc:
++        return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset))
++
++class OperationLoc(object):
++    # An oploc is the location within the RPython source code of a given
++    # operation
++    # 
++    # This is a list consisting of CodeLoc instances, some of which may be None
++    #
++    # For the simple case, this is list of length 1 with a single CodeLoc
++    #
++    # For an operation inside an inlined callsite, we have a list of length 2:
++    #    [codeloc of callsite,
++    #     codeloc of operation within inlined body]
++    #
++    # For more interesting inlined cases, we have a chain of source locations:
++    #    [codeloc of callsite,
++    #     codeloc of inner callsite,
++    #     ... ,
++    #     codeloc of innermost inlined callsite,
++    #     codeloc of operation within inlined body]
++    #
++
++    __slots__ = ('codelocs', )
++
++    def __init__(self, codelocs):
++        self.codelocs = codelocs
++
++    def __str__(self):
++        return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']'
++
++    def __cmp__(self, other):
++        return cmp(self.codelocs, other.codelocs)
++
++def block_comparator(blk0, blk1):
++    '''
++    Sort function for blocks, putting them in an ordering that attempts to
++    maximize readability of the generated C code
++    '''
++    # print 'comparing %r and %r' % (blk0, blk1)
++    # Put the start/end block at the top/bottom:
++    if blk0.isstartblock:
++        return -1
++
++    if blk1.isstartblock:
++        return 1
++
++    # Order blocks by the offset, where present:
++    if blk0.operations:
++        if blk1.operations:
++            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
++        else:
++            return -1
++    else:
++        if blk1.operations:
++            return 1
++        else:
++            return 0
++
++def edge_comparator(edge0, edge1):
++    return block_comparator(edge0.target, edge1.target)
+ 
+ class FunctionGraph(object):
+     __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__']
+@@ -94,6 +208,21 @@ class FunctionGraph(object):
+                 seen[block] = True
+                 stack += block.exits[::-1]
+ 
++    def iterblocks_by_source(self):
++        # Try to preserve logical source ordering in the blocks
++        block = self.startblock
++        yield block
++        seen = {block: True}
++        stack = list(block.exits[::-1])
++        stack.sort(edge_comparator)
++        while stack:
++            block = stack.pop().target
++            if block not in seen:
++                yield block
++                seen[block] = True
++                stack += block.exits[::-1]
++                stack.sort(edge_comparator)
++
+     def iterlinks(self):
+         block = self.startblock
+         seen = {block: True}
+@@ -183,14 +312,14 @@ class Block(object):
+         self.exits      = []              # list of Link(s)
+ 
+     def at(self):
+-        if self.operations and self.operations[0].offset >= 0:
+-            return "@%d" % self.operations[0].offset
++        if self.operations:
++            return str(self.operations[0].oploc)
+         else:
+             return ""
+ 
+     def __str__(self):
+         if self.operations:
+-            txt = "block@%d" % self.operations[0].offset
++            txt = "block%s" % self.operations[0].oploc
+         else:
+             if (not self.exits) and len(self.inputargs) == 1:
+                 txt = "return block"
+@@ -245,6 +374,21 @@ class Block(object):
+         from pypy.translator.tool.graphpage import try_show
+         try_show(self)
+ 
++    def isreturnblock(self):
++        return (not self.operations) and (not self.exits) and len(self.inputargs) == 1
++
++    def get_base_label(self, blocknum):
++        # Generate a more friendly C label for this block
++        if self.operations:
++            txt = "block"
++        elif (not self.exits) and len(self.inputargs) == 1:
++            txt = "return_block"
++        elif (not self.exits) and len(self.inputargs) == 2:
++            txt = "raise_block"
++        else:
++            txt = "codeless_block"
++        return '%s%d' % (txt, blocknum)
++
+ 
+ class Variable(object):
+     __slots__ = ["_name", "_nr", "concretetype"]
+@@ -331,13 +475,15 @@ class WrapException(Exception):
+ 
+ 
+ class SpaceOperation(object):
+-    __slots__ = "opname args result offset".split()
++    __slots__ = "opname args result oploc".split()
+ 
+-    def __init__(self, opname, args, result, offset=-1):
++    def __init__(self, opname, args, result, oploc=None):
+         self.opname = intern(opname)      # operation name
+         self.args   = list(args)  # mixed list of var/const
+         self.result = result      # either Variable or Constant instance
+-        self.offset = offset      # offset in code string
++        if oploc is None:
++            oploc = OperationLoc([None])
++        self.oploc = oploc
+ 
+     def __eq__(self, other):
+         return (self.__class__ is other.__class__ and 
+@@ -352,8 +498,9 @@ class SpaceOperation(object):
+         return hash((self.opname,tuple(self.args),self.result))
+ 
+     def __repr__(self):
+-        return "%r = %s(%s)" % (self.result, self.opname,
+-                                ", ".join(map(repr, self.args)))
++        return "%r = %s(%s) (%s)" % (self.result, self.opname,
++                                     ", ".join(map(repr, self.args)),
++                                     self.oploc)
+ 
+ class Atom(object):
+     def __init__(self, name):
+@@ -427,8 +574,7 @@ def copygraph(graph, shallow=False, varm
+                 for op in oplist:
+                     copyop = SpaceOperation(op.opname,
+                                             [copyvar(v) for v in op.args],
+-                                            copyvar(op.result), op.offset)
+-                    #copyop.offset = op.offset
++                                            copyvar(op.result), op.oploc)
+                     result.append(copyop)
+                 return result
+             newblock.operations = copyoplist(block.operations)
+diff -up pypy-1.5-src/pypy/objspace/flow/objspace.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/objspace.py
+--- pypy-1.5-src/pypy/objspace/flow/objspace.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/objspace/flow/objspace.py	2011-05-02 14:28:33.943161001 -0400
+@@ -313,7 +313,9 @@ class FlowObjSpace(ObjSpace):
+     def do_operation(self, name, *args_w):
+         spaceop = SpaceOperation(name, args_w, Variable())
+         if hasattr(self, 'executioncontext'):  # not here during bootstrapping
+-            spaceop.offset = self.executioncontext.crnt_offset
++            codeloc = CodeLoc(self.executioncontext.code,
++                              self.executioncontext.crnt_offset)
++            spaceop.oploc = OperationLoc([codeloc])
+             self.executioncontext.recorder.append(spaceop)
+         return spaceop.result
+ 
+diff -up pypy-1.5-src/pypy/objspace/flow/test/test_model.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/test/test_model.py
+--- pypy-1.5-src/pypy/objspace/flow/test/test_model.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/objspace/flow/test/test_model.py	2011-05-02 14:28:33.943161001 -0400
+@@ -119,3 +119,25 @@ def test_variable():
+     assert v2.renamed
+     assert v2.name.startswith("foobar_") and v2.name != v.name
+     assert v2.name.split('_', 1)[1].isdigit()
++
++def test_source_locations():
++    # Invent some random offsets into the code:
++    co = sample_function.__code__
++    codelocA = CodeLoc(co, 42)
++    codelocB = CodeLoc(co, 87)
++
++    assert str(codelocA) == 'sample_function at 42'
++    assert str(codelocB) == 'sample_function at 87'
++
++    assert cmp(codelocA, codelocB) < 0
++    assert cmp(codelocB, codelocA) > 0
++    
++    oplocA = OperationLoc([codelocA])
++    oplocB = OperationLoc([codelocB])
++
++    assert str(oplocA) == '[sample_function at 42]'
++    assert str(oplocB) == '[sample_function at 87]'
++
++    assert cmp(oplocA, oplocB) < 0
++    assert cmp(oplocB, oplocA) > 0
++
+diff -up pypy-1.5-src/pypy/rpython/rtyper.py.more-readable-c-code pypy-1.5-src/pypy/rpython/rtyper.py
+--- pypy-1.5-src/pypy/rpython/rtyper.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/rpython/rtyper.py	2011-05-02 14:28:33.943161001 -0400
+@@ -800,7 +800,7 @@ class HighLevelOp(object):
+         return vars
+ 
+     def genop(self, opname, args_v, resulttype=None):
+-        return self.llops.genop(opname, args_v, resulttype)
++        return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc)
+ 
+     def gendirectcall(self, ll_function, *args_v):
+         return self.llops.gendirectcall(ll_function, *args_v)
+@@ -935,7 +935,7 @@ class LowLevelOpList(list):
+                                                     v.concretetype))
+         return v
+ 
+-    def genop(self, opname, args_v, resulttype=None):
++    def genop(self, opname, args_v, resulttype=None, oploc=None):
+         try:
+             for v in args_v:
+                 v.concretetype
+@@ -944,7 +944,7 @@ class LowLevelOpList(list):
+                                  " and pass its result to genop(),"
+                                  " never hop.args_v directly.")
+         vresult = Variable()
+-        self.append(SpaceOperation(opname, args_v, vresult))
++        self.append(SpaceOperation(opname, args_v, vresult, oploc))
+         if resulttype is None:
+             vresult.concretetype = Void
+             return None
+diff -up pypy-1.5-src/pypy/translator/backendopt/inline.py.more-readable-c-code pypy-1.5-src/pypy/translator/backendopt/inline.py
+--- pypy-1.5-src/pypy/translator/backendopt/inline.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/backendopt/inline.py	2011-05-02 14:32:26.975161005 -0400
+@@ -4,6 +4,7 @@ from pypy.translator.simplify import get
+ from pypy.translator.unsimplify import copyvar
+ from pypy.objspace.flow.model import Variable, Constant, Block, Link
+ from pypy.objspace.flow.model import SpaceOperation, c_last_exception
++from pypy.objspace.flow.model import OperationLoc
+ from pypy.objspace.flow.model import FunctionGraph
+ from pypy.objspace.flow.model import mkentrymap, checkgraph
+ from pypy.annotation import model as annmodel
+@@ -231,6 +232,7 @@ class BaseInliner(object):
+         self.varmap = {}
+         self._copied_blocks = {}
+         self.op = block.operations[index_operation]
++        self.callsite_oploc = self.op.oploc
+         self.graph_to_inline = self.get_graph_from_op(self.op)
+         self.exception_guarded = False
+         if (block.exitswitch == c_last_exception and
+@@ -290,7 +292,9 @@ class BaseInliner(object):
+         
+     def copy_operation(self, op):
+         args = [self.get_new_name(arg) for arg in op.args]
+-        result = SpaceOperation(op.opname, args, self.get_new_name(op.result))
++        new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:])
++        result = SpaceOperation(op.opname, args, self.get_new_name(op.result), 
++                                new_oploc)
+         return result
+ 
+     def copy_block(self, block):
+diff -up pypy-1.5-src/pypy/translator/c/funcgen.py.more-readable-c-code pypy-1.5-src/pypy/translator/c/funcgen.py
+--- pypy-1.5-src/pypy/translator/c/funcgen.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/c/funcgen.py	2011-05-02 14:28:33.944161001 -0400
+@@ -1,4 +1,6 @@
+ import sys
++import inspect
++import dis
+ from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
+ from pypy.translator.c.support import cdecl
+ from pypy.translator.c.support import llvalue_from_constant, gen_assignments
+@@ -22,6 +24,38 @@ LOCALVAR = 'l_%s'
+ 
+ KEEP_INLINED_GRAPHS = False
+ 
++def block_comparator(blk0, blk1):
++    '''
++    Sort function for blocks, putting them in an ordering that attempts to
++    maximize readability of the generated C code
++    '''
++    # print 'comparing %r and %r' % (blk0, blk1)
++    # Put the start/end block at the top/bottom:
++    if blk0.isstartblock:
++        return -1
++
++    if blk1.isstartblock:
++        return 1
++
++    # Order blocks by the offset, where present:
++    if blk0.operations:
++        if blk1.operations:
++            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
++        else:
++            return -1
++    else:
++        if blk1.operations:
++            return 1
++        else:
++            return 0
++
++def escape_c_comments(py_src):
++    # Escape C comments within RPython source, to avoid generating bogus
++    # comments in our generated C source:
++    py_src = py_src.replace('/*', '')
++    py_src = py_src.replace('*/', '')
++    return py_src
++
+ class FunctionCodeGenerator(object):
+     """
+     Collects information about a function which we have to generate
+@@ -210,14 +244,57 @@ class FunctionCodeGenerator(object):
+ 
+     def cfunction_body(self):
+         graph = self.graph
+-        yield 'goto block0;'    # to avoid a warning "this label is not used"
++        # Try to print python source code:
++        if hasattr(graph, 'func'):
++            filename = inspect.getfile(graph.func)
++            #yield '/* name: %r */' % filename
++            try:
++                src, startline = inspect.getsourcelines(graph.func)
++            except IOError:
++                pass # No source found
++            except IndexError:
++                pass # Bulletproofing
++            else:
++                yield '/* Python source %r' % filename
++                for i, line in enumerate(src):
++                    line = line.rstrip()
++                    line = escape_c_comments(line)
++                    # FuncNode.funcgen_implementation treats lines ending in ':'
++                    # as C blocks, which messes up the formatting.
++                    # Work around this:
++                    if line.endswith(':'):
++                        line += ' '
++                    yield ' * %4d : %s' % (startline + i, line)
++                yield ' */'
++
++        label = graph.startblock.get_base_label(self.blocknum[graph.startblock])
++        yield 'goto %s;' % label # to avoid a warning "this label is not used"
++
++        # Sort the blocks into a (hopefully) readable order:
++        blocks = list(graph.iterblocks_by_source())
++        blocks.sort(block_comparator)
+ 
+         # generate the body of each block
+-        for block in graph.iterblocks():
++        for block in blocks:
++            cursrcloc = None
+             myblocknum = self.blocknum[block]
+             yield ''
+-            yield 'block%d:' % myblocknum
++            yield '%s:' % block.get_base_label(myblocknum)
++            #yield "/* repr(block): %r */" % (block, )
++            #yield "/* type(block): %r */" % (type(block), )
+             for i, op in enumerate(block.operations):
++                #yield "/* type(op): %r */" % (type(op), )
++                #yield "/* op.oploc: %s */" % (op.oploc, )
++                codeloc = op.oploc.codelocs[-1]
++                if codeloc:
++                    srcloc = codeloc.get_source_loc()
++                    if srcloc != cursrcloc:
++                        try:
++                            yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text()))
++                            cursrcloc = srcloc
++                        except IOError:
++                            pass
++
+                 for line in self.gen_op(op):
+                     yield line
+             if len(block.exits) == 0:
+@@ -309,7 +386,7 @@ class FunctionCodeGenerator(object):
+             assignments.append((a2typename, dest, src))
+         for line in gen_assignments(assignments):
+             yield line
+-        label = 'block%d' % self.blocknum[link.target]
++        label = link.target.get_base_label(self.blocknum[link.target])
+         if link.target in self.innerloops:
+             loop = self.innerloops[link.target]
+             if link is loop.links[-1]:   # link that ends a loop
+diff -up pypy-1.5-src/pypy/translator/c/test/test_genc.py.more-readable-c-code pypy-1.5-src/pypy/translator/c/test/test_genc.py
+--- pypy-1.5-src/pypy/translator/c/test/test_genc.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/c/test/test_genc.py	2011-05-02 14:28:33.945161001 -0400
+@@ -1,4 +1,5 @@
+ import autopath, sys, os, py
++import re
+ from pypy.rpython.lltypesystem.lltype import *
+ from pypy.annotation import model as annmodel
+ from pypy.translator.translator import TranslationContext
+@@ -515,3 +516,130 @@ def test_inhibit_tail_call():
+     else:
+         assert 0, "the call was not found in the C source"
+     assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1]
++
++def get_generated_c_source(fn, types):
++    # Return a (optimized fn, c source code, c source filename) 3-tuple
++    t = Translation(fn)
++    t.annotate(types)
++    c_filename_path = t.source_c()
++    h = c_filename_path.open()
++    src = h.read()
++    h.close()
++    c_fn = t.compile_c()
++    return (c_fn, src, c_filename_path)
++
++def extract_c_function(c_src, fname):
++    # Extract the source for a given C function out of a the given src string
++    # Makes assumptions about the layout of the source
++    pattern = '^(.+) \**%s\(.*\) {$' % fname
++    within_fn = False
++    result = ''
++    for line in c_src.splitlines():
++        if within_fn:
++            result += line + '\n'
++            if line.startswith('}'):
++                return result
++        else:
++            m = re.match(pattern, line)
++            if m:
++                within_fn = True
++                result += line + '\n'
++    return result
++    
++    
++
++def test_generated_c_source():
++    # Verify that generate C source "looks good"
++    # We'll use is_perfect_number, as it contains a loop and a conditional
++
++    # Generate C source code
++    from pypy.translator.test.snippet import is_perfect_number
++    c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number,
++                                                        [int])
++
++    # Locate the C source for the type-specialized function:
++    c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number')
++    
++    # Verify that the C source contains embedded comments containing the lines
++    # of the python source:
++    expected_comment_lines = [
++        '/* is_perfect_number:31 :     while div < n: */',
++        '/* is_perfect_number:32 :         if n % div == 0: */',
++        '/* is_perfect_number:33 :             sum += div */',
++        '/* is_perfect_number:34 :         div += 1 */',
++        '/* is_perfect_number:35 :     return n == sum */']
++    for exp_line in expected_comment_lines:
++        assert exp_line in c_fn_src
++        
++    # Verify that the lines occur in the correct order
++    # ...we do this by filtering the function's generated C source to just
++    # those lines containing our comments (and dropping whitespace):
++    lines = c_fn_src.splitlines()
++    lines = [line.strip()
++             for line in lines
++             if '/* is_perfect_number:' in line]
++
++    # ...we should now have exact equality: the ordering should be as expected,
++    # and each comment should appear exactly once:
++    assert lines == expected_comment_lines
++
++    # Ensure that the generated C function does the right thing:
++    assert c_fn(5) == False
++    assert c_fn(6) == True
++    assert c_fn(7) == False
++
++    assert c_fn(5.0) == False
++    assert c_fn(6.0) == True
++    assert c_fn(7.0) == False
++
++    assert c_fn(5L) == False
++    assert c_fn(6L) == True
++    assert c_fn(7L) == False
++
++    try:
++        c_fn('hello world')
++    except:
++        pass
++    else:
++        raise 'Was expected exception'
++    
++def test_escaping_c_comments():
++    # Ensure that c comments within RPython code get escaped when we generate
++    # our .c code (to avoid generating bogus C)
++    # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a
++    # docstring embedding a C comment
++    def c_style_comment(a, b):
++        '''Here is a C-style comment within an RPython docstring:
++                /* hello world */
++        '''
++        # and here's one in a string literal:
++        return '/* hello world a:%s b:%s */' % (a, b)
++
++    def cplusplus_style_comment(a, b):
++        '''Here is a C++-style comment within an RPython docstring:
++                // hello world
++        '''
++        # and here are some in string literals, and one as the floor division
++        # operator:
++        return '// hello world: a // b = %s' % (a // b)
++
++    for fn_name, exp_output in [('c_style_comment',
++                                 '/* hello world a:6 b:3 */'),
++                                ('cplusplus_style_comment',
++                                 '// hello world: a // b = 2')]:
++        fn = locals()[fn_name]
++
++        c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int])
++        # If the above survived, then the C compiler managed to handle
++        # the generated C code
++
++        # Verify that the generated code works (i.e. that we didn't
++        # accidentally change the meaning):
++        assert c_fn(6, 3) == exp_output
++
++        # Ensure that at least part of the docstrings made it into the C
++        # code:
++        c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name)
++        assert 'Here is a ' in c_fn_src
++        assert 'style comment within an RPython docstring' in c_fn_src
++        
+diff -up pypy-1.5-src/pypy/translator/driver.py.more-readable-c-code pypy-1.5-src/pypy/translator/driver.py
+--- pypy-1.5-src/pypy/translator/driver.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/driver.py	2011-05-02 14:28:33.945161001 -0400
+@@ -536,6 +536,7 @@ class TranslationDriver(SimpleTaskEngine
+             dstname = self.compute_exe_name() + '.staticdata.info'
+             shutil.copy(str(fname), str(dstname))
+             self.log.info('Static data info written to %s' % dstname)
++        return c_source_filename
+ 
+     #
+     task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
+diff -up pypy-1.5-src/pypy/translator/gensupp.py.more-readable-c-code pypy-1.5-src/pypy/translator/gensupp.py
+--- pypy-1.5-src/pypy/translator/gensupp.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/gensupp.py	2011-05-02 14:33:31.026161001 -0400
+@@ -14,8 +14,8 @@ def ordered_blocks(graph):
+     allblocks = []
+     for block in graph.iterblocks():
+             # first we order by offset in the code string
+-            if block.operations:
+-                ofs = block.operations[0].offset
++            if block.operations and block.operations[0].oploc.codelocs[0]:
++                ofs = block.operations[0].oploc.codelocs[0].offset
+             else:
+                 ofs = sys.maxint
+             # then we order by input variable name or value
+diff -up pypy-1.5-src/pypy/translator/interactive.py.more-readable-c-code pypy-1.5-src/pypy/translator/interactive.py
+--- pypy-1.5-src/pypy/translator/interactive.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/interactive.py	2011-05-02 14:28:33.946161001 -0400
+@@ -138,7 +138,7 @@ class Translation(object):
+     def source_c(self, argtypes=None, **kwds):
+         self.update_options(argtypes, kwds)
+         self.ensure_backend('c')
+-        self.driver.source_c()
++        return self.driver.source_c()
+ 
+     def source_cl(self, argtypes=None, **kwds):
+         self.update_options(argtypes, kwds)
+diff -up pypy-1.5-src/pypy/translator/llsupport/wrapper.py.more-readable-c-code pypy-1.5-src/pypy/translator/llsupport/wrapper.py
+--- pypy-1.5-src/pypy/translator/llsupport/wrapper.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/llsupport/wrapper.py	2011-05-02 14:28:33.946161001 -0400
+@@ -59,6 +59,8 @@ def new_wrapper(func, translator, newnam
+     # "return result"
+     block = Block(wrapper_inputargs)
+     wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
++    if hasattr(graph, 'func'):
++        wgraph.func = graph.func
+     translator.update_call_graph(wgraph, graph, object())
+     translator.graphs.append(wgraph)
+     block.operations[:] = newops
+diff -up pypy-1.5-src/pypy/translator/simplify.py.more-readable-c-code pypy-1.5-src/pypy/translator/simplify.py
+--- pypy-1.5-src/pypy/translator/simplify.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
++++ pypy-1.5-src/pypy/translator/simplify.py	2011-05-02 14:28:33.952161001 -0400
+@@ -298,7 +298,7 @@ def join_blocks(graph):
+                 return renaming.get(v, v)
+             def rename_op(op):
+                 args = [rename(a) for a in op.args]
+-                op = SpaceOperation(op.opname, args, rename(op.result), op.offset)
++                op = SpaceOperation(op.opname, args, rename(op.result), op.oploc)
+                 # special case...
+                 if op.opname == 'indirect_call':
+                     if isinstance(op.args[0], Constant):
diff --git a/pypy.spec b/pypy.spec
index c69893a..1a651e0 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
-Version:        1.4.1
-Release:        10%{?dist}
+Version:        1.5
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -105,7 +105,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 %global verbose_logs 0
 
 %global pypyprefix %{_libdir}/pypy-%{version}
-%global pylibver 2.5.2
+%global pylibver 2.7
 
 # We refer to this subdir of the source tree in a few places during the build:
 %global goal_dir pypy/translator/goal
@@ -120,7 +120,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Source0:        http://pypy.org/download/pypy-%{version}-src.tar.bz2
 
 # Edit a translator file for linux in order to configure our cflags and dynamic libffi
-Patch0:         pypy-1.4-config.patch
+Patch0:         pypy-1.5-config.patch
 
 # By default, if built at a tty, the translation process renders a Mandelbrot
 # set to indicate progress.
@@ -150,7 +150,7 @@ Patch3: pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
 #  http://codespeak.net/pipermail/pypy-dev/2010q4/006532.html
 # TODO: get this into the upstream bug tracker, and finish inlining
 # support (rhbz#666963)
-Patch4: pypy-1.4.1-more-readable-c-code.patch
+Patch4: pypy-1.5-more-readable-c-code.patch
 
 
 # Build-time requirements:
@@ -584,7 +584,7 @@ mkdir -p %{buildroot}/%{pypyprefix}/site-packages
 # interface going forward, so let's just mimic upstream for now.
 %global pypy_include_dir  %{pypyprefix}/include
 mkdir -p %{buildroot}/%{pypy_include_dir}
-cp include/*.h include/*.inl %{buildroot}/%{pypy_include_dir}
+cp include/*.h %{buildroot}/%{pypy_include_dir}
 
 
 # Capture the RPython source code files from the build within the debuginfo
@@ -698,6 +698,25 @@ CheckPyPy() {
       #   seems to hang on this test, within test_line_terminator
       SkipTest test_asynchat
 
+      # test_audioop:
+      #     test test_audioop crashed -- <type 'exceptions.ImportError'>: No module named audioop
+      #     Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/regrtest.py", line 874, in runtest_inner
+      #         the_package = __import__(abstest, globals(), locals(), [])
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_audioop.py", line 1, in <module>
+      #         import audioop
+      #     ImportError: No module named audioop
+      SkipTest test_audioop
+
+      # test_capi:
+      #   RPython traceback:
+      #     RPython traceback:
+      #       File "implement.c", line 243013, in _PyObject_New
+      #       File "implement_1.c", line 31707, in _PyObject_NewVar
+      #       File "implement.c", line 217060, in from_ref
+      #     Fatal RPython error: AssertionError
+      SkipTest test_capi
+
       # test_compiler:
       #   4 errors out of 13:
       #     testSourceCodeEncodingsError
@@ -710,10 +729,102 @@ CheckPyPy() {
       #   failures=17, errors=20, out of 132 tests
       SkipTest test_ctypes
 
+      # test_distutils:
+      #     Warning -- os.environ was modified by test_distutils
+      #     test test_distutils failed -- multiple errors occurred; run in verbose mode for details
+      SkipTest test_distutils
+
       # test_frozen:
       #   TestFailed: import __hello__ failed:No module named __hello__
       SkipTest test_frozen
 
+      # test_gc:
+      #     test test_gc crashed -- <type 'exceptions.AttributeError'>: 'module' object has no attribute 'get_debug'
+      SkipTest test_gc
+
+      # test_gdb:
+      #     test test_gdb crashed -- <type 'exceptions.KeyError'>: 'PY_CFLAGS'
+      SkipTest test_gdb
+
+      # test_generators:
+      #     **********************************************************************
+      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine
+      #     Failed example:
+      #         del g; gc_collect()
+      #     Expected:
+      #         exiting
+      #     Got nothing
+      #     **********************************************************************
+      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine
+      #     Failed example:
+      #         del g; gc_collect()
+      #     Expected:
+      #         exiting
+      #     Got nothing
+      #     **********************************************************************
+      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine
+      #     Failed example:
+      #         del g; gc_collect()
+      #     Expected:
+      #         finally
+      #     Got nothing
+      #     **********************************************************************
+      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine
+      #     Failed example:
+      #         sys.stderr.getvalue().startswith(
+      #             "Exception RuntimeError: 'generator ignored GeneratorExit' in "
+      #         )
+      #     Expected:
+      #         True
+      #     Got:
+      #         False
+      #     **********************************************************************
+      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.refleaks
+      #     Failed example:
+      #         try:
+      #             sys.stderr = StringIO.StringIO()
+      #             class Leaker:
+      #                 def __del__(self):
+      #                     raise RuntimeError
+      #             l = Leaker()
+      #             del l
+      #             gc_collect()
+      #             err = sys.stderr.getvalue().strip()
+      #             err.startswith(
+      #                 "Exception RuntimeError: RuntimeError() in "
+      #             )
+      #             err.endswith("> ignored")
+      #             len(err.splitlines())
+      #         finally:
+      #             sys.stderr = old
+      #     Expected:
+      #         True
+      #         True
+      #         1
+      #     Got:
+      #         False
+      #         False
+      #         0
+      #     **********************************************************************
+      #     2 items had failures:
+      #        4 of 107 in test.test_generators.__test__.coroutine
+      #        1 of  11 in test.test_generators.__test__.refleaks
+      #     ***Test Failed*** 5 failures.
+      #     test test_generators failed -- 5 of 294 doctests failed
+      SkipTest test_generators
+
+      # test_getargs2:
+      #     test test_getargs2 failed -- multiple errors occurred; run in verbose mode for details
+      SkipTest test_getargs2
+
+      # test_hotshot:
+      #     test test_hotshot crashed -- <type 'exceptions.ImportError'>: No module named _hotshot
+      SkipTest test_hotshot
+
+      # test_io:
+      #     test test_io failed -- multiple errors occurred; run in verbose mode for details
+      SkipTest test_io
+
       # test_ioctl:
       #   Failing in Koji with dist-f15 with:
       #     ======================================================================
@@ -737,6 +848,23 @@ CheckPyPy() {
       #   24 failures out of 25, apparently all due to TypeError
       SkipTest test_iterlen
 
+      # test_multiprocessing:
+      #     test test_multiprocessing failed -- multiple errors occurred; run in verbose mode for details
+      SkipTest test_multiprocessing
+
+      # test_module:
+      #     test test_module failed -- Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_module.py", line 81, in test_clear_dict_in_ref_cycle
+      #         self.assertEqual(destroyed, [1])
+      #     AssertionError: Lists differ: [] != [1]
+      #     Second list contains 1 additional elements.
+      #     First extra element 0:
+      #     1
+      #     - []
+      #     + [1]
+      #     ?  +
+      SkipTest test_module
+
       # test_parser:
       #   12 failures out of 15
       SkipTest test_parser
@@ -746,6 +874,44 @@ CheckPyPy() {
       #    test test_platform failed -- errors occurred in test.test_platform.PlatformTest
       SkipTest test_platform
 
+      # test_posix:
+      #     test test_posix failed -- Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 361, in test_getcwd_long_pathnames
+      #         _create_and_do_getcwd(dirname)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd
+      #         _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd
+      #         _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
+      #       [...repeats...]
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd
+      #         _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 356, in _create_and_do_getcwd
+      #         self.assertEqual(e.errno, expected_errno)
+      #     AssertionError: 36 != 34
+      SkipTest test_posix
+
+      # test_readline:
+      #     test test_readline failed -- Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_readline.py", line 16, in testHistoryUpdates
+      #         readline.clear_history()
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/readline.py", line 277, in clear_history
+      #         del self.get_reader().history[:]
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/readline.py", line 186, in get_reader
+      #         console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/unix_console.py", line 103, in __init__
+      #         self._clear = _my_getstr("clear")
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/unix_console.py", line 45, in _my_getstr
+      #         "terminal doesn't have the required '%s' capability"%cap
+      #     InvalidTerminal: terminal doesn't have the required 'clear' capability
+      SkipTest test_readline
+
+      # test_scope:
+      #     test test_scope failed -- Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_scope.py", line 437, in testLeaks
+      #         self.assertEqual(Foo.count, 0)
+      #     AssertionError: 100 != 0
+      SkipTest test_scope
+
       # test_socket:
       #   testSockName can fail in Koji with:
       #       my_ip_addr = socket.gethostbyname(socket.gethostname())
@@ -761,10 +927,138 @@ CheckPyPy() {
       #     ProgrammingError: Incomplete statement ''
       SkipTest test_sqlite
 
+      # test_strop:
+      #     test test_strop crashed -- <type 'exceptions.ImportError'>: No module named strop
+      SkipTest test_strop
+
+      # test_structmembers:
+      #     test test_structmembers failed -- multiple errors occurred; run in verbose mode for details
+      SkipTest test_structmembers
+
+      # test_subprocess:
+      #     debug: WARNING: library path not found, using compiled-in sys.path and sys.prefix will be unset
+      #     'import site' failed
+      #     .
+      #         this bit of output is from a test of stdout in a different process ...
+      #     /builddir/build/BUILD/pypy-1.5-src/lib_pypy/ctypes_support.py:26: RuntimeWarning: C function without declared arguments called
+      #       return standard_c_lib.__errno_location()
+      #     debug: WARNING: library path not found, using compiled-in sys.path and sys.prefix will be unset
+      #     'import site' failed
+      #     .
+      #         this bit of output is from a test of stdout in a different process ...
+      #     test test_subprocess failed -- multiple errors occurred; run in verbose mode for details
+      SkipTest test_subprocess
+
+      # test_symtable:
+      #     test test_symtable crashed -- <type 'exceptions.ImportError'>: No module named _symtable
+      SkipTest test_symtable
+
+      # test_sys_settrace:
+      #     test test_sys_settrace failed -- Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 334, in test_13_genexp
+      #         self.run_test(generator_example)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 280, in run_test
+      #         self.run_and_compare(func, func.events)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 277, in run_and_compare
+      #         tracer.events, events)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 269, in compare_events
+      #         [str(x) for x in events])))
+      #     AssertionError: events did not match expectation:
+      #       (0, 'call')
+      #       (2, 'line')
+      #       (-6, 'call')
+      #       (-5, 'line')
+      #       (-4, 'line')
+      #       (-4, 'return')
+      #     - (-4, 'call')
+      #     - (-4, 'exception')
+      #     - (-1, 'line')
+      #     - (-1, 'return')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (6, 'line')
+      #       (5, 'line')
+      #       (5, 'return')
+      SkipTest test_sys_settrace
+
+      # test_tempfile:
+      #     test test_tempfile failed -- multiple errors occurred; run in verbose mode for details
+      SkipTest test_tempfile
+
+      # test_thread
+      #   Koji build appears to hang here
+      SkipTest test_thread
+
       # test_traceback:
       #   works when run standalone; failures seen when run as part of a suite
       SkipTest test_traceback
 
+      # test_uuid:
+      #     ======================================================================
+      #     ERROR: test_ifconfig_getnode (test.test_uuid.TestUUID)
+      #     ----------------------------------------------------------------------
+      #     Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_uuid.py", line 306, in test_ifconfig_getnode
+      #         node = uuid._ifconfig_getnode()
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/uuid.py", line 326, in _ifconfig_getnode
+      #         ip_addr = socket.gethostbyname(socket.gethostname())
+      #     gaierror: [Errno -3] Temporary failure in name resolution
+      #     ----------------------------------------------------------------------
+      #     Ran 14 tests in 0.369s
+      #     FAILED (errors=1)
+      SkipTest test_uuid
+
+      # test_zipimport_support:
+      #     ======================================================================
+      #     ERROR: test_doctest_main_issue4197 (test.test_zipimport_support.ZipSupportTests)
+      #     ----------------------------------------------------------------------
+      #     Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_zipimport_support.py", line 194, in test_doctest_main_issue4197
+      #         exit_code, data = run_python(script_name)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 80, in run_python
+      #         p = spawn_python(*args, **kwargs)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 66, in spawn_python
+      #         **kwargs)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 672, in __init__
+      #         errread, errwrite)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 1206, in _execute_child
+      #         raise child_exception
+      #     OSError: [Errno 13] Permission denied
+      #     ======================================================================
+      #     ERROR: test_pdb_issue4201 (test.test_zipimport_support.ZipSupportTests)
+      #     ----------------------------------------------------------------------
+      #     Traceback (most recent call last):
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_zipimport_support.py", line 221, in test_pdb_issue4201
+      #         p = spawn_python(script_name)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 66, in spawn_python
+      #         **kwargs)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 672, in __init__
+      #         errread, errwrite)
+      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 1206, in _execute_child
+      #         raise child_exception
+      #     OSError: [Errno 13] Permission denied
+      #     ----------------------------------------------------------------------
+      #     Ran 4 tests in 0.726s
+      #     FAILED (errors=2)
+      SkipTest test_zipimport_support
+
       # test_zlib:
       #   failure seen in Koji, not sure of reason why:
       #     test test_zlib failed -- Traceback (most recent call last):
@@ -832,6 +1126,8 @@ rm -rf $RPM_BUILD_ROOT
 
 %dir %{pypyprefix}
 %dir %{pypyprefix}/lib-python
+%{pypyprefix}/lib-python/TODO
+%{pypyprefix}/lib-python/stdlib-version.txt
 %{pypyprefix}/lib-python/%{pylibver}/
 %{pypyprefix}/lib-python/modified-%{pylibver}/
 %{pypyprefix}/lib-python/conftest.py*
@@ -847,7 +1143,6 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %dir %{pypy_include_dir}
 %{pypy_include_dir}/*.h
-%{pypy_include_dir}/*.inl
 
 %if 0%{with_stackless}
 %files stackless
@@ -858,6 +1153,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon May  2 2011 David Malcolm <dmalcolm at redhat.com> - 1.5-1
+- 1.5
+
 * Wed Apr 20 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-10
 - build a /usr/bin/pypy (but without the JIT compiler) on architectures that
 don't support the JIT, so that they do at least have something that runs
diff --git a/sources b/sources
index 90f34be..a047407 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-ebbbb156b1eb842e9e65d909ed5f9f6d  pypy-1.4.1-src.tar.bz2
+cb9ada2c50666318c3a2863da1fbe487  pypy-1.5-src.tar.bz2
-- 
cgit v0.10.2


From 3d2cef177d26ff303a5be984f912e2b8d4266b0d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Hor=C3=A1k?= <dan at danny.cz>
Date: Wed, 11 May 2011 10:15:52 +0200
Subject: fix build on non-jit arches

Build on non-jit arch like s390 fails with

[translation:info] Translating target as defined by targetpypystandalone
[platform:msg] Setting platform to 'host' cc=None
Traceback (most recent call last):
  File "translate.py", line 322, in <module>
    main()
  File "translate.py", line 208, in main
    targetspec_dic, translateconfig, config, args = parse_options_and_load_target()
  File "translate.py", line 176, in parse_options_and_load_target
    targetspec_dic['handle_config'](config, translateconfig)
  File "targetpypystandalone.py", line 109, in handle_config
    raise Exception("You have to specify the --opt level.\n"
Exception: You have to specify the --opt level.
Try --opt=2 or --opt=jit, or equivalently -O2 or -Ojit .

diff --git a/pypy.spec b/pypy.spec
index 1a651e0..b4705c1 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -431,6 +431,8 @@ BuildPyPy \
   pypy \
 %if 0%{with_jit}
   "-Ojit" \
+%else
+  "-O2" \
 %endif
   %{nil}
 
-- 
cgit v0.10.2


From 1feef4d56b6572b03fd805e50ad8f6e43900cfac Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Wed, 3 Aug 2011 13:02:57 -0400
Subject: add pypytrace-mode.el to the pypy-libs subpackage, for viewing JIT
 trace logs in emacs


diff --git a/pypy.spec b/pypy.spec
index b4705c1..0c2c717 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.5
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -223,6 +223,9 @@ BuildRequires:  gc-devel
 
 BuildRequires:  /usr/bin/execstack
 
+# For byte-compiling the JIT-viewing mode:
+BuildRequires:  emacs
+
 # pypy is bundling these so we delete them in %%prep.  I don't think they are
 # needed unless we build pypy targetted at running on the jvm.
 #BuildRequires:  jna
@@ -248,6 +251,11 @@ CPU architecture.
 %package libs
 Group:    Development/Languages
 Summary:  Run-time libraries used by PyPy implementations of Python
+
+# We supply an emacs mode for the JIT viewer.
+# (This doesn't bring in all of emacs, just the directory structure)
+Requires: emacs-filesystem >= %{_emacs_version}
+
 %description libs
 Libraries required by the various PyPy implementations of Python.
 
@@ -442,6 +450,8 @@ BuildPyPy \
    "--stackless"
 %endif
 
+%{_emacs_bytecompile} pypy/jit/tool/pypytrace-mode.el
+
 %install
 rm -rf $RPM_BUILD_ROOT
 
@@ -617,6 +627,10 @@ find \
 # but given that the objective is to preserve a copy of the source code, those
 # are acceptable.
 
+# Install the JIT trace mode for Emacs:
+mkdir -p %{buildroot}/%{_emacs_sitelispdir}
+cp -a pypy/jit/tool/pypytrace-mode.el* %{buildroot}/%{_emacs_sitelispdir}
+
 %check
 topdir=$(pwd)
 
@@ -1135,6 +1149,8 @@ rm -rf $RPM_BUILD_ROOT
 %{pypyprefix}/lib-python/conftest.py*
 %{pypyprefix}/lib_pypy/
 %{pypyprefix}/site-packages/
+%{_emacs_sitelispdir}/pypytrace-mode.el
+%{_emacs_sitelispdir}/pypytrace-mode.elc
 
 %files
 %defattr(-,root,root,-)
@@ -1155,6 +1171,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Aug  2 2011 David Malcolm <dmalcolm at redhat.com> - 1.5-2
+- add pypytrace-mode.el to the pypy-libs subpackage, for viewing JIT trace
+logs in emacs
+
 * Mon May  2 2011 David Malcolm <dmalcolm at redhat.com> - 1.5-1
 - 1.5
 
-- 
cgit v0.10.2


From 3a2c2ec86de943a3dbdc8de5608e6a8f79c48a85 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Fri, 19 Aug 2011 19:04:38 -0400
Subject: pypy-1.6-1

- 1.6
- rewrite the %check section, introducing per-test timeouts

diff --git a/.gitignore b/.gitignore
index 017cf34..ecd135f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 /pypy-1.4.1-src.tar.bz2
 /pypy-1.5-src.tar.bz2
+/release-1.6.tar.bz2
diff --git a/pypy.spec b/pypy.spec
index 0c2c717..c3faabb 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
-Version:        1.5
-Release:        2%{?dist}
+Version:        1.6
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -104,6 +104,9 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 # Easy way to enable/disable verbose logging:
 %global verbose_logs 0
 
+# Easy way to turn off the selftests:
+%global run_selftests 1
+
 %global pypyprefix %{_libdir}/pypy-%{version}
 %global pylibver 2.7
 
@@ -117,7 +120,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:        http://pypy.org/download/pypy-%{version}-src.tar.bz2
+Source0:        https://bitbucket.org/pypy/pypy/get/release-1.6.tar.bz2
 
 # Edit a translator file for linux in order to configure our cflags and dynamic libffi
 Patch0:         pypy-1.5-config.patch
@@ -218,9 +221,17 @@ BuildRequires:  openssl-devel
 BuildRequires:  valgrind-devel
 %endif
 
+%if %{run_selftests}
 # Used by the selftests, though not by the build:
 BuildRequires:  gc-devel
 
+# For use in the selftests, for recording stats:
+BuildRequires:  time
+
+# For use in the selftests, for imposing a per-test timeout:
+BuildRequires:  perl
+%endif
+
 BuildRequires:  /usr/bin/execstack
 
 # For byte-compiling the JIT-viewing mode:
@@ -289,7 +300,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-%{version}-src
+%setup -q -n pypy-pypy-release-%{version}
 %patch0 -p1 -b .configure-fedora
 %patch1 -p1 -b .suppress-mandelbrot-set-during-tty-build
 
@@ -656,445 +667,47 @@ CheckPyPy() {
 
     pushd %{goal_dir}
 
-    # Gather a list of tests to skip, due to known failures
-    # TODO: report these failures to pypy upstream
-    # See also rhbz#666967 and rhbz#666969
-    TESTS_TO_SKIP=""
-
-    # Test failures relating to missing codecs
-    # Hopefully when pypy merges to 2.7 support we'll gain these via a
-    # refreshed stdlib:
-      # test_codecencodings_cn:
-      #   all tests fail, with one of
-      #     unknown encoding: gb18030
-      #     unknown encoding: gb2312
-      #     unknown encoding: gbk
-      SkipTest test_codecencodings_cn
-
-      # test_codecencodings_hk:
-      #   all tests fail, with:
-      #     unknown encoding: big5hkscs
-      SkipTest test_codecencodings_hk
-
-      # test_codecencodings_jp:
-      #   all tests fail, with one of:
-      #     unknown encoding: cp932
-      #     unknown encoding: euc_jisx0213
-      #     unknown encoding: euc_jp
-      #     unknown encoding: shift_jis
-      #     unknown encoding: shift_jisx0213
-      SkipTest test_codecencodings_jp
-
-      # test_codecencodings_kr:
-      #   all tests fail, with one of:
-      #     unknown encoding: cp949
-      #     unknown encoding: euc_kr
-      #     unknown encoding: johab
-      SkipTest test_codecencodings_kr
-
-      # test_codecencodings_tw:
-      #    all tests fail, with:
-      #      unknown encoding: big5
-      SkipTest test_codecencodings_tw
-
-      # test_multibytecodec:
-      #   14 failures out of 15, due to:
-      #     unknown encoding: euc-kr
-      #     unknown encoding: gb2312
-      #     unknown encoding: jisx0213
-      #     unknown encoding: cp949
-      #     unknown encoding: iso2022-jp
-      #     unknown encoding: gb18030
-      SkipTest test_multibytecodec
-
-    #
-    # Other failures:
-    #
-      # test_asynchat:
-      #   seems to hang on this test, within test_line_terminator
-      SkipTest test_asynchat
-
-      # test_audioop:
-      #     test test_audioop crashed -- <type 'exceptions.ImportError'>: No module named audioop
-      #     Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/regrtest.py", line 874, in runtest_inner
-      #         the_package = __import__(abstest, globals(), locals(), [])
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_audioop.py", line 1, in <module>
-      #         import audioop
-      #     ImportError: No module named audioop
-      SkipTest test_audioop
-
-      # test_capi:
-      #   RPython traceback:
-      #     RPython traceback:
-      #       File "implement.c", line 243013, in _PyObject_New
-      #       File "implement_1.c", line 31707, in _PyObject_NewVar
-      #       File "implement.c", line 217060, in from_ref
-      #     Fatal RPython error: AssertionError
-      SkipTest test_capi
-
-      # test_compiler:
-      #   4 errors out of 13:
-      #     testSourceCodeEncodingsError
-      #     testWith
-      #     testWithAss
-      #     testYieldExpr
-      SkipTest test_compiler
-
-      # test_ctypes:
-      #   failures=17, errors=20, out of 132 tests
-      SkipTest test_ctypes
-
-      # test_distutils:
-      #     Warning -- os.environ was modified by test_distutils
-      #     test test_distutils failed -- multiple errors occurred; run in verbose mode for details
-      SkipTest test_distutils
-
-      # test_frozen:
-      #   TestFailed: import __hello__ failed:No module named __hello__
-      SkipTest test_frozen
-
-      # test_gc:
-      #     test test_gc crashed -- <type 'exceptions.AttributeError'>: 'module' object has no attribute 'get_debug'
-      SkipTest test_gc
-
-      # test_gdb:
-      #     test test_gdb crashed -- <type 'exceptions.KeyError'>: 'PY_CFLAGS'
-      SkipTest test_gdb
-
-      # test_generators:
-      #     **********************************************************************
-      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine
-      #     Failed example:
-      #         del g; gc_collect()
-      #     Expected:
-      #         exiting
-      #     Got nothing
-      #     **********************************************************************
-      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine
-      #     Failed example:
-      #         del g; gc_collect()
-      #     Expected:
-      #         exiting
-      #     Got nothing
-      #     **********************************************************************
-      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine
-      #     Failed example:
-      #         del g; gc_collect()
-      #     Expected:
-      #         finally
-      #     Got nothing
-      #     **********************************************************************
-      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine
-      #     Failed example:
-      #         sys.stderr.getvalue().startswith(
-      #             "Exception RuntimeError: 'generator ignored GeneratorExit' in "
-      #         )
-      #     Expected:
-      #         True
-      #     Got:
-      #         False
-      #     **********************************************************************
-      #     File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.refleaks
-      #     Failed example:
-      #         try:
-      #             sys.stderr = StringIO.StringIO()
-      #             class Leaker:
-      #                 def __del__(self):
-      #                     raise RuntimeError
-      #             l = Leaker()
-      #             del l
-      #             gc_collect()
-      #             err = sys.stderr.getvalue().strip()
-      #             err.startswith(
-      #                 "Exception RuntimeError: RuntimeError() in "
-      #             )
-      #             err.endswith("> ignored")
-      #             len(err.splitlines())
-      #         finally:
-      #             sys.stderr = old
-      #     Expected:
-      #         True
-      #         True
-      #         1
-      #     Got:
-      #         False
-      #         False
-      #         0
-      #     **********************************************************************
-      #     2 items had failures:
-      #        4 of 107 in test.test_generators.__test__.coroutine
-      #        1 of  11 in test.test_generators.__test__.refleaks
-      #     ***Test Failed*** 5 failures.
-      #     test test_generators failed -- 5 of 294 doctests failed
-      SkipTest test_generators
-
-      # test_getargs2:
-      #     test test_getargs2 failed -- multiple errors occurred; run in verbose mode for details
-      SkipTest test_getargs2
-
-      # test_hotshot:
-      #     test test_hotshot crashed -- <type 'exceptions.ImportError'>: No module named _hotshot
-      SkipTest test_hotshot
-
-      # test_io:
-      #     test test_io failed -- multiple errors occurred; run in verbose mode for details
-      SkipTest test_io
-
-      # test_ioctl:
-      #   Failing in Koji with dist-f15 with:
-      #     ======================================================================
-      #     FAIL: test_ioctl (test.test_ioctl.IoctlTests)
-      #     ----------------------------------------------------------------------
-      #     Traceback (most recent call last):
-      #       File "/usr/lib/pypy-1.4.1/lib-python/2.5.2/test/test_ioctl.py", line 25, in test_ioctl
-      #         self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
-      #     AssertionError: 0 not in (8304, 17737)
-      #     ======================================================================
-      #     FAIL: test_ioctl_mutate (test.test_ioctl.IoctlTests)
-      #     ----------------------------------------------------------------------
-      #     Traceback (most recent call last):
-      #       File "/usr/lib/pypy-1.4.1/lib-python/2.5.2/test/test_ioctl.py", line 35, in test_ioctl_mutate
-      #         self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
-      #     AssertionError: 0 not in (8304, 17737)
-      #     ----------------------------------------------------------------------
-      SkipTest test_ioctl
-
-      # test_iterlen:
-      #   24 failures out of 25, apparently all due to TypeError
-      SkipTest test_iterlen
-
-      # test_multiprocessing:
-      #     test test_multiprocessing failed -- multiple errors occurred; run in verbose mode for details
-      SkipTest test_multiprocessing
-
-      # test_module:
-      #     test test_module failed -- Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_module.py", line 81, in test_clear_dict_in_ref_cycle
-      #         self.assertEqual(destroyed, [1])
-      #     AssertionError: Lists differ: [] != [1]
-      #     Second list contains 1 additional elements.
-      #     First extra element 0:
-      #     1
-      #     - []
-      #     + [1]
-      #     ?  +
-      SkipTest test_module
-
-      # test_parser:
-      #   12 failures out of 15
-      SkipTest test_parser
-
-      # test_platform:
-      #   Koji builds show:
-      #    test test_platform failed -- errors occurred in test.test_platform.PlatformTest
-      SkipTest test_platform
-
-      # test_posix:
-      #     test test_posix failed -- Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 361, in test_getcwd_long_pathnames
-      #         _create_and_do_getcwd(dirname)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd
-      #         _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd
-      #         _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
-      #       [...repeats...]
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd
-      #         _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 356, in _create_and_do_getcwd
-      #         self.assertEqual(e.errno, expected_errno)
-      #     AssertionError: 36 != 34
-      SkipTest test_posix
-
-      # test_readline:
-      #     test test_readline failed -- Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_readline.py", line 16, in testHistoryUpdates
-      #         readline.clear_history()
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/readline.py", line 277, in clear_history
-      #         del self.get_reader().history[:]
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/readline.py", line 186, in get_reader
-      #         console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/unix_console.py", line 103, in __init__
-      #         self._clear = _my_getstr("clear")
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/unix_console.py", line 45, in _my_getstr
-      #         "terminal doesn't have the required '%s' capability"%cap
-      #     InvalidTerminal: terminal doesn't have the required 'clear' capability
-      SkipTest test_readline
-
-      # test_scope:
-      #     test test_scope failed -- Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_scope.py", line 437, in testLeaks
-      #         self.assertEqual(Foo.count, 0)
-      #     AssertionError: 100 != 0
-      SkipTest test_scope
-
-      # test_socket:
-      #   testSockName can fail in Koji with:
-      #       my_ip_addr = socket.gethostbyname(socket.gethostname())
-      #     gaierror: (-3, 'Temporary failure in name resolution')
-      SkipTest test_socket
-
-      # test_sort:
-      #   some failures
-      SkipTest test_sort
-
-      # test_sqlite:
-      #   3 of the sqlite3.test.dbapi.ExtensionTests raise:
-      #     ProgrammingError: Incomplete statement ''
-      SkipTest test_sqlite
-
-      # test_strop:
-      #     test test_strop crashed -- <type 'exceptions.ImportError'>: No module named strop
-      SkipTest test_strop
-
-      # test_structmembers:
-      #     test test_structmembers failed -- multiple errors occurred; run in verbose mode for details
-      SkipTest test_structmembers
-
-      # test_subprocess:
-      #     debug: WARNING: library path not found, using compiled-in sys.path and sys.prefix will be unset
-      #     'import site' failed
-      #     .
-      #         this bit of output is from a test of stdout in a different process ...
-      #     /builddir/build/BUILD/pypy-1.5-src/lib_pypy/ctypes_support.py:26: RuntimeWarning: C function without declared arguments called
-      #       return standard_c_lib.__errno_location()
-      #     debug: WARNING: library path not found, using compiled-in sys.path and sys.prefix will be unset
-      #     'import site' failed
-      #     .
-      #         this bit of output is from a test of stdout in a different process ...
-      #     test test_subprocess failed -- multiple errors occurred; run in verbose mode for details
-      SkipTest test_subprocess
-
-      # test_symtable:
-      #     test test_symtable crashed -- <type 'exceptions.ImportError'>: No module named _symtable
-      SkipTest test_symtable
-
-      # test_sys_settrace:
-      #     test test_sys_settrace failed -- Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 334, in test_13_genexp
-      #         self.run_test(generator_example)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 280, in run_test
-      #         self.run_and_compare(func, func.events)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 277, in run_and_compare
-      #         tracer.events, events)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 269, in compare_events
-      #         [str(x) for x in events])))
-      #     AssertionError: events did not match expectation:
-      #       (0, 'call')
-      #       (2, 'line')
-      #       (-6, 'call')
-      #       (-5, 'line')
-      #       (-4, 'line')
-      #       (-4, 'return')
-      #     - (-4, 'call')
-      #     - (-4, 'exception')
-      #     - (-1, 'line')
-      #     - (-1, 'return')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (6, 'line')
-      #       (5, 'line')
-      #       (5, 'return')
-      SkipTest test_sys_settrace
-
-      # test_tempfile:
-      #     test test_tempfile failed -- multiple errors occurred; run in verbose mode for details
-      SkipTest test_tempfile
-
-      # test_thread
-      #   Koji build appears to hang here
-      SkipTest test_thread
-
-      # test_traceback:
-      #   works when run standalone; failures seen when run as part of a suite
-      SkipTest test_traceback
-
-      # test_uuid:
-      #     ======================================================================
-      #     ERROR: test_ifconfig_getnode (test.test_uuid.TestUUID)
-      #     ----------------------------------------------------------------------
-      #     Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_uuid.py", line 306, in test_ifconfig_getnode
-      #         node = uuid._ifconfig_getnode()
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/uuid.py", line 326, in _ifconfig_getnode
-      #         ip_addr = socket.gethostbyname(socket.gethostname())
-      #     gaierror: [Errno -3] Temporary failure in name resolution
-      #     ----------------------------------------------------------------------
-      #     Ran 14 tests in 0.369s
-      #     FAILED (errors=1)
-      SkipTest test_uuid
-
-      # test_zipimport_support:
-      #     ======================================================================
-      #     ERROR: test_doctest_main_issue4197 (test.test_zipimport_support.ZipSupportTests)
-      #     ----------------------------------------------------------------------
-      #     Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_zipimport_support.py", line 194, in test_doctest_main_issue4197
-      #         exit_code, data = run_python(script_name)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 80, in run_python
-      #         p = spawn_python(*args, **kwargs)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 66, in spawn_python
-      #         **kwargs)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 672, in __init__
-      #         errread, errwrite)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 1206, in _execute_child
-      #         raise child_exception
-      #     OSError: [Errno 13] Permission denied
-      #     ======================================================================
-      #     ERROR: test_pdb_issue4201 (test.test_zipimport_support.ZipSupportTests)
-      #     ----------------------------------------------------------------------
-      #     Traceback (most recent call last):
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_zipimport_support.py", line 221, in test_pdb_issue4201
-      #         p = spawn_python(script_name)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 66, in spawn_python
-      #         **kwargs)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 672, in __init__
-      #         errread, errwrite)
-      #       File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 1206, in _execute_child
-      #         raise child_exception
-      #     OSError: [Errno 13] Permission denied
-      #     ----------------------------------------------------------------------
-      #     Ran 4 tests in 0.726s
-      #     FAILED (errors=2)
-      SkipTest test_zipimport_support
-
-      # test_zlib:
-      #   failure seen in Koji, not sure of reason why:
-      #     test test_zlib failed -- Traceback (most recent call last):
-      #     File "/builddir/build/BUILD/pypy-1.4.1-src/lib-python/2.5.2/test/test_zlib.py", line 72, in test_baddecompressobj
-      #       self.assertRaises(ValueError, zlib.decompressobj, 0)
-      #     AssertionError: ValueError not raised
-      SkipTest test_zlib
-
-    %if 0%{use_self_when_building}
-    # Patch 3 prioritizes the installed copy of pypy's libraries over the
-    # build copy.
-    # This leads to test failures of test_pep263 and test_tarfile
-    # For now, suppress these when building using pypy itself:
-    SkipTest test_pep263   # on-disk encoding issues
-    SkipTest test_tarfile  # permissions issues
-    %endif
-
-    # Run the built binary through the selftests
-    # "-w" : re-run failed tests in verbose mode
-    time ./$ExeName -m test.regrtest -w -x $TESTS_TO_SKIP
+    # I'm seeing numerous cases where tests seem to hang, or fail unpredictably
+    # So we'll run each test in its own process, with a timeout
+
+    # Use regrtest to explicitly list all tests:
+    ( ./$ExeName -c \
+         "from test.regrtest import findtests; print '\n'.join(findtests())"
+    ) > testnames.txt
+
+    echo "== Test names =="
+    cat testnames.txt
+    echo "================="
+
+    echo "" > failed-tests.txt
+
+    for TestName in $(cat testnames.txt) ; do
+
+        echo "===================" $TestName "===================="
+
+        # Use /usr/bin/time (rather than the shell "time" builtin) to gather
+        # info on the process (time/CPU/memory).  This passes on the exit
+        # status of the underlying command
+        #
+        # Use perl's alarm command to impose a timeout
+        #   900 seconds is 15 minutes per test.
+        # If a test hangs, that test should get terminated, allowing the build
+        # to continue.
+        #
+        # Invoke pypy on test.regrtest to run the specific test suite
+        # verbosely
+        #
+        # For now, || true, so that any failures don't halt the build:
+        ( /usr/bin/time \
+           perl -e 'alarm shift @ARGV; exec @ARGV' 900 \
+             ./$ExeName -m test.regrtest -v $TestName ) \
+        || (echo $TestName >> failed-tests.txt) \
+        || true
+    done
+
+    echo "== Failed tests =="
+    cat failed-tests.txt
+    echo "================="
 
     popd
 
@@ -1124,12 +737,14 @@ CheckPyPy() {
     echo "--------------------------------------------------------------"
 }
 
+%if %{run_selftests}
 CheckPyPy pypy
 
 %if 0%{with_stackless}
 CheckPyPy pypy-stackless
 %endif
 
+%endif # run_selftests
 
 
 %clean
@@ -1142,7 +757,6 @@ rm -rf $RPM_BUILD_ROOT
 
 %dir %{pypyprefix}
 %dir %{pypyprefix}/lib-python
-%{pypyprefix}/lib-python/TODO
 %{pypyprefix}/lib-python/stdlib-version.txt
 %{pypyprefix}/lib-python/%{pylibver}/
 %{pypyprefix}/lib-python/modified-%{pylibver}/
@@ -1171,6 +785,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Aug 18 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-1
+- 1.6
+- rewrite the %%check section, introducing per-test timeouts
+
 * Tue Aug  2 2011 David Malcolm <dmalcolm at redhat.com> - 1.5-2
 - add pypytrace-mode.el to the pypy-libs subpackage, for viewing JIT trace
 logs in emacs
diff --git a/sources b/sources
index a047407..5660f1e 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-cb9ada2c50666318c3a2863da1fbe487  pypy-1.5-src.tar.bz2
+1189352effc5df7df84e6916b3b3eae3  release-1.6.tar.bz2
-- 
cgit v0.10.2


From 1df5c3e618c5f2bcbdbe44f329039dfffc1cd79e Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Sat, 20 Aug 2011 11:59:48 -0400
Subject: work around test_subprocess failure seen in koji (patch 5)


diff --git a/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch b/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
new file mode 100644
index 0000000..eb6f324
--- /dev/null
+++ b/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
@@ -0,0 +1,12 @@
+diff -up pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py.non-readable-path pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py
+--- pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py.non-readable-path	2011-08-20 11:46:31.410646024 -0400
++++ pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py	2011-08-20 11:46:39.421645476 -0400
+@@ -570,7 +570,7 @@ class ProcessTestCase(BaseTestCase):
+         for i in range(1024):
+             # Windows raises IOError.  Others raise OSError.
+             with self.assertRaises(EnvironmentError) as c:
+-                subprocess.Popen(['nonexisting_i_hope'],
++                subprocess.Popen(['/usr/bin/nonexisting_i_hope'],
+                                  stdout=subprocess.PIPE,
+                                  stderr=subprocess.PIPE)
+             if c.exception.errno != errno.ENOENT:  # ignore "no such file"
diff --git a/pypy.spec b/pypy.spec
index c3faabb..3280ff9 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.6
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -155,6 +155,16 @@ Patch3: pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
 # support (rhbz#666963)
 Patch4: pypy-1.5-more-readable-c-code.patch
 
+# In my koji builds, /root/bin is in the PATH for some reason
+# This leads to test_subprocess.py failing, due to "test_leaking_fds_on_error"
+# trying every dir in PATH for "nonexisting_i_hope", which leads to it raising
+#  OSError: [Errno 13] Permission denied
+# when it tries to read /root/bin, rather than raising "No such file"
+#
+# Work around this by specifying an absolute path for the non-existant
+# executable
+# Not yet sent upstream
+Patch5: pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
 
 # Build-time requirements:
 
@@ -318,6 +328,7 @@ sed -i \
 
 %patch4 -p1 -b .more-readable-c-code
 
+%patch5 -p1
 
 # Replace /usr/local/bin/python shebangs with /usr/bin/python:
 find -name "*.py" -exec \
@@ -785,6 +796,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sat Aug 20 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-2
+- work around test_subprocess failure seen in koji (patch 5)
+
 * Thu Aug 18 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-1
 - 1.6
 - rewrite the %%check section, introducing per-test timeouts
-- 
cgit v0.10.2


From afabd9d6bee5ad70b522d5d9c5745256ff46b827 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Thu, 25 Aug 2011 11:58:55 -0400
Subject: 1.6-3: add rpm macros file to the devel subpackage; skip some tests


diff --git a/macros.pypy b/macros.pypy
new file mode 100644
index 0000000..5f40b6f
--- /dev/null
+++ b/macros.pypy
@@ -0,0 +1,5 @@
+%__pypy /usr/bin/pypy
+%pypy_sitelib %(%{__pypy} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")
+%pypy_sitearch %(%{__pypy} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")
+%pypy_version %(%{__pypy} -c "import sys; sys.stdout.write(sys.version[:3])")
+%pypydir %{_builddir}/pypy-%{name}-%{version}-%{release}
diff --git a/pypy.spec b/pypy.spec
index 3280ff9..2c3e47c 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.6
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -122,6 +122,10 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 # Source and patches:
 Source0:        https://bitbucket.org/pypy/pypy/get/release-1.6.tar.bz2
 
+# Supply various useful RPM macros for building python modules against pypy:
+#  __pypy, pypy_sitelib, pypy_sitearch
+Source2:        macros.pypy
+
 # Edit a translator file for linux in order to configure our cflags and dynamic libffi
 Patch0:         pypy-1.5-config.patch
 
@@ -653,13 +657,16 @@ find \
 mkdir -p %{buildroot}/%{_emacs_sitelispdir}
 cp -a pypy/jit/tool/pypytrace-mode.el* %{buildroot}/%{_emacs_sitelispdir}
 
+# Install macros for rpm:
+mkdir -p %{buildroot}/%{_sysconfdir}/rpm
+install -m 644 %{SOURCE2} %{buildroot}/%{_sysconfdir}/rpm
+
 %check
 topdir=$(pwd)
 
 SkipTest() {
-    # Append the given test name to TESTS_TO_SKIP
     TEST_NAME=$1
-    TESTS_TO_SKIP="$TESTS_TO_SKIP $TEST_NAME"
+    sed -i -e"s|$TEST_NAME||" testnames.txt
 }
 
 CheckPyPy() {
@@ -686,6 +693,19 @@ CheckPyPy() {
          "from test.regrtest import findtests; print '\n'.join(findtests())"
     ) > testnames.txt
 
+    # Skip some tests:
+      # "audioop" doesn't exist for pypy yet:
+      SkipTest test_audioop
+
+      # The gdb CPython hooks haven't been ported to cpyext:
+      SkipTest test_gdb
+
+      # hotshot relies heavily on _hotshot, which doesn't exist:
+      SkipTest test_hotshot
+
+      # "strop" module doesn't exist for pypy yet:
+      SkipTest test_strop
+
     echo "== Test names =="
     cat testnames.txt
     echo "================="
@@ -786,6 +806,7 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %dir %{pypy_include_dir}
 %{pypy_include_dir}/*.h
+%config(noreplace) %{_sysconfdir}/rpm/macros.pypy
 
 %if 0%{with_stackless}
 %files stackless
@@ -796,6 +817,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-3
+- add rpm macros file to the devel subpackage (source 2)
+- skip some tests that can't pass yet
+
 * Sat Aug 20 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-2
 - work around test_subprocess failure seen in koji (patch 5)
 
-- 
cgit v0.10.2


From 106cb91275756dab4a44a6e75cd090ea57c6d5a7 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Thu, 25 Aug 2011 14:50:53 -0400
Subject: fix SkipTest function to avoid corrupting the name of "test_gdbm"


diff --git a/pypy.spec b/pypy.spec
index 2c3e47c..b303232 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.6
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -666,7 +666,7 @@ topdir=$(pwd)
 
 SkipTest() {
     TEST_NAME=$1
-    sed -i -e"s|$TEST_NAME||" testnames.txt
+    sed -i -e"s|^$TEST_NAME$||g" testnames.txt
 }
 
 CheckPyPy() {
@@ -817,6 +817,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-4
+- fix SkipTest function to avoid corrupting the name of "test_gdbm"
+
 * Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-3
 - add rpm macros file to the devel subpackage (source 2)
 - skip some tests that can't pass yet
-- 
cgit v0.10.2


From 009aeb1c2d9928be62c11bf154af0644f08816eb Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Mon, 12 Sep 2011 21:01:16 -0400
Subject: build using python26 on el5 (2.4 is too early)


diff --git a/pypy.spec b/pypy.spec
index b303232..9fc1462 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.6
-Release:        4%{?dist}
+Release:        5%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -213,10 +213,18 @@ Patch5: pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
 BuildRequires: pypy
 %global bootstrap_python_interp pypy
 %else
+
+# Python 2.6 or later is needed, so on RHEL5 (2.4) we need to use the alternate
+# python26 rpm:
+%if 0%{?rhel} == 5
+BuildRequires: python26-devel
+%global bootstrap_python_interp python26
+%else
 BuildRequires: python-devel
 %global bootstrap_python_interp python
 %endif
 
+%endif
 
 
 # FIXME: I'm seeing errors like this in the logs:
@@ -817,6 +825,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Sep 12 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-5
+- build using python26 on el5 (2.4 is too early)
+
 * Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-4
 - fix SkipTest function to avoid corrupting the name of "test_gdbm"
 
-- 
cgit v0.10.2


From 2d36a5e81680be23c3e25e9f4bff4737a550687f Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Tue, 13 Sep 2011 05:00:09 -0400
Subject: don't ship the emacs JIT-viewer on el5 and el6

* Tue Sep 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-6
- don't ship the emacs JIT-viewer on el5 and el6 (missing emacs-filesystem;
missing _emacs_bytecompile macro on el5)

diff --git a/pypy.spec b/pypy.spec
index 9fc1462..90b3f88 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.6
-Release:        5%{?dist}
+Release:        6%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -100,6 +100,12 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 # Should we build a "pypy-stackless" binary?
 %global with_stackless 0
 
+# Should we build the emacs JIT-viewing mode?
+%if 0%{?rhel} == 5 || 0%{?rhel} == 6
+%global with_emacs 0
+%else
+%global with_emacs 1
+%endif
 
 # Easy way to enable/disable verbose logging:
 %global verbose_logs 0
@@ -257,7 +263,9 @@ BuildRequires:  perl
 BuildRequires:  /usr/bin/execstack
 
 # For byte-compiling the JIT-viewing mode:
+%if %{with_emacs}
 BuildRequires:  emacs
+%endif
 
 # pypy is bundling these so we delete them in %%prep.  I don't think they are
 # needed unless we build pypy targetted at running on the jvm.
@@ -287,7 +295,9 @@ Summary:  Run-time libraries used by PyPy implementations of Python
 
 # We supply an emacs mode for the JIT viewer.
 # (This doesn't bring in all of emacs, just the directory structure)
+%if %{with_emacs}
 Requires: emacs-filesystem >= %{_emacs_version}
+%endif
 
 %description libs
 Libraries required by the various PyPy implementations of Python.
@@ -484,7 +494,9 @@ BuildPyPy \
    "--stackless"
 %endif
 
+%if %{with_emacs}
 %{_emacs_bytecompile} pypy/jit/tool/pypytrace-mode.el
+%endif
 
 %install
 rm -rf $RPM_BUILD_ROOT
@@ -662,8 +674,10 @@ find \
 # are acceptable.
 
 # Install the JIT trace mode for Emacs:
+%if %{with_emacs}
 mkdir -p %{buildroot}/%{_emacs_sitelispdir}
 cp -a pypy/jit/tool/pypytrace-mode.el* %{buildroot}/%{_emacs_sitelispdir}
+%endif
 
 # Install macros for rpm:
 mkdir -p %{buildroot}/%{_sysconfdir}/rpm
@@ -802,8 +816,10 @@ rm -rf $RPM_BUILD_ROOT
 %{pypyprefix}/lib-python/conftest.py*
 %{pypyprefix}/lib_pypy/
 %{pypyprefix}/site-packages/
+%if %{with_emacs}
 %{_emacs_sitelispdir}/pypytrace-mode.el
 %{_emacs_sitelispdir}/pypytrace-mode.elc
+%endif
 
 %files
 %defattr(-,root,root,-)
@@ -825,6 +841,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Sep 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-6
+- don't ship the emacs JIT-viewer on el5 and el6 (missing emacs-filesystem;
+missing _emacs_bytecompile macro on el5)
+
 * Mon Sep 12 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-5
 - build using python26 on el5 (2.4 is too early)
 
-- 
cgit v0.10.2


From 953cba8f403df754b658c3310b0505c1ba5dc5a5 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Tue, 4 Oct 2011 14:37:40 -0400
Subject: 1.6-7: skip test_multiprocessing

* Tue Oct  4 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-7
- skip test_multiprocessing

diff --git a/pypy.spec b/pypy.spec
index 90b3f88..2579860 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.6
-Release:        6%{?dist}
+Release:        7%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -728,6 +728,12 @@ CheckPyPy() {
       # "strop" module doesn't exist for pypy yet:
       SkipTest test_strop
 
+      # I'm seeing Koji builds hanging e.g.:
+      #   http://koji.fedoraproject.org/koji/getfile?taskID=3386821&name=build.log
+      # The only test that seems to have timed out in that log is
+      # test_multiprocessing, so skip it for now:
+      SkipTest test_multiprocessing
+
     echo "== Test names =="
     cat testnames.txt
     echo "================="
@@ -841,13 +847,15 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Oct  4 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-7
+- skip test_multiprocessing
+
 * Tue Sep 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-6
 - don't ship the emacs JIT-viewer on el5 and el6 (missing emacs-filesystem;
 missing _emacs_bytecompile macro on el5)
 
 * Mon Sep 12 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-5
 - build using python26 on el5 (2.4 is too early)
-
 * Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-4
 - fix SkipTest function to avoid corrupting the name of "test_gdbm"
 
-- 
cgit v0.10.2


From 4ef3f10721000d632a9dcfcfca05c7cde0f91b95 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Tue, 22 Nov 2011 11:30:49 -0500
Subject: 1.7

* Mon Nov 21 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-1
- 1.7: refresh patch 0 (configuration) and patch 4 (readability of generated
code)

diff --git a/.gitignore b/.gitignore
index ecd135f..99af398 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 /pypy-1.4.1-src.tar.bz2
 /pypy-1.5-src.tar.bz2
 /release-1.6.tar.bz2
+/release-1.7.tar.bz2
diff --git a/config.patch b/config.patch
new file mode 100644
index 0000000..afd7a7d
--- /dev/null
+++ b/config.patch
@@ -0,0 +1,49 @@
+diff -up pypy-pypy-release-1.7/pypy/translator/platform/linux.py.configure-fedora pypy-pypy-release-1.7/pypy/translator/platform/linux.py
+--- pypy-pypy-release-1.7/pypy/translator/platform/linux.py.configure-fedora	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/platform/linux.py	2011-11-21 13:07:03.454240019 -0500
+@@ -1,15 +1,21 @@
+ """Support for Linux."""
+ 
++import os
+ import sys
+ from pypy.translator.platform.posix import BasePosix
+ 
++CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
++          '-Wall', '-Wno-unused']
++if os.environ.get('CFLAGS', None):
++    CFLAGS.extend(os.environ['CFLAGS'].split())
++CFLAGS = tuple(CFLAGS)
++
+ class BaseLinux(BasePosix):
+     name = "linux"
+     
+     link_flags = ('-pthread',)
+     extra_libs = ('-lrt',)
+-    cflags = ('-O3', '-pthread', '-fomit-frame-pointer',
+-              '-Wall', '-Wno-unused')
++    cflags = CFLAGS
+     standalone_only = ()
+     shared_only = ('-fPIC',)
+     so_ext = 'so'
+@@ -26,13 +32,14 @@ class BaseLinux(BasePosix):
+         return self._pkg_config("libffi", "--libs-only-L",
+                                 ['/usr/lib/libffi'])
+ 
+-    def library_dirs_for_libffi_a(self):
+-        # places where we need to look for libffi.a
+-        # XXX obscuuure!  only look for libffi.a if run with translate.py
+-        if 'translate' in sys.modules:
+-            return self.library_dirs_for_libffi() + ['/usr/lib']
+-        else:
+-            return []
++    # Fedora, at least, has the shared version but not the static:
++    #def library_dirs_for_libffi_a(self):
++    #    # places where we need to look for libffi.a
++    #    # XXX obscuuure!  only look for libffi.a if run with translate.py
++    #    if 'translate' in sys.modules:
++    #        return self.library_dirs_for_libffi() + ['/usr/lib']
++    #    else:
++    #        return []
+ 
+ 
+ class Linux(BaseLinux):
diff --git a/more-readable-c-code.patch b/more-readable-c-code.patch
new file mode 100644
index 0000000..92d340f
--- /dev/null
+++ b/more-readable-c-code.patch
@@ -0,0 +1,693 @@
+diff -up pypy-pypy-release-1.7/pypy/interpreter/pycode.py.more-readable-c-code pypy-pypy-release-1.7/pypy/interpreter/pycode.py
+--- pypy-pypy-release-1.7/pypy/interpreter/pycode.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/interpreter/pycode.py	2011-11-21 16:16:15.673463780 -0500
+@@ -13,6 +13,7 @@ from pypy.interpreter.gateway import Non
+ from pypy.interpreter.astcompiler.consts import (
+     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
+     CO_GENERATOR, CO_CONTAINSGLOBALS)
++from pypy.interpreter.pytraceback import offset2lineno
+ from pypy.rlib.rarithmetic import intmask
+ from pypy.rlib.debug import make_sure_not_resized
+ from pypy.rlib import jit
+@@ -81,6 +82,7 @@ class PyCode(eval.Code):
+         self.hidden_applevel = hidden_applevel
+         self.magic = magic
+         self._signature = cpython_code_signature(self)
++        self._cached_source = None
+         self._initialize()
+ 
+     def _initialize(self):
+@@ -397,3 +399,23 @@ class PyCode(eval.Code):
+ 
+     def repr(self, space):
+         return space.wrap(self.get_repr())
++
++    def get_linenum_for_offset(self, offset):
++        # Given a bytecode offset, return a 1-based index into the lines of the
++        # source code
++        return offset2lineno(self, offset)
++
++    def _ensure_source(self):
++        # Lazily grab the source lines into self._cached_source (or raise
++        # an IOError)
++        if not self._cached_source:
++            f = open(self.co_filename, 'r')
++            source = [line.rstrip() for line in f.readlines()]
++            f.close()
++            self._cached_source = source
++    
++    def get_source_text(self, linenum):
++        # Given a 1-based index, get the corresponding line of source code (or
++        # raise an IOError)
++        self._ensure_source()
++        return self._cached_source[linenum - 1]
+diff -up pypy-pypy-release-1.7/pypy/objspace/flow/model.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/model.py
+--- pypy-pypy-release-1.7/pypy/objspace/flow/model.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/objspace/flow/model.py	2011-11-21 16:15:36.599466455 -0500
+@@ -31,6 +31,120 @@ from pypy.tool.identity_dict import iden
+ 
+ __metaclass__ = type
+ 
++class SourceLoc(object):
++    # A srcloc is a specific location within the RPython source code,
++    # intended for human display
++    __slots__ = ('code', # code object
++                 'linenum' # 1-based index, as displayed to a user
++                 )
++    def __init__(self, code, linenum):
++        self.code = code
++        self.linenum = linenum
++
++    def get_text(self):
++        # Get the actual source text of this line
++        return self.code.get_source_text(self.linenum)
++
++    def __eq__(self, other):
++        return self.code == other.code and self.linenum == other.linenum
++
++    def __ne__(self, other):
++        if other:
++            return self.code != other.code or self.linenum != other.linenum
++        else:
++            return True
++
++class CodeLoc(object):
++    # A codeloc is a specific location within the RPython bytecode
++    __slots__ = ('code', # code object
++                 'offset' # int index into bytecode, or -1
++                 )
++
++    def __init__(self, code, offset):
++        self.code = code
++        self.offset = offset
++
++    def __str__(self):
++        if self.offset >= 0:
++            return "%s@%d" % (self.code.co_name, self.offset)
++        else:
++            return ""
++
++    def __ne__(self, other):
++        if other:
++            return self.code != other.code or self.offset != other.offset
++        else:
++            return True
++
++    def __cmp__(self, other):
++        # Partial ordering, for those locations that have an offset:
++        if other:
++            if self.offset >= 0 and other.offset >= 0:
++                return self.offset - other.offset
++        return 0
++
++    def get_source_loc(self):
++        # Convert to a SourceLoc:
++        return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset))
++
++class OperationLoc(object):
++    # An oploc is the location within the RPython source code of a given
++    # operation
++    # 
++    # This is a list consisting of CodeLoc instances, some of which may be None
++    #
++    # For the simple case, this is list of length 1 with a single CodeLoc
++    #
++    # For an operation inside an inlined callsite, we have a list of length 2:
++    #    [codeloc of callsite,
++    #     codeloc of operation within inlined body]
++    #
++    # For more interesting inlined cases, we have a chain of source locations:
++    #    [codeloc of callsite,
++    #     codeloc of inner callsite,
++    #     ... ,
++    #     codeloc of innermost inlined callsite,
++    #     codeloc of operation within inlined body]
++    #
++
++    __slots__ = ('codelocs', )
++
++    def __init__(self, codelocs):
++        self.codelocs = codelocs
++
++    def __str__(self):
++        return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']'
++
++    def __cmp__(self, other):
++        return cmp(self.codelocs, other.codelocs)
++
++def block_comparator(blk0, blk1):
++    '''
++    Sort function for blocks, putting them in an ordering that attempts to
++    maximize readability of the generated C code
++    '''
++    # print 'comparing %r and %r' % (blk0, blk1)
++    # Put the start/end block at the top/bottom:
++    if blk0.isstartblock:
++        return -1
++
++    if blk1.isstartblock:
++        return 1
++
++    # Order blocks by the offset, where present:
++    if blk0.operations:
++        if blk1.operations:
++            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
++        else:
++            return -1
++    else:
++        if blk1.operations:
++            return 1
++        else:
++            return 0
++
++def edge_comparator(edge0, edge1):
++    return block_comparator(edge0.target, edge1.target)
+ 
+ class FunctionGraph(object):
+     __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__']
+@@ -94,6 +208,21 @@ class FunctionGraph(object):
+                 seen[block] = True
+                 stack += block.exits[::-1]
+ 
++    def iterblocks_by_source(self):
++        # Try to preserve logical source ordering in the blocks
++        block = self.startblock
++        yield block
++        seen = {block: True}
++        stack = list(block.exits[::-1])
++        stack.sort(edge_comparator)
++        while stack:
++            block = stack.pop().target
++            if block not in seen:
++                yield block
++                seen[block] = True
++                stack += block.exits[::-1]
++                stack.sort(edge_comparator)
++
+     def iterlinks(self):
+         block = self.startblock
+         seen = {block: True}
+@@ -183,14 +312,14 @@ class Block(object):
+         self.exits      = []              # list of Link(s)
+ 
+     def at(self):
+-        if self.operations and self.operations[0].offset >= 0:
+-            return "@%d" % self.operations[0].offset
++        if self.operations:
++            return str(self.operations[0].oploc)
+         else:
+             return ""
+ 
+     def __str__(self):
+         if self.operations:
+-            txt = "block@%d" % self.operations[0].offset
++            txt = "block%s" % self.operations[0].oploc
+         else:
+             if (not self.exits) and len(self.inputargs) == 1:
+                 txt = "return block"
+@@ -245,6 +374,21 @@ class Block(object):
+         from pypy.translator.tool.graphpage import try_show
+         try_show(self)
+ 
++    def isreturnblock(self):
++        return (not self.operations) and (not self.exits) and len(self.inputargs) == 1
++
++    def get_base_label(self, blocknum):
++        # Generate a more friendly C label for this block
++        if self.operations:
++            txt = "block"
++        elif (not self.exits) and len(self.inputargs) == 1:
++            txt = "return_block"
++        elif (not self.exits) and len(self.inputargs) == 2:
++            txt = "raise_block"
++        else:
++            txt = "codeless_block"
++        return '%s%d' % (txt, blocknum)
++
+ 
+ class Variable(object):
+     __slots__ = ["_name", "_nr", "concretetype"]
+@@ -331,13 +475,15 @@ class WrapException(Exception):
+ 
+ 
+ class SpaceOperation(object):
+-    __slots__ = "opname args result offset".split()
++    __slots__ = "opname args result oploc".split()
+ 
+-    def __init__(self, opname, args, result, offset=-1):
++    def __init__(self, opname, args, result, oploc=None):
+         self.opname = intern(opname)      # operation name
+         self.args   = list(args)  # mixed list of var/const
+         self.result = result      # either Variable or Constant instance
+-        self.offset = offset      # offset in code string
++        if oploc is None:
++            oploc = OperationLoc([None])
++        self.oploc = oploc
+ 
+     def __eq__(self, other):
+         return (self.__class__ is other.__class__ and 
+@@ -352,8 +498,9 @@ class SpaceOperation(object):
+         return hash((self.opname,tuple(self.args),self.result))
+ 
+     def __repr__(self):
+-        return "%r = %s(%s)" % (self.result, self.opname,
+-                                ", ".join(map(repr, self.args)))
++        return "%r = %s(%s) (%s)" % (self.result, self.opname,
++                                     ", ".join(map(repr, self.args)),
++                                     self.oploc)
+ 
+ class Atom(object):
+     def __init__(self, name):
+@@ -427,8 +574,7 @@ def copygraph(graph, shallow=False, varm
+                 for op in oplist:
+                     copyop = SpaceOperation(op.opname,
+                                             [copyvar(v) for v in op.args],
+-                                            copyvar(op.result), op.offset)
+-                    #copyop.offset = op.offset
++                                            copyvar(op.result), op.oploc)
+                     result.append(copyop)
+                 return result
+             newblock.operations = copyoplist(block.operations)
+diff -up pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py
+--- pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py	2011-11-21 16:15:36.600466455 -0500
+@@ -315,7 +315,9 @@ class FlowObjSpace(ObjSpace):
+     def do_operation(self, name, *args_w):
+         spaceop = SpaceOperation(name, args_w, Variable())
+         if hasattr(self, 'executioncontext'):  # not here during bootstrapping
+-            spaceop.offset = self.executioncontext.crnt_offset
++            codeloc = CodeLoc(self.executioncontext.code,
++                              self.executioncontext.crnt_offset)
++            spaceop.oploc = OperationLoc([codeloc])
+             self.executioncontext.recorder.append(spaceop)
+         return spaceop.result
+ 
+diff -up pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py
+--- pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py	2011-11-21 16:15:36.600466455 -0500
+@@ -119,3 +119,25 @@ def test_variable():
+     assert v2.renamed
+     assert v2.name.startswith("foobar_") and v2.name != v.name
+     assert v2.name.split('_', 1)[1].isdigit()
++
++def test_source_locations():
++    # Invent some random offsets into the code:
++    co = sample_function.__code__
++    codelocA = CodeLoc(co, 42)
++    codelocB = CodeLoc(co, 87)
++
++    assert str(codelocA) == 'sample_function at 42'
++    assert str(codelocB) == 'sample_function at 87'
++
++    assert cmp(codelocA, codelocB) < 0
++    assert cmp(codelocB, codelocA) > 0
++    
++    oplocA = OperationLoc([codelocA])
++    oplocB = OperationLoc([codelocB])
++
++    assert str(oplocA) == '[sample_function at 42]'
++    assert str(oplocB) == '[sample_function at 87]'
++
++    assert cmp(oplocA, oplocB) < 0
++    assert cmp(oplocB, oplocA) > 0
++
+diff -up pypy-pypy-release-1.7/pypy/rpython/rtyper.py.more-readable-c-code pypy-pypy-release-1.7/pypy/rpython/rtyper.py
+--- pypy-pypy-release-1.7/pypy/rpython/rtyper.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/rpython/rtyper.py	2011-11-21 16:15:36.601466455 -0500
+@@ -800,7 +800,7 @@ class HighLevelOp(object):
+         return vars
+ 
+     def genop(self, opname, args_v, resulttype=None):
+-        return self.llops.genop(opname, args_v, resulttype)
++        return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc)
+ 
+     def gendirectcall(self, ll_function, *args_v):
+         return self.llops.gendirectcall(ll_function, *args_v)
+@@ -935,7 +935,7 @@ class LowLevelOpList(list):
+                                                     v.concretetype))
+         return v
+ 
+-    def genop(self, opname, args_v, resulttype=None):
++    def genop(self, opname, args_v, resulttype=None, oploc=None):
+         try:
+             for v in args_v:
+                 v.concretetype
+@@ -944,7 +944,7 @@ class LowLevelOpList(list):
+                                  " and pass its result to genop(),"
+                                  " never hop.args_v directly.")
+         vresult = Variable()
+-        self.append(SpaceOperation(opname, args_v, vresult))
++        self.append(SpaceOperation(opname, args_v, vresult, oploc))
+         if resulttype is None:
+             vresult.concretetype = Void
+             return None
+diff -up pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py
+--- pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py	2011-11-21 16:15:36.601466455 -0500
+@@ -4,6 +4,7 @@ from pypy.translator.simplify import get
+ from pypy.translator.unsimplify import copyvar
+ from pypy.objspace.flow.model import Variable, Constant, Block, Link
+ from pypy.objspace.flow.model import SpaceOperation, c_last_exception
++from pypy.objspace.flow.model import OperationLoc
+ from pypy.objspace.flow.model import FunctionGraph
+ from pypy.objspace.flow.model import mkentrymap, checkgraph
+ from pypy.annotation import model as annmodel
+@@ -231,6 +232,7 @@ class BaseInliner(object):
+         self.varmap = {}
+         self._copied_blocks = {}
+         self.op = block.operations[index_operation]
++        self.callsite_oploc = self.op.oploc
+         self.graph_to_inline = self.get_graph_from_op(self.op)
+         self.exception_guarded = False
+         if (block.exitswitch == c_last_exception and
+@@ -290,7 +292,9 @@ class BaseInliner(object):
+         
+     def copy_operation(self, op):
+         args = [self.get_new_name(arg) for arg in op.args]
+-        result = SpaceOperation(op.opname, args, self.get_new_name(op.result))
++        new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:])
++        result = SpaceOperation(op.opname, args, self.get_new_name(op.result), 
++                                new_oploc)
+         return result
+ 
+     def copy_block(self, block):
+diff -up pypy-pypy-release-1.7/pypy/translator/c/funcgen.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/c/funcgen.py
+--- pypy-pypy-release-1.7/pypy/translator/c/funcgen.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/c/funcgen.py	2011-11-21 16:15:36.602466455 -0500
+@@ -1,4 +1,6 @@
+ import sys
++import inspect
++import dis
+ from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
+ from pypy.translator.c.support import cdecl
+ from pypy.translator.c.support import llvalue_from_constant, gen_assignments
+@@ -22,6 +24,38 @@ LOCALVAR = 'l_%s'
+ 
+ KEEP_INLINED_GRAPHS = False
+ 
++def block_comparator(blk0, blk1):
++    '''
++    Sort function for blocks, putting them in an ordering that attempts to
++    maximize readability of the generated C code
++    '''
++    # print 'comparing %r and %r' % (blk0, blk1)
++    # Put the start/end block at the top/bottom:
++    if blk0.isstartblock:
++        return -1
++
++    if blk1.isstartblock:
++        return 1
++
++    # Order blocks by the offset, where present:
++    if blk0.operations:
++        if blk1.operations:
++            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
++        else:
++            return -1
++    else:
++        if blk1.operations:
++            return 1
++        else:
++            return 0
++
++def escape_c_comments(py_src):
++    # Escape C comments within RPython source, to avoid generating bogus
++    # comments in our generated C source:
++    py_src = py_src.replace('/*', '')
++    py_src = py_src.replace('*/', '')
++    return py_src
++
+ class FunctionCodeGenerator(object):
+     """
+     Collects information about a function which we have to generate
+@@ -207,14 +241,57 @@ class FunctionCodeGenerator(object):
+ 
+     def cfunction_body(self):
+         graph = self.graph
+-        yield 'goto block0;'    # to avoid a warning "this label is not used"
++        # Try to print python source code:
++        if hasattr(graph, 'func'):
++            filename = inspect.getfile(graph.func)
++            #yield '/* name: %r */' % filename
++            try:
++                src, startline = inspect.getsourcelines(graph.func)
++            except IOError:
++                pass # No source found
++            except IndexError:
++                pass # Bulletproofing
++            else:
++                yield '/* Python source %r' % filename
++                for i, line in enumerate(src):
++                    line = line.rstrip()
++                    line = escape_c_comments(line)
++                    # FuncNode.funcgen_implementation treats lines ending in ':'
++                    # as C blocks, which messes up the formatting.
++                    # Work around this:
++                    if line.endswith(':'):
++                        line += ' '
++                    yield ' * %4d : %s' % (startline + i, line)
++                yield ' */'
++
++        label = graph.startblock.get_base_label(self.blocknum[graph.startblock])
++        yield 'goto %s;' % label # to avoid a warning "this label is not used"
++
++        # Sort the blocks into a (hopefully) readable order:
++        blocks = list(graph.iterblocks_by_source())
++        blocks.sort(block_comparator)
+ 
+         # generate the body of each block
+-        for block in graph.iterblocks():
++        for block in blocks:
++            cursrcloc = None
+             myblocknum = self.blocknum[block]
+             yield ''
+-            yield 'block%d:' % myblocknum
++            yield '%s:' % block.get_base_label(myblocknum)
++            #yield "/* repr(block): %r */" % (block, )
++            #yield "/* type(block): %r */" % (type(block), )
+             for i, op in enumerate(block.operations):
++                #yield "/* type(op): %r */" % (type(op), )
++                #yield "/* op.oploc: %s */" % (op.oploc, )
++                codeloc = op.oploc.codelocs[-1]
++                if codeloc:
++                    srcloc = codeloc.get_source_loc()
++                    if srcloc != cursrcloc:
++                        try:
++                            yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text()))
++                            cursrcloc = srcloc
++                        except IOError:
++                            pass
++
+                 for line in self.gen_op(op):
+                     yield line
+             if len(block.exits) == 0:
+@@ -306,7 +383,7 @@ class FunctionCodeGenerator(object):
+             assignments.append((a2typename, dest, src))
+         for line in gen_assignments(assignments):
+             yield line
+-        label = 'block%d' % self.blocknum[link.target]
++        label = link.target.get_base_label(self.blocknum[link.target])
+         if link.target in self.innerloops:
+             loop = self.innerloops[link.target]
+             if link is loop.links[-1]:   # link that ends a loop
+diff -up pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py
+--- pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py	2011-11-21 16:15:36.602466455 -0500
+@@ -1,4 +1,5 @@
+ import autopath, sys, os, py
++import re
+ from pypy.rpython.lltypesystem.lltype import *
+ from pypy.annotation import model as annmodel
+ from pypy.translator.translator import TranslationContext
+@@ -532,3 +533,130 @@ def test_inhibit_tail_call():
+     else:
+         assert 0, "the call was not found in the C source"
+     assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1]
++
++def get_generated_c_source(fn, types):
++    # Return a (optimized fn, c source code, c source filename) 3-tuple
++    t = Translation(fn)
++    t.annotate(types)
++    c_filename_path = t.source_c()
++    h = c_filename_path.open()
++    src = h.read()
++    h.close()
++    c_fn = t.compile_c()
++    return (c_fn, src, c_filename_path)
++
++def extract_c_function(c_src, fname):
++    # Extract the source for a given C function out of a the given src string
++    # Makes assumptions about the layout of the source
++    pattern = '^(.+) \**%s\(.*\) {$' % fname
++    within_fn = False
++    result = ''
++    for line in c_src.splitlines():
++        if within_fn:
++            result += line + '\n'
++            if line.startswith('}'):
++                return result
++        else:
++            m = re.match(pattern, line)
++            if m:
++                within_fn = True
++                result += line + '\n'
++    return result
++    
++    
++
++def test_generated_c_source():
++    # Verify that generate C source "looks good"
++    # We'll use is_perfect_number, as it contains a loop and a conditional
++
++    # Generate C source code
++    from pypy.translator.test.snippet import is_perfect_number
++    c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number,
++                                                        [int])
++
++    # Locate the C source for the type-specialized function:
++    c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number')
++    
++    # Verify that the C source contains embedded comments containing the lines
++    # of the python source:
++    expected_comment_lines = [
++        '/* is_perfect_number:31 :     while div < n: */',
++        '/* is_perfect_number:32 :         if n % div == 0: */',
++        '/* is_perfect_number:33 :             sum += div */',
++        '/* is_perfect_number:34 :         div += 1 */',
++        '/* is_perfect_number:35 :     return n == sum */']
++    for exp_line in expected_comment_lines:
++        assert exp_line in c_fn_src
++        
++    # Verify that the lines occur in the correct order
++    # ...we do this by filtering the function's generated C source to just
++    # those lines containing our comments (and dropping whitespace):
++    lines = c_fn_src.splitlines()
++    lines = [line.strip()
++             for line in lines
++             if '/* is_perfect_number:' in line]
++
++    # ...we should now have exact equality: the ordering should be as expected,
++    # and each comment should appear exactly once:
++    assert lines == expected_comment_lines
++
++    # Ensure that the generated C function does the right thing:
++    assert c_fn(5) == False
++    assert c_fn(6) == True
++    assert c_fn(7) == False
++
++    assert c_fn(5.0) == False
++    assert c_fn(6.0) == True
++    assert c_fn(7.0) == False
++
++    assert c_fn(5L) == False
++    assert c_fn(6L) == True
++    assert c_fn(7L) == False
++
++    try:
++        c_fn('hello world')
++    except:
++        pass
++    else:
++        raise 'Was expected exception'
++    
++def test_escaping_c_comments():
++    # Ensure that c comments within RPython code get escaped when we generate
++    # our .c code (to avoid generating bogus C)
++    # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a
++    # docstring embedding a C comment
++    def c_style_comment(a, b):
++        '''Here is a C-style comment within an RPython docstring:
++                /* hello world */
++        '''
++        # and here's one in a string literal:
++        return '/* hello world a:%s b:%s */' % (a, b)
++
++    def cplusplus_style_comment(a, b):
++        '''Here is a C++-style comment within an RPython docstring:
++                // hello world
++        '''
++        # and here are some in string literals, and one as the floor division
++        # operator:
++        return '// hello world: a // b = %s' % (a // b)
++
++    for fn_name, exp_output in [('c_style_comment',
++                                 '/* hello world a:6 b:3 */'),
++                                ('cplusplus_style_comment',
++                                 '// hello world: a // b = 2')]:
++        fn = locals()[fn_name]
++
++        c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int])
++        # If the above survived, then the C compiler managed to handle
++        # the generated C code
++
++        # Verify that the generated code works (i.e. that we didn't
++        # accidentally change the meaning):
++        assert c_fn(6, 3) == exp_output
++
++        # Ensure that at least part of the docstrings made it into the C
++        # code:
++        c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name)
++        assert 'Here is a ' in c_fn_src
++        assert 'style comment within an RPython docstring' in c_fn_src
++        
+diff -up pypy-pypy-release-1.7/pypy/translator/driver.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/driver.py
+--- pypy-pypy-release-1.7/pypy/translator/driver.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/driver.py	2011-11-21 16:15:36.603466455 -0500
+@@ -535,6 +535,7 @@ class TranslationDriver(SimpleTaskEngine
+             dstname = self.compute_exe_name() + '.staticdata.info'
+             shutil.copy(str(fname), str(dstname))
+             self.log.info('Static data info written to %s' % dstname)
++        return c_source_filename
+ 
+     #
+     task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
+diff -up pypy-pypy-release-1.7/pypy/translator/gensupp.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/gensupp.py
+--- pypy-pypy-release-1.7/pypy/translator/gensupp.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/gensupp.py	2011-11-21 16:15:36.603466455 -0500
+@@ -14,8 +14,8 @@ def ordered_blocks(graph):
+     allblocks = []
+     for block in graph.iterblocks():
+             # first we order by offset in the code string
+-            if block.operations:
+-                ofs = block.operations[0].offset
++            if block.operations and block.operations[0].oploc.codelocs[0]:
++                ofs = block.operations[0].oploc.codelocs[0].offset
+             else:
+                 ofs = sys.maxint
+             # then we order by input variable name or value
+diff -up pypy-pypy-release-1.7/pypy/translator/interactive.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/interactive.py
+--- pypy-pypy-release-1.7/pypy/translator/interactive.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/interactive.py	2011-11-21 16:15:36.604466454 -0500
+@@ -138,7 +138,7 @@ class Translation(object):
+     def source_c(self, argtypes=None, **kwds):
+         self.update_options(argtypes, kwds)
+         self.ensure_backend('c')
+-        self.driver.source_c()
++        return self.driver.source_c()
+ 
+     def source_cl(self, argtypes=None, **kwds):
+         self.update_options(argtypes, kwds)
+diff -up pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py
+--- pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py	2011-11-21 16:15:36.604466454 -0500
+@@ -59,6 +59,8 @@ def new_wrapper(func, translator, newnam
+     # "return result"
+     block = Block(wrapper_inputargs)
+     wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
++    if hasattr(graph, 'func'):
++        wgraph.func = graph.func
+     translator.update_call_graph(wgraph, graph, object())
+     translator.graphs.append(wgraph)
+     block.operations[:] = newops
+diff -up pypy-pypy-release-1.7/pypy/translator/simplify.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/simplify.py
+--- pypy-pypy-release-1.7/pypy/translator/simplify.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
++++ pypy-pypy-release-1.7/pypy/translator/simplify.py	2011-11-21 16:15:36.605466454 -0500
+@@ -292,7 +292,7 @@ def join_blocks(graph):
+                 return renaming.get(v, v)
+             def rename_op(op):
+                 args = [rename(a) for a in op.args]
+-                op = SpaceOperation(op.opname, args, rename(op.result), op.offset)
++                op = SpaceOperation(op.opname, args, rename(op.result), op.oploc)
+                 # special case...
+                 if op.opname == 'indirect_call':
+                     if isinstance(op.args[0], Constant):
diff --git a/pypy-1.5-config.patch b/pypy-1.5-config.patch
deleted file mode 100644
index 82d8fc9..0000000
--- a/pypy-1.5-config.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-diff -up pypy-1.5-src/pypy/translator/platform/linux.py.configure-fedora pypy-1.5-src/pypy/translator/platform/linux.py
---- pypy-1.5-src/pypy/translator/platform/linux.py.configure-fedora	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/platform/linux.py	2011-04-30 18:59:24.041160978 -0400
-@@ -1,13 +1,18 @@
- """Support for Linux."""
--
-+import os
- from pypy.translator.platform.posix import BasePosix
- 
-+CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
-+          '-Wall', '-Wno-unused']
-+if os.environ.get('CFLAGS', None):
-+    CFLAGS.extend(os.environ['CFLAGS'].split())
-+CFLAGS = tuple(CFLAGS)
-+
- class BaseLinux(BasePosix):
-     name = "linux"
-     
-     link_flags = ('-pthread', '-lrt')
--    cflags = ('-O3', '-pthread', '-fomit-frame-pointer',
--              '-Wall', '-Wno-unused')
-+    cflags = CFLAGS
-     standalone_only = ()
-     shared_only = ('-fPIC',)
-     so_ext = 'so'
-@@ -29,9 +34,10 @@ class Linux(BaseLinux):
-     shared_only = ()    # it seems that on 32-bit linux, compiling with -fPIC
-                         # gives assembler that asmgcc is not happy about.
- 
--    def library_dirs_for_libffi_a(self):
--        # places where we need to look for libffi.a
--        return self.library_dirs_for_libffi() + ['/usr/lib']
-+    # Fedora Linux, at least, has the shared version but not the static
-+    #def library_dirs_for_libffi_a(self):
-+    #    # places where we need to look for libffi.a
-+    #    return self.library_dirs_for_libffi() + ['/usr/lib']
- 
- 
- class Linux64(BaseLinux):
diff --git a/pypy-1.5-more-readable-c-code.patch b/pypy-1.5-more-readable-c-code.patch
deleted file mode 100644
index b7103e2..0000000
--- a/pypy-1.5-more-readable-c-code.patch
+++ /dev/null
@@ -1,693 +0,0 @@
-diff -up pypy-1.5-src/pypy/interpreter/pycode.py.more-readable-c-code pypy-1.5-src/pypy/interpreter/pycode.py
---- pypy-1.5-src/pypy/interpreter/pycode.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/interpreter/pycode.py	2011-05-02 14:28:33.942161002 -0400
-@@ -13,6 +13,7 @@ from pypy.interpreter.gateway import Non
- from pypy.interpreter.astcompiler.consts import (CO_OPTIMIZED,
-     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
-     CO_GENERATOR, CO_CONTAINSGLOBALS)
-+from pypy.interpreter.pytraceback import offset2lineno
- from pypy.rlib.rarithmetic import intmask
- from pypy.rlib.debug import make_sure_not_resized
- from pypy.rlib import jit
-@@ -80,6 +81,7 @@ class PyCode(eval.Code):
-         self.hidden_applevel = hidden_applevel
-         self.magic = magic
-         self._signature = cpython_code_signature(self)
-+        self._cached_source = None
-         self._initialize()
- 
-     def _initialize(self):
-@@ -396,3 +398,23 @@ class PyCode(eval.Code):
- 
-     def repr(self, space):
-         return space.wrap(self.get_repr())
-+
-+    def get_linenum_for_offset(self, offset):
-+        # Given a bytecode offset, return a 1-based index into the lines of the
-+        # source code
-+        return offset2lineno(self, offset)
-+
-+    def _ensure_source(self):
-+        # Lazily grab the source lines into self._cached_source (or raise
-+        # an IOError)
-+        if not self._cached_source:
-+            f = open(self.co_filename, 'r')
-+            source = [line.rstrip() for line in f.readlines()]
-+            f.close()
-+            self._cached_source = source
-+    
-+    def get_source_text(self, linenum):
-+        # Given a 1-based index, get the corresponding line of source code (or
-+        # raise an IOError)
-+        self._ensure_source()
-+        return self._cached_source[linenum - 1]
-diff -up pypy-1.5-src/pypy/objspace/flow/model.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/model.py
---- pypy-1.5-src/pypy/objspace/flow/model.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/objspace/flow/model.py	2011-05-02 14:28:33.942161002 -0400
-@@ -31,6 +31,120 @@ from pypy.tool.identity_dict import iden
- 
- __metaclass__ = type
- 
-+class SourceLoc(object):
-+    # A srcloc is a specific location within the RPython source code,
-+    # intended for human display
-+    __slots__ = ('code', # code object
-+                 'linenum' # 1-based index, as displayed to a user
-+                 )
-+    def __init__(self, code, linenum):
-+        self.code = code
-+        self.linenum = linenum
-+
-+    def get_text(self):
-+        # Get the actual source text of this line
-+        return self.code.get_source_text(self.linenum)
-+
-+    def __eq__(self, other):
-+        return self.code == other.code and self.linenum == other.linenum
-+
-+    def __ne__(self, other):
-+        if other:
-+            return self.code != other.code or self.linenum != other.linenum
-+        else:
-+            return True
-+
-+class CodeLoc(object):
-+    # A codeloc is a specific location within the RPython bytecode
-+    __slots__ = ('code', # code object
-+                 'offset' # int index into bytecode, or -1
-+                 )
-+
-+    def __init__(self, code, offset):
-+        self.code = code
-+        self.offset = offset
-+
-+    def __str__(self):
-+        if self.offset >= 0:
-+            return "%s@%d" % (self.code.co_name, self.offset)
-+        else:
-+            return ""
-+
-+    def __ne__(self, other):
-+        if other:
-+            return self.code != other.code or self.offset != other.offset
-+        else:
-+            return True
-+
-+    def __cmp__(self, other):
-+        # Partial ordering, for those locations that have an offset:
-+        if other:
-+            if self.offset >= 0 and other.offset >= 0:
-+                return self.offset - other.offset
-+        return 0
-+
-+    def get_source_loc(self):
-+        # Convert to a SourceLoc:
-+        return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset))
-+
-+class OperationLoc(object):
-+    # An oploc is the location within the RPython source code of a given
-+    # operation
-+    # 
-+    # This is a list consisting of CodeLoc instances, some of which may be None
-+    #
-+    # For the simple case, this is list of length 1 with a single CodeLoc
-+    #
-+    # For an operation inside an inlined callsite, we have a list of length 2:
-+    #    [codeloc of callsite,
-+    #     codeloc of operation within inlined body]
-+    #
-+    # For more interesting inlined cases, we have a chain of source locations:
-+    #    [codeloc of callsite,
-+    #     codeloc of inner callsite,
-+    #     ... ,
-+    #     codeloc of innermost inlined callsite,
-+    #     codeloc of operation within inlined body]
-+    #
-+
-+    __slots__ = ('codelocs', )
-+
-+    def __init__(self, codelocs):
-+        self.codelocs = codelocs
-+
-+    def __str__(self):
-+        return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']'
-+
-+    def __cmp__(self, other):
-+        return cmp(self.codelocs, other.codelocs)
-+
-+def block_comparator(blk0, blk1):
-+    '''
-+    Sort function for blocks, putting them in an ordering that attempts to
-+    maximize readability of the generated C code
-+    '''
-+    # print 'comparing %r and %r' % (blk0, blk1)
-+    # Put the start/end block at the top/bottom:
-+    if blk0.isstartblock:
-+        return -1
-+
-+    if blk1.isstartblock:
-+        return 1
-+
-+    # Order blocks by the offset, where present:
-+    if blk0.operations:
-+        if blk1.operations:
-+            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
-+        else:
-+            return -1
-+    else:
-+        if blk1.operations:
-+            return 1
-+        else:
-+            return 0
-+
-+def edge_comparator(edge0, edge1):
-+    return block_comparator(edge0.target, edge1.target)
- 
- class FunctionGraph(object):
-     __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__']
-@@ -94,6 +208,21 @@ class FunctionGraph(object):
-                 seen[block] = True
-                 stack += block.exits[::-1]
- 
-+    def iterblocks_by_source(self):
-+        # Try to preserve logical source ordering in the blocks
-+        block = self.startblock
-+        yield block
-+        seen = {block: True}
-+        stack = list(block.exits[::-1])
-+        stack.sort(edge_comparator)
-+        while stack:
-+            block = stack.pop().target
-+            if block not in seen:
-+                yield block
-+                seen[block] = True
-+                stack += block.exits[::-1]
-+                stack.sort(edge_comparator)
-+
-     def iterlinks(self):
-         block = self.startblock
-         seen = {block: True}
-@@ -183,14 +312,14 @@ class Block(object):
-         self.exits      = []              # list of Link(s)
- 
-     def at(self):
--        if self.operations and self.operations[0].offset >= 0:
--            return "@%d" % self.operations[0].offset
-+        if self.operations:
-+            return str(self.operations[0].oploc)
-         else:
-             return ""
- 
-     def __str__(self):
-         if self.operations:
--            txt = "block@%d" % self.operations[0].offset
-+            txt = "block%s" % self.operations[0].oploc
-         else:
-             if (not self.exits) and len(self.inputargs) == 1:
-                 txt = "return block"
-@@ -245,6 +374,21 @@ class Block(object):
-         from pypy.translator.tool.graphpage import try_show
-         try_show(self)
- 
-+    def isreturnblock(self):
-+        return (not self.operations) and (not self.exits) and len(self.inputargs) == 1
-+
-+    def get_base_label(self, blocknum):
-+        # Generate a more friendly C label for this block
-+        if self.operations:
-+            txt = "block"
-+        elif (not self.exits) and len(self.inputargs) == 1:
-+            txt = "return_block"
-+        elif (not self.exits) and len(self.inputargs) == 2:
-+            txt = "raise_block"
-+        else:
-+            txt = "codeless_block"
-+        return '%s%d' % (txt, blocknum)
-+
- 
- class Variable(object):
-     __slots__ = ["_name", "_nr", "concretetype"]
-@@ -331,13 +475,15 @@ class WrapException(Exception):
- 
- 
- class SpaceOperation(object):
--    __slots__ = "opname args result offset".split()
-+    __slots__ = "opname args result oploc".split()
- 
--    def __init__(self, opname, args, result, offset=-1):
-+    def __init__(self, opname, args, result, oploc=None):
-         self.opname = intern(opname)      # operation name
-         self.args   = list(args)  # mixed list of var/const
-         self.result = result      # either Variable or Constant instance
--        self.offset = offset      # offset in code string
-+        if oploc is None:
-+            oploc = OperationLoc([None])
-+        self.oploc = oploc
- 
-     def __eq__(self, other):
-         return (self.__class__ is other.__class__ and 
-@@ -352,8 +498,9 @@ class SpaceOperation(object):
-         return hash((self.opname,tuple(self.args),self.result))
- 
-     def __repr__(self):
--        return "%r = %s(%s)" % (self.result, self.opname,
--                                ", ".join(map(repr, self.args)))
-+        return "%r = %s(%s) (%s)" % (self.result, self.opname,
-+                                     ", ".join(map(repr, self.args)),
-+                                     self.oploc)
- 
- class Atom(object):
-     def __init__(self, name):
-@@ -427,8 +574,7 @@ def copygraph(graph, shallow=False, varm
-                 for op in oplist:
-                     copyop = SpaceOperation(op.opname,
-                                             [copyvar(v) for v in op.args],
--                                            copyvar(op.result), op.offset)
--                    #copyop.offset = op.offset
-+                                            copyvar(op.result), op.oploc)
-                     result.append(copyop)
-                 return result
-             newblock.operations = copyoplist(block.operations)
-diff -up pypy-1.5-src/pypy/objspace/flow/objspace.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/objspace.py
---- pypy-1.5-src/pypy/objspace/flow/objspace.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/objspace/flow/objspace.py	2011-05-02 14:28:33.943161001 -0400
-@@ -313,7 +313,9 @@ class FlowObjSpace(ObjSpace):
-     def do_operation(self, name, *args_w):
-         spaceop = SpaceOperation(name, args_w, Variable())
-         if hasattr(self, 'executioncontext'):  # not here during bootstrapping
--            spaceop.offset = self.executioncontext.crnt_offset
-+            codeloc = CodeLoc(self.executioncontext.code,
-+                              self.executioncontext.crnt_offset)
-+            spaceop.oploc = OperationLoc([codeloc])
-             self.executioncontext.recorder.append(spaceop)
-         return spaceop.result
- 
-diff -up pypy-1.5-src/pypy/objspace/flow/test/test_model.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/test/test_model.py
---- pypy-1.5-src/pypy/objspace/flow/test/test_model.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/objspace/flow/test/test_model.py	2011-05-02 14:28:33.943161001 -0400
-@@ -119,3 +119,25 @@ def test_variable():
-     assert v2.renamed
-     assert v2.name.startswith("foobar_") and v2.name != v.name
-     assert v2.name.split('_', 1)[1].isdigit()
-+
-+def test_source_locations():
-+    # Invent some random offsets into the code:
-+    co = sample_function.__code__
-+    codelocA = CodeLoc(co, 42)
-+    codelocB = CodeLoc(co, 87)
-+
-+    assert str(codelocA) == 'sample_function at 42'
-+    assert str(codelocB) == 'sample_function at 87'
-+
-+    assert cmp(codelocA, codelocB) < 0
-+    assert cmp(codelocB, codelocA) > 0
-+    
-+    oplocA = OperationLoc([codelocA])
-+    oplocB = OperationLoc([codelocB])
-+
-+    assert str(oplocA) == '[sample_function at 42]'
-+    assert str(oplocB) == '[sample_function at 87]'
-+
-+    assert cmp(oplocA, oplocB) < 0
-+    assert cmp(oplocB, oplocA) > 0
-+
-diff -up pypy-1.5-src/pypy/rpython/rtyper.py.more-readable-c-code pypy-1.5-src/pypy/rpython/rtyper.py
---- pypy-1.5-src/pypy/rpython/rtyper.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/rpython/rtyper.py	2011-05-02 14:28:33.943161001 -0400
-@@ -800,7 +800,7 @@ class HighLevelOp(object):
-         return vars
- 
-     def genop(self, opname, args_v, resulttype=None):
--        return self.llops.genop(opname, args_v, resulttype)
-+        return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc)
- 
-     def gendirectcall(self, ll_function, *args_v):
-         return self.llops.gendirectcall(ll_function, *args_v)
-@@ -935,7 +935,7 @@ class LowLevelOpList(list):
-                                                     v.concretetype))
-         return v
- 
--    def genop(self, opname, args_v, resulttype=None):
-+    def genop(self, opname, args_v, resulttype=None, oploc=None):
-         try:
-             for v in args_v:
-                 v.concretetype
-@@ -944,7 +944,7 @@ class LowLevelOpList(list):
-                                  " and pass its result to genop(),"
-                                  " never hop.args_v directly.")
-         vresult = Variable()
--        self.append(SpaceOperation(opname, args_v, vresult))
-+        self.append(SpaceOperation(opname, args_v, vresult, oploc))
-         if resulttype is None:
-             vresult.concretetype = Void
-             return None
-diff -up pypy-1.5-src/pypy/translator/backendopt/inline.py.more-readable-c-code pypy-1.5-src/pypy/translator/backendopt/inline.py
---- pypy-1.5-src/pypy/translator/backendopt/inline.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/backendopt/inline.py	2011-05-02 14:32:26.975161005 -0400
-@@ -4,6 +4,7 @@ from pypy.translator.simplify import get
- from pypy.translator.unsimplify import copyvar
- from pypy.objspace.flow.model import Variable, Constant, Block, Link
- from pypy.objspace.flow.model import SpaceOperation, c_last_exception
-+from pypy.objspace.flow.model import OperationLoc
- from pypy.objspace.flow.model import FunctionGraph
- from pypy.objspace.flow.model import mkentrymap, checkgraph
- from pypy.annotation import model as annmodel
-@@ -231,6 +232,7 @@ class BaseInliner(object):
-         self.varmap = {}
-         self._copied_blocks = {}
-         self.op = block.operations[index_operation]
-+        self.callsite_oploc = self.op.oploc
-         self.graph_to_inline = self.get_graph_from_op(self.op)
-         self.exception_guarded = False
-         if (block.exitswitch == c_last_exception and
-@@ -290,7 +292,9 @@ class BaseInliner(object):
-         
-     def copy_operation(self, op):
-         args = [self.get_new_name(arg) for arg in op.args]
--        result = SpaceOperation(op.opname, args, self.get_new_name(op.result))
-+        new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:])
-+        result = SpaceOperation(op.opname, args, self.get_new_name(op.result), 
-+                                new_oploc)
-         return result
- 
-     def copy_block(self, block):
-diff -up pypy-1.5-src/pypy/translator/c/funcgen.py.more-readable-c-code pypy-1.5-src/pypy/translator/c/funcgen.py
---- pypy-1.5-src/pypy/translator/c/funcgen.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/c/funcgen.py	2011-05-02 14:28:33.944161001 -0400
-@@ -1,4 +1,6 @@
- import sys
-+import inspect
-+import dis
- from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
- from pypy.translator.c.support import cdecl
- from pypy.translator.c.support import llvalue_from_constant, gen_assignments
-@@ -22,6 +24,38 @@ LOCALVAR = 'l_%s'
- 
- KEEP_INLINED_GRAPHS = False
- 
-+def block_comparator(blk0, blk1):
-+    '''
-+    Sort function for blocks, putting them in an ordering that attempts to
-+    maximize readability of the generated C code
-+    '''
-+    # print 'comparing %r and %r' % (blk0, blk1)
-+    # Put the start/end block at the top/bottom:
-+    if blk0.isstartblock:
-+        return -1
-+
-+    if blk1.isstartblock:
-+        return 1
-+
-+    # Order blocks by the offset, where present:
-+    if blk0.operations:
-+        if blk1.operations:
-+            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
-+        else:
-+            return -1
-+    else:
-+        if blk1.operations:
-+            return 1
-+        else:
-+            return 0
-+
-+def escape_c_comments(py_src):
-+    # Escape C comments within RPython source, to avoid generating bogus
-+    # comments in our generated C source:
-+    py_src = py_src.replace('/*', '')
-+    py_src = py_src.replace('*/', '')
-+    return py_src
-+
- class FunctionCodeGenerator(object):
-     """
-     Collects information about a function which we have to generate
-@@ -210,14 +244,57 @@ class FunctionCodeGenerator(object):
- 
-     def cfunction_body(self):
-         graph = self.graph
--        yield 'goto block0;'    # to avoid a warning "this label is not used"
-+        # Try to print python source code:
-+        if hasattr(graph, 'func'):
-+            filename = inspect.getfile(graph.func)
-+            #yield '/* name: %r */' % filename
-+            try:
-+                src, startline = inspect.getsourcelines(graph.func)
-+            except IOError:
-+                pass # No source found
-+            except IndexError:
-+                pass # Bulletproofing
-+            else:
-+                yield '/* Python source %r' % filename
-+                for i, line in enumerate(src):
-+                    line = line.rstrip()
-+                    line = escape_c_comments(line)
-+                    # FuncNode.funcgen_implementation treats lines ending in ':'
-+                    # as C blocks, which messes up the formatting.
-+                    # Work around this:
-+                    if line.endswith(':'):
-+                        line += ' '
-+                    yield ' * %4d : %s' % (startline + i, line)
-+                yield ' */'
-+
-+        label = graph.startblock.get_base_label(self.blocknum[graph.startblock])
-+        yield 'goto %s;' % label # to avoid a warning "this label is not used"
-+
-+        # Sort the blocks into a (hopefully) readable order:
-+        blocks = list(graph.iterblocks_by_source())
-+        blocks.sort(block_comparator)
- 
-         # generate the body of each block
--        for block in graph.iterblocks():
-+        for block in blocks:
-+            cursrcloc = None
-             myblocknum = self.blocknum[block]
-             yield ''
--            yield 'block%d:' % myblocknum
-+            yield '%s:' % block.get_base_label(myblocknum)
-+            #yield "/* repr(block): %r */" % (block, )
-+            #yield "/* type(block): %r */" % (type(block), )
-             for i, op in enumerate(block.operations):
-+                #yield "/* type(op): %r */" % (type(op), )
-+                #yield "/* op.oploc: %s */" % (op.oploc, )
-+                codeloc = op.oploc.codelocs[-1]
-+                if codeloc:
-+                    srcloc = codeloc.get_source_loc()
-+                    if srcloc != cursrcloc:
-+                        try:
-+                            yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text()))
-+                            cursrcloc = srcloc
-+                        except IOError:
-+                            pass
-+
-                 for line in self.gen_op(op):
-                     yield line
-             if len(block.exits) == 0:
-@@ -309,7 +386,7 @@ class FunctionCodeGenerator(object):
-             assignments.append((a2typename, dest, src))
-         for line in gen_assignments(assignments):
-             yield line
--        label = 'block%d' % self.blocknum[link.target]
-+        label = link.target.get_base_label(self.blocknum[link.target])
-         if link.target in self.innerloops:
-             loop = self.innerloops[link.target]
-             if link is loop.links[-1]:   # link that ends a loop
-diff -up pypy-1.5-src/pypy/translator/c/test/test_genc.py.more-readable-c-code pypy-1.5-src/pypy/translator/c/test/test_genc.py
---- pypy-1.5-src/pypy/translator/c/test/test_genc.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/c/test/test_genc.py	2011-05-02 14:28:33.945161001 -0400
-@@ -1,4 +1,5 @@
- import autopath, sys, os, py
-+import re
- from pypy.rpython.lltypesystem.lltype import *
- from pypy.annotation import model as annmodel
- from pypy.translator.translator import TranslationContext
-@@ -515,3 +516,130 @@ def test_inhibit_tail_call():
-     else:
-         assert 0, "the call was not found in the C source"
-     assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1]
-+
-+def get_generated_c_source(fn, types):
-+    # Return a (optimized fn, c source code, c source filename) 3-tuple
-+    t = Translation(fn)
-+    t.annotate(types)
-+    c_filename_path = t.source_c()
-+    h = c_filename_path.open()
-+    src = h.read()
-+    h.close()
-+    c_fn = t.compile_c()
-+    return (c_fn, src, c_filename_path)
-+
-+def extract_c_function(c_src, fname):
-+    # Extract the source for a given C function out of a the given src string
-+    # Makes assumptions about the layout of the source
-+    pattern = '^(.+) \**%s\(.*\) {$' % fname
-+    within_fn = False
-+    result = ''
-+    for line in c_src.splitlines():
-+        if within_fn:
-+            result += line + '\n'
-+            if line.startswith('}'):
-+                return result
-+        else:
-+            m = re.match(pattern, line)
-+            if m:
-+                within_fn = True
-+                result += line + '\n'
-+    return result
-+    
-+    
-+
-+def test_generated_c_source():
-+    # Verify that generate C source "looks good"
-+    # We'll use is_perfect_number, as it contains a loop and a conditional
-+
-+    # Generate C source code
-+    from pypy.translator.test.snippet import is_perfect_number
-+    c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number,
-+                                                        [int])
-+
-+    # Locate the C source for the type-specialized function:
-+    c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number')
-+    
-+    # Verify that the C source contains embedded comments containing the lines
-+    # of the python source:
-+    expected_comment_lines = [
-+        '/* is_perfect_number:31 :     while div < n: */',
-+        '/* is_perfect_number:32 :         if n % div == 0: */',
-+        '/* is_perfect_number:33 :             sum += div */',
-+        '/* is_perfect_number:34 :         div += 1 */',
-+        '/* is_perfect_number:35 :     return n == sum */']
-+    for exp_line in expected_comment_lines:
-+        assert exp_line in c_fn_src
-+        
-+    # Verify that the lines occur in the correct order
-+    # ...we do this by filtering the function's generated C source to just
-+    # those lines containing our comments (and dropping whitespace):
-+    lines = c_fn_src.splitlines()
-+    lines = [line.strip()
-+             for line in lines
-+             if '/* is_perfect_number:' in line]
-+
-+    # ...we should now have exact equality: the ordering should be as expected,
-+    # and each comment should appear exactly once:
-+    assert lines == expected_comment_lines
-+
-+    # Ensure that the generated C function does the right thing:
-+    assert c_fn(5) == False
-+    assert c_fn(6) == True
-+    assert c_fn(7) == False
-+
-+    assert c_fn(5.0) == False
-+    assert c_fn(6.0) == True
-+    assert c_fn(7.0) == False
-+
-+    assert c_fn(5L) == False
-+    assert c_fn(6L) == True
-+    assert c_fn(7L) == False
-+
-+    try:
-+        c_fn('hello world')
-+    except:
-+        pass
-+    else:
-+        raise 'Was expected exception'
-+    
-+def test_escaping_c_comments():
-+    # Ensure that c comments within RPython code get escaped when we generate
-+    # our .c code (to avoid generating bogus C)
-+    # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a
-+    # docstring embedding a C comment
-+    def c_style_comment(a, b):
-+        '''Here is a C-style comment within an RPython docstring:
-+                /* hello world */
-+        '''
-+        # and here's one in a string literal:
-+        return '/* hello world a:%s b:%s */' % (a, b)
-+
-+    def cplusplus_style_comment(a, b):
-+        '''Here is a C++-style comment within an RPython docstring:
-+                // hello world
-+        '''
-+        # and here are some in string literals, and one as the floor division
-+        # operator:
-+        return '// hello world: a // b = %s' % (a // b)
-+
-+    for fn_name, exp_output in [('c_style_comment',
-+                                 '/* hello world a:6 b:3 */'),
-+                                ('cplusplus_style_comment',
-+                                 '// hello world: a // b = 2')]:
-+        fn = locals()[fn_name]
-+
-+        c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int])
-+        # If the above survived, then the C compiler managed to handle
-+        # the generated C code
-+
-+        # Verify that the generated code works (i.e. that we didn't
-+        # accidentally change the meaning):
-+        assert c_fn(6, 3) == exp_output
-+
-+        # Ensure that at least part of the docstrings made it into the C
-+        # code:
-+        c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name)
-+        assert 'Here is a ' in c_fn_src
-+        assert 'style comment within an RPython docstring' in c_fn_src
-+        
-diff -up pypy-1.5-src/pypy/translator/driver.py.more-readable-c-code pypy-1.5-src/pypy/translator/driver.py
---- pypy-1.5-src/pypy/translator/driver.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/driver.py	2011-05-02 14:28:33.945161001 -0400
-@@ -536,6 +536,7 @@ class TranslationDriver(SimpleTaskEngine
-             dstname = self.compute_exe_name() + '.staticdata.info'
-             shutil.copy(str(fname), str(dstname))
-             self.log.info('Static data info written to %s' % dstname)
-+        return c_source_filename
- 
-     #
-     task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
-diff -up pypy-1.5-src/pypy/translator/gensupp.py.more-readable-c-code pypy-1.5-src/pypy/translator/gensupp.py
---- pypy-1.5-src/pypy/translator/gensupp.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/gensupp.py	2011-05-02 14:33:31.026161001 -0400
-@@ -14,8 +14,8 @@ def ordered_blocks(graph):
-     allblocks = []
-     for block in graph.iterblocks():
-             # first we order by offset in the code string
--            if block.operations:
--                ofs = block.operations[0].offset
-+            if block.operations and block.operations[0].oploc.codelocs[0]:
-+                ofs = block.operations[0].oploc.codelocs[0].offset
-             else:
-                 ofs = sys.maxint
-             # then we order by input variable name or value
-diff -up pypy-1.5-src/pypy/translator/interactive.py.more-readable-c-code pypy-1.5-src/pypy/translator/interactive.py
---- pypy-1.5-src/pypy/translator/interactive.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/interactive.py	2011-05-02 14:28:33.946161001 -0400
-@@ -138,7 +138,7 @@ class Translation(object):
-     def source_c(self, argtypes=None, **kwds):
-         self.update_options(argtypes, kwds)
-         self.ensure_backend('c')
--        self.driver.source_c()
-+        return self.driver.source_c()
- 
-     def source_cl(self, argtypes=None, **kwds):
-         self.update_options(argtypes, kwds)
-diff -up pypy-1.5-src/pypy/translator/llsupport/wrapper.py.more-readable-c-code pypy-1.5-src/pypy/translator/llsupport/wrapper.py
---- pypy-1.5-src/pypy/translator/llsupport/wrapper.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/llsupport/wrapper.py	2011-05-02 14:28:33.946161001 -0400
-@@ -59,6 +59,8 @@ def new_wrapper(func, translator, newnam
-     # "return result"
-     block = Block(wrapper_inputargs)
-     wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
-+    if hasattr(graph, 'func'):
-+        wgraph.func = graph.func
-     translator.update_call_graph(wgraph, graph, object())
-     translator.graphs.append(wgraph)
-     block.operations[:] = newops
-diff -up pypy-1.5-src/pypy/translator/simplify.py.more-readable-c-code pypy-1.5-src/pypy/translator/simplify.py
---- pypy-1.5-src/pypy/translator/simplify.py.more-readable-c-code	2011-04-30 10:18:50.000000000 -0400
-+++ pypy-1.5-src/pypy/translator/simplify.py	2011-05-02 14:28:33.952161001 -0400
-@@ -298,7 +298,7 @@ def join_blocks(graph):
-                 return renaming.get(v, v)
-             def rename_op(op):
-                 args = [rename(a) for a in op.args]
--                op = SpaceOperation(op.opname, args, rename(op.result), op.offset)
-+                op = SpaceOperation(op.opname, args, rename(op.result), op.oploc)
-                 # special case...
-                 if op.opname == 'indirect_call':
-                     if isinstance(op.args[0], Constant):
diff --git a/pypy.spec b/pypy.spec
index 2579860..1d6b6af 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
-Version:        1.6
-Release:        7%{?dist}
+Version:        1.7
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -126,14 +126,14 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:        https://bitbucket.org/pypy/pypy/get/release-1.6.tar.bz2
+Source0:        https://bitbucket.org/pypy/pypy/get/release-%{version}.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
 Source2:        macros.pypy
 
 # Edit a translator file for linux in order to configure our cflags and dynamic libffi
-Patch0:         pypy-1.5-config.patch
+Patch0:         config.patch
 
 # By default, if built at a tty, the translation process renders a Mandelbrot
 # set to indicate progress.
@@ -163,7 +163,7 @@ Patch3: pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
 #  http://codespeak.net/pipermail/pypy-dev/2010q4/006532.html
 # TODO: get this into the upstream bug tracker, and finish inlining
 # support (rhbz#666963)
-Patch4: pypy-1.5-more-readable-c-code.patch
+Patch4: more-readable-c-code.patch
 
 # In my koji builds, /root/bin is in the PATH for some reason
 # This leads to test_subprocess.py failing, due to "test_leaking_fds_on_error"
@@ -847,6 +847,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Nov 21 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-1
+- 1.7: refresh patch 0 (configuration) and patch 4 (readability of generated
+code)
+
 * Tue Oct  4 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-7
 - skip test_multiprocessing
 
diff --git a/sources b/sources
index 5660f1e..197491c 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-1189352effc5df7df84e6916b3b3eae3  release-1.6.tar.bz2
+fc22184c931ead98bdae9ec3e79595c2  release-1.7.tar.bz2
-- 
cgit v0.10.2


From 416c353a67345f32fa7da698b18eef5ad1d1e77e Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Fri, 16 Dec 2011 17:15:41 -0500
Subject: 1.7-2: use --gcrootfinder=shadowstack, and use standard Fedora
 compilation flags * Fri Dec 16 2011 David Malcolm <dmalcolm at redhat.com> -
 1.7-2 - use --gcrootfinder=shadowstack, and use standard Fedora compilation
 flags, with -Wno-unused (rhbz#666966 and rhbz#707707)


diff --git a/pypy.spec b/pypy.spec
index 1d6b6af..d99d341 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.7
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -110,6 +110,10 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 # Easy way to enable/disable verbose logging:
 %global verbose_logs 0
 
+# Forcibly use the shadow-stack option for detecting GC roots, rather than
+# relying on hacking up generated assembler with regexps:
+%global shadow_stack 1
+
 # Easy way to turn off the selftests:
 %global run_selftests 1
 
@@ -429,6 +433,22 @@ BuildPyPy() {
   # plus all substrings from CFLAGS in the environment.
   # This is used to generate a value for CFLAGS that's written into the Makefile
 
+  # How will we track garbage-collection roots in the generated code?
+  #   http://pypy.readthedocs.org/en/latest/config/translation.gcrootfinder.html
+
+%if 0%{shadow_stack}
+  # This is the most portable option, and avoids a reliance on non-guaranteed
+  # behaviors within GCC's code generator: use an explicitly-maintained stack
+  # of root pointers:
+  %define gcrootfinder_options --gcrootfinder=shadowstack
+
+  export CFLAGS=$(echo "$RPM_OPT_FLAGS")
+
+%else
+  # Go with the default, which is "asmgcc"
+
+  %define gcrootfinder_options %{nil}
+
   # https://bugzilla.redhat.com/show_bug.cgi?id=588941#c18
   # The generated Makefile compiles the .c files into assembler (.s), rather
   # than direct to .o  It then post-processes this assembler to locate
@@ -443,6 +463,13 @@ BuildPyPy() {
   # Filed as https://bugzilla.redhat.com/show_bug.cgi?id=666966
   export CFLAGS=$(echo "$RPM_OPT_FLAGS" | sed -e 's/-Wp,-D_FORTIFY_SOURCE=2//' -e 's/-fexceptions//' -e 's/-fstack-protector//' -e 's/--param=ssp-buffer-size=4//' -e 's/-O2//' -e 's/-fasynchronous-unwind-tables//' -e 's/-march=i686//' -e 's/-mtune=atom//')
 
+%endif
+
+  # The generated C code leads to many thousands of warnings of the form:
+  #   warning: variable 'l_v26003' set but not used [-Wunused-but-set-variable]
+  # Suppress them:
+  export CFLAGS=$(echo "$CFLAGS" -Wno-unused)
+
   # If we're already built the JIT-enabled "pypy", then use it for subsequent
   # builds (of other configurations):
   if test -x './pypy' ; then
@@ -466,6 +493,7 @@ BuildPyPy() {
     --cflags="$CFLAGS" \
     --batch \
     --output=$ExeName \
+    %{gcrootfinder_options} \
     $Options
 
   echo "--------------------------------------------------------------"
@@ -847,6 +875,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Fri Dec 16 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-2
+- use --gcrootfinder=shadowstack, and use standard Fedora compilation flags,
+with -Wno-unused (rhbz#666966 and rhbz#707707)
+
 * Mon Nov 21 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-1
 - 1.7: refresh patch 0 (configuration) and patch 4 (readability of generated
 code)
-- 
cgit v0.10.2


From e21faf468c1f7001f4680cff5f09fca068fb0397 Mon Sep 17 00:00:00 2001
From: Dennis Gilmore <dennis at ausil.us>
Date: Fri, 13 Jan 2012 19:29:18 -0600
Subject: - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild


diff --git a/pypy.spec b/pypy.spec
index d99d341..4bf93a4 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.7
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -875,6 +875,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sat Jan 14 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.7-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
 * Fri Dec 16 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-2
 - use --gcrootfinder=shadowstack, and use standard Fedora compilation flags,
 with -Wno-unused (rhbz#666966 and rhbz#707707)
-- 
cgit v0.10.2


From a8e52ca5f82917a1b2fb3a3684272c2c1e39f146 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Tue, 31 Jan 2012 04:53:38 -0500
Subject: fix an incompatibility with virtualenv (rhbz#742641)

Previously, we manually fixed up the library search path to be
below %{pypyprefix}, by patching pypy/translator/goal/app_main.py (adding
LIBRARY_INSTALLATION_PATH in patch 3, then using sed to change it to the
correct value in %prep after applying the patch).

This led to issues when using pypy with virtualenv, so now (as suggested in
https://codespeak.net/issue/pypy-dev/issue614 ) we simply install the pypy
binary into %{pypyprefix}, and make /usr/bin/pypy be a symlink to it.  This
allows pypy to find its libraries both when run outside a virtualenv, and
within it.

Resolves https://bugzilla.redhat.com/show_bug.cgi?id=742641

diff --git a/pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch b/pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
deleted file mode 100644
index 93bcb69..0000000
--- a/pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-diff -r cd083843b67a pypy/translator/goal/app_main.py
---- a/pypy/translator/goal/app_main.py	Mon Dec 20 17:17:45 2010 +0100
-+++ b/pypy/translator/goal/app_main.py	Wed Dec 22 17:43:21 2010 -0500
-@@ -191,6 +191,12 @@
-     IS_WINDOWS = False
- 
- def get_library_path(executable):
-+    # FIXME: get this from translator configuration
-+    dirname = LIBRARY_INSTALLATION_PATH
-+    newpath = sys.pypy_initial_path(dirname)
-+    if newpath:
-+        return newpath
-+    
-     search = executable
-     while 1:
-         dirname = resolvedirof(search)
diff --git a/pypy.spec b/pypy.spec
index 4bf93a4..b5982bd 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.7
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -149,18 +149,6 @@ Patch1:         pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
 # of "ls" (http://bugs.python.org/issue7108)
 Patch2: fix-test_commands-expected-ls-output-issue7108.patch
 
-# When locating the pypy standard libraries, look first within
-# LIBRARY_INSTALLATION_PATH.
-# We convert this from being a non-existant variable into a string literal
-# with the value of "pypyprefix" in the "prep" phase below.
-#
-# We still use the scanning relative to the binary location when invoking a
-# pypy binary during the build (e.g. during "check")
-#
-# Sent upstream (with caveats) as:
-#   https://codespeak.net/issue/pypy-dev/issue614
-Patch3: pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch
-
 # Try to improve the readability of the generated .c code, by adding in the
 # RPython source as comments where possible.
 # A version of this was sent upstream as:
@@ -344,14 +332,6 @@ pushd lib-python/%{pylibver}
 %patch2 -p0
 popd
 
-# Look for the pypy libraries within LIBRARY_INSTALLATION_PATH first:
-%patch3 -p1
-# Fixup LIBRARY_INSTALLATION_PATH to be a string literal containing our value
-# for "pypyprefix":
-sed -i \
-  -e 's|LIBRARY_INSTALLATION_PATH|"%{pypyprefix}"|' \
-  pypy/translator/goal/app_main.py
-
 %patch4 -p1 -b .more-readable-c-code
 
 %patch5 -p1
@@ -535,7 +515,19 @@ rm -rf $RPM_BUILD_ROOT
 InstallPyPy() {
     ExeName=$1
 
-    install -m 755 %{goal_dir}/$ExeName %{buildroot}/%{_bindir}
+    # To ensure compatibility with virtualenv, pypy finds its libraries
+    # relative to itself; this happens within
+    #    pypy/translator/goal/app_main.py:get_library_path
+    # which calls sys.pypy_initial_path(dirname) on the dir containing
+    # the executable, with symlinks resolved.
+    #
+    # Hence we make /usr/bin/pypy be a symlink to the real binary, which we
+    # place within /usr/lib[64]/pypy-1.* as pypy
+    #
+    # This ought to enable our pypy build to work with virtualenv
+    # (rhbz#742641)
+    install -m 755 %{goal_dir}/$ExeName %{buildroot}/%{pypyprefix}/$ExeName
+    ln -s %{pypyprefix}/$ExeName %{buildroot}/%{_bindir}
 
     # The generated machine code doesn't need an executable stack,  but
     # one of the assembler files (gcmaptable.s) doesn't have the necessary
@@ -546,10 +538,11 @@ InstallPyPy() {
     #
     # I tried various approaches involving fixing the build, but the simplest
     # approach is to postprocess the ELF file:
-    execstack --clear-execstack %{buildroot}/%{_bindir}/$ExeName
+    execstack --clear-execstack %{buildroot}/%{pypyprefix}/$ExeName
 }
 
 mkdir -p %{buildroot}/%{_bindir}
+mkdir -p %{buildroot}/%{pypyprefix}
 
 InstallPyPy pypy
 
@@ -570,7 +563,6 @@ InstallPyPy pypy-stackless
 #   PREFIX/lib-python/modified.2.5.2
 # as given on the above page, i.e. it uses '-' not '.'
 
-mkdir -p %{buildroot}/%{pypyprefix}
 cp -a lib-python %{buildroot}/%{pypyprefix}
 
 cp -a lib_pypy %{buildroot}/%{pypyprefix}
@@ -859,6 +851,7 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %doc LICENSE README
 %{_bindir}/pypy
+%{pypyprefix}/pypy
 
 %files devel
 %defattr(-,root,root,-)
@@ -875,6 +868,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Jan 31 2012 David Malcolm <dmalcolm at redhat.com> - 1.7-4
+- fix an incompatibility with virtualenv (rhbz#742641)
+
 * Sat Jan 14 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.7-3
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
 
-- 
cgit v0.10.2


From 52a91fcc4b0ffbdb511ad40e389fe6566d1b8623 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Fri, 10 Feb 2012 09:19:56 -0500
Subject: 1.8

rebase to 1.8:
* regenerate config patch (patch 0)
* drop selinux patch (patch 2)
* regenerate patch 5

diff --git a/.gitignore b/.gitignore
index 99af398..86ec921 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 /pypy-1.5-src.tar.bz2
 /release-1.6.tar.bz2
 /release-1.7.tar.bz2
+/release-1.8.tar.bz2
diff --git a/config.patch b/config.patch
index afd7a7d..a11f397 100644
--- a/config.patch
+++ b/config.patch
@@ -1,31 +1,7 @@
-diff -up pypy-pypy-release-1.7/pypy/translator/platform/linux.py.configure-fedora pypy-pypy-release-1.7/pypy/translator/platform/linux.py
---- pypy-pypy-release-1.7/pypy/translator/platform/linux.py.configure-fedora	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/platform/linux.py	2011-11-21 13:07:03.454240019 -0500
-@@ -1,15 +1,21 @@
- """Support for Linux."""
- 
-+import os
- import sys
- from pypy.translator.platform.posix import BasePosix
- 
-+CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
-+          '-Wall', '-Wno-unused']
-+if os.environ.get('CFLAGS', None):
-+    CFLAGS.extend(os.environ['CFLAGS'].split())
-+CFLAGS = tuple(CFLAGS)
-+
- class BaseLinux(BasePosix):
-     name = "linux"
-     
-     link_flags = ('-pthread',)
-     extra_libs = ('-lrt',)
--    cflags = ('-O3', '-pthread', '-fomit-frame-pointer',
--              '-Wall', '-Wno-unused')
-+    cflags = CFLAGS
-     standalone_only = ()
-     shared_only = ('-fPIC',)
-     so_ext = 'so'
-@@ -26,13 +32,14 @@ class BaseLinux(BasePosix):
+diff -up pypy-pypy-2346207d9946/pypy/translator/platform/linux.py.configure-fedora pypy-pypy-2346207d9946/pypy/translator/platform/linux.py
+--- pypy-pypy-2346207d9946/pypy/translator/platform/linux.py.configure-fedora	2012-02-09 13:27:19.000000000 -0500
++++ pypy-pypy-2346207d9946/pypy/translator/platform/linux.py	2012-02-10 09:06:20.393066016 -0500
+@@ -31,13 +31,14 @@ class BaseLinux(BasePosix):
          return self._pkg_config("libffi", "--libs-only-L",
                                  ['/usr/lib/libffi'])
  
diff --git a/fix-test_commands-expected-ls-output-issue7108.patch b/fix-test_commands-expected-ls-output-issue7108.patch
deleted file mode 100644
index becc3e0..0000000
--- a/fix-test_commands-expected-ls-output-issue7108.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- test/test_commands.py.orig	2010-12-22 13:25:11.357333216 -0500
-+++ test/test_commands.py	2010-12-22 13:25:57.927166219 -0500
-@@ -47,7 +47,7 @@ class CommandTests(unittest.TestCase):
-         # Note that the first case above has a space in the group name
-         # while the second one has a space in both names.
-         pat = r'''d.........   # It is a directory.
--                  \+?          # It may have ACLs.
-+                  [.+@]?       # It may have alt access (SELinux, ACLs or metadata ('@' OS X).
-                   \s+\d+       # It has some number of links.
-                   [^/]*        # Skip user, group, size, and date.
-                   /\.          # and end with the name of the file.
diff --git a/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch b/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
index eb6f324..9071be5 100644
--- a/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
+++ b/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
@@ -1,6 +1,5 @@
-diff -up pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py.non-readable-path pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py
---- pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py.non-readable-path	2011-08-20 11:46:31.410646024 -0400
-+++ pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py	2011-08-20 11:46:39.421645476 -0400
+--- pypy-pypy-2346207d9946/lib-python/2.7/test/test_subprocess.py.orig	2012-02-09 13:27:19.000000000 -0500
++++ pypy-pypy-2346207d9946/lib-python/2.7/test/test_subprocess.py	2012-02-10 09:14:08.312216221 -0500
 @@ -570,7 +570,7 @@ class ProcessTestCase(BaseTestCase):
          for i in range(1024):
              # Windows raises IOError.  Others raise OSError.
@@ -9,4 +8,4 @@ diff -up pypy-pypy-release-1.6/lib-python/2.7/test/test_subprocess.py.non-readab
 +                subprocess.Popen(['/usr/bin/nonexisting_i_hope'],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
-             if c.exception.errno != errno.ENOENT:  # ignore "no such file"
+             # ignore errors that indicate the command was not found
diff --git a/pypy.spec b/pypy.spec
index b5982bd..9838bae 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
-Version:        1.7
-Release:        4%{?dist}
+Version:        1.8
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -145,10 +145,6 @@ Patch0:         config.patch
 # merely render dots:
 Patch1:         pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
 
-# test_commmands fails on SELinux systems due to a change in the output
-# of "ls" (http://bugs.python.org/issue7108)
-Patch2: fix-test_commands-expected-ls-output-issue7108.patch
-
 # Try to improve the readability of the generated .c code, by adding in the
 # RPython source as comments where possible.
 # A version of this was sent upstream as:
@@ -324,14 +320,10 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-pypy-release-%{version}
+%setup -q -n pypy-pypy-2346207d9946
 %patch0 -p1 -b .configure-fedora
 %patch1 -p1 -b .suppress-mandelbrot-set-during-tty-build
 
-pushd lib-python/%{pylibver}
-%patch2 -p0
-popd
-
 %patch4 -p1 -b .more-readable-c-code
 
 %patch5 -p1
@@ -868,6 +860,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Feb  9 2012 David Malcolm <dmalcolm at redhat.com> - 1.8-1
+- 1.8; regenerate config patch (patch 0); drop selinux patch (patch 2);
+regenerate patch 5
+
 * Tue Jan 31 2012 David Malcolm <dmalcolm at redhat.com> - 1.7-4
 - fix an incompatibility with virtualenv (rhbz#742641)
 
diff --git a/sources b/sources
index 197491c..30a988e 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-fc22184c931ead98bdae9ec3e79595c2  release-1.7.tar.bz2
+661be06978fdc907d84f0ee1f1228c8b  release-1.8.tar.bz2
-- 
cgit v0.10.2


From 07098c88a6645a0333d4c0d927251a23d002376d Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Fri, 10 Feb 2012 11:12:43 -0500
Subject: 1.8-2: disable C readability patch for now (patch 4)


diff --git a/pypy.spec b/pypy.spec
index 9838bae..8b80611 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.8
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -324,7 +324,38 @@ Build of PyPy with support for micro-threads for massive concurrency
 %patch0 -p1 -b .configure-fedora
 %patch1 -p1 -b .suppress-mandelbrot-set-during-tty-build
 
-%patch4 -p1 -b .more-readable-c-code
+# Disabled for now, as it needs regenerating for 1.8
+#patch4 -p1 -b .more-readable-c-code
+# Fails on 1.8 with this error:
+#   [translation:ERROR] Error:
+#   [translation:ERROR]  Traceback (most recent call last):
+#   [translation:ERROR]    File "translate.py", line 309, in main
+#   [translation:ERROR]     drv.proceed(goals)
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/driver.py", line 811, in proceed
+#   [translation:ERROR]     return self._execute(goals, task_skip = self._maybe_skip())
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/tool/taskengine.py", line 116, in _execute
+#   [translation:ERROR]     res = self._do(goal, taskcallable, *args, **kwds)
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/driver.py", line 287, in _do
+#   [translation:ERROR]     res = func()
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/driver.py", line 530, in task_source_c
+#   [translation:ERROR]     exe_name=exe_name)
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/genc.py", line 252, in generate_source
+#   [translation:ERROR]     split=self.split)
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/genc.py", line 989, in gen_source
+#   [translation:ERROR]     sg.gen_readable_parts_of_source(f)
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/genc.py", line 843, in gen_readable_parts_of_source
+#   [translation:ERROR]     for node, impl in nodeiter:
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/genc.py", line 729, in subiter
+#   [translation:ERROR]     impl = '\n'.join(list(node.implementation())).split('\n')
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/node.py", line 867, in implementation
+#   [translation:ERROR]     for s in self.funcgen_implementation(funcgen):
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/node.py", line 901, in funcgen_implementation
+#   [translation:ERROR]     for line in bodyiter:
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/funcgen.py", line 272, in cfunction_body
+#   [translation:ERROR]     blocks.sort(block_comparator)
+#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/funcgen.py", line 34, in block_comparator
+#   [translation:ERROR]     if blk0.isstartblock:
+#   [translation:ERROR]  AttributeError: 'Block' object has no attribute 'isstartblock'
 
 %patch5 -p1
 
@@ -860,6 +891,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Fri Feb 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.8-2
+- disable C readability patch for now (patch 4)
+
 * Thu Feb  9 2012 David Malcolm <dmalcolm at redhat.com> - 1.8-1
 - 1.8; regenerate config patch (patch 0); drop selinux patch (patch 2);
 regenerate patch 5
-- 
cgit v0.10.2


From b042622bfa38e9ad3794d4f845207042e589b20b Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Fri, 8 Jun 2012 20:18:15 -0400
Subject: 1.9


diff --git a/pypy.spec b/pypy.spec
index 8b80611..80b4039 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
-Version:        1.8
-Release:        2%{?dist}
+Version:        1.9
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -320,7 +320,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-pypy-2346207d9946
+%setup -q -n pypy-pypy-341e1e3821ff
 %patch0 -p1 -b .configure-fedora
 %patch1 -p1 -b .suppress-mandelbrot-set-during-tty-build
 
@@ -861,7 +861,6 @@ rm -rf $RPM_BUILD_ROOT
 %dir %{pypyprefix}/lib-python
 %{pypyprefix}/lib-python/stdlib-version.txt
 %{pypyprefix}/lib-python/%{pylibver}/
-%{pypyprefix}/lib-python/modified-%{pylibver}/
 %{pypyprefix}/lib-python/conftest.py*
 %{pypyprefix}/lib_pypy/
 %{pypyprefix}/site-packages/
@@ -891,6 +890,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Fri Jun  8 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-1
+- 1.9
+
 * Fri Feb 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.8-2
 - disable C readability patch for now (patch 4)
 
-- 
cgit v0.10.2


From 615fd77fe04457d552feff9d10986589b35a6148 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Wed, 13 Jun 2012 11:11:16 -0400
Subject: upload 1.9 tarball


diff --git a/.gitignore b/.gitignore
index 86ec921..4c551cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
 /release-1.6.tar.bz2
 /release-1.7.tar.bz2
 /release-1.8.tar.bz2
+/release-1.9.tar.bz2
diff --git a/sources b/sources
index 30a988e..2a64332 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-661be06978fdc907d84f0ee1f1228c8b  release-1.8.tar.bz2
+f92c0171a9578a3e4a0f74947ec596ab  release-1.9.tar.bz2
-- 
cgit v0.10.2


From 92ec0ebc5bf5746a03e45726d8e300ef51ff7940 Mon Sep 17 00:00:00 2001
From: Peter Robinson <pbrobinson at gmail.com>
Date: Mon, 18 Jun 2012 09:50:36 +0100
Subject: Compile with PIC, fixes FTBFS on ARM


diff --git a/pypy.spec b/pypy.spec
index 80b4039..e579720 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.9
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -471,7 +471,7 @@ BuildPyPy() {
   # The generated C code leads to many thousands of warnings of the form:
   #   warning: variable 'l_v26003' set but not used [-Wunused-but-set-variable]
   # Suppress them:
-  export CFLAGS=$(echo "$CFLAGS" -Wno-unused)
+  export CFLAGS=$(echo "$CFLAGS" -Wno-unused -fPIC)
 
   # If we're already built the JIT-enabled "pypy", then use it for subsequent
   # builds (of other configurations):
@@ -890,6 +890,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Jun 18 2012 Peter Robinson <pbrobinson at fedoraproject.org> - 1.9-2
+- Compile with PIC, fixes FTBFS on ARM
+
 * Fri Jun  8 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-1
 - 1.9
 
-- 
cgit v0.10.2


From 26f62305fe07f9429bb6f4dc47d8749d7bd8ca7f Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Tue, 10 Jul 2012 16:45:52 -0400
Subject: 1.9-3

* Tue Jul 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-3
- log all output from "make" (patch 6)
- disable the MOTD at startup (patch 7)
- hide symbols from the dynamic linker (patch 8)
- add PyInt_AsUnsignedLongLongMask (patch 9)
- capture the Makefile, the typeids.txt, and the dynamic-symbols file within
the debuginfo package

diff --git a/006-always-log-stdout.patch b/006-always-log-stdout.patch
new file mode 100644
index 0000000..2df1f00
--- /dev/null
+++ b/006-always-log-stdout.patch
@@ -0,0 +1,11 @@
+--- pypy-pypy-341e1e3821ff/pypy/translator/platform/__init__.py.always_log_stdout	2012-07-06 11:13:46.878979461 -0400
++++ pypy-pypy-341e1e3821ff/pypy/translator/platform/__init__.py	2012-07-06 11:25:26.281235732 -0400
+@@ -126,6 +126,8 @@ class Platform(object):
+         self._handle_error(returncode, stdout, stderr, outname)
+ 
+     def _handle_error(self, returncode, stdout, stderr, outname):
++        for line in stdout.splitlines():
++            log.message(line)
+         if returncode != 0:
+             errorfile = outname.new(ext='errors')
+             errorfile.write(stderr, 'wb')
diff --git a/007-remove-startup-message.patch b/007-remove-startup-message.patch
new file mode 100644
index 0000000..e05586b
--- /dev/null
+++ b/007-remove-startup-message.patch
@@ -0,0 +1,21 @@
+--- pypy-pypy-341e1e3821ff/lib_pypy/_pypy_interact.py.remove_startup_message	2012-07-06 12:10:46.504228264 -0400
++++ pypy-pypy-341e1e3821ff/lib_pypy/_pypy_interact.py	2012-07-06 12:11:01.986034714 -0400
+@@ -13,18 +13,6 @@ def interactive_console(mainmodule=None)
+         sys.ps2 = '.... '
+     #
+     try:
+-        from _pypy_irc_topic import some_topic
+-        text = "And now for something completely different: ``%s''" % (
+-            some_topic(),)
+-        while len(text) >= 80:
+-            i = text[:80].rfind(' ')
+-            print text[:i]
+-            text = text[i+1:]
+-        print text
+-    except ImportError:
+-        pass
+-    #
+-    try:
+         if not os.isatty(sys.stdin.fileno()):
+             # Bail out if stdin is not tty-like, as pyrepl wouldn't be happy
+             # For example, with:
diff --git a/008-fix-dynamic-symbols-script.patch b/008-fix-dynamic-symbols-script.patch
new file mode 100644
index 0000000..5b1d551
--- /dev/null
+++ b/008-fix-dynamic-symbols-script.patch
@@ -0,0 +1,15 @@
+diff --git a/pypy/translator/platform/posix.py b/pypy/translator/platform/posix.py
+--- a/pypy/translator/platform/posix.py
++++ b/pypy/translator/platform/posix.py
+@@ -48,8 +48,10 @@
+         response_file = self._make_response_file("dynamic-symbols-")
+         f = response_file.open("w")
+         f.write("{\n")
++        f.write("  global:\n")
+         for sym in eci.export_symbols:
+-            f.write("%s;\n" % (sym,))
++            f.write("    %s;\n" % (sym,))
++        f.write("  local:*;\n")
+         f.write("};")
+         f.close()
+ 
diff --git a/009-add-PyInt_AsUnsignedLongLongMask.patch b/009-add-PyInt_AsUnsignedLongLongMask.patch
new file mode 100644
index 0000000..dae7e16
--- /dev/null
+++ b/009-add-PyInt_AsUnsignedLongLongMask.patch
@@ -0,0 +1,48 @@
+diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py
+--- a/pypy/module/cpyext/intobject.py
++++ b/pypy/module/cpyext/intobject.py
+@@ -6,7 +6,7 @@
+     PyObject, PyObjectFields, CONST_STRING, CANNOT_FAIL, Py_ssize_t)
+ from pypy.module.cpyext.pyobject import (
+     make_typedescr, track_reference, RefcountState, from_ref)
+-from pypy.rlib.rarithmetic import r_uint, intmask, LONG_TEST
++from pypy.rlib.rarithmetic import r_uint, intmask, LONG_TEST, r_ulonglong
+ from pypy.objspace.std.intobject import W_IntObject
+ import sys
+ 
+@@ -83,6 +83,20 @@
+         num = space.bigint_w(w_int)
+         return num.uintmask()
+ 
++ at cpython_api([PyObject], rffi.ULONGLONG, error=-1)
++def PyInt_AsUnsignedLongLongMask(space, w_obj):
++    """Will first attempt to cast the object to a PyIntObject or
++    PyLongObject, if it is not already one, and then return its value as
++    unsigned long long, without checking for overflow.
++    """
++    w_int = space.int(w_obj)
++    if space.is_true(space.isinstance(w_int, space.w_int)):
++        num = space.int_w(w_int)
++        return r_ulonglong(num)
++    else:
++        num = space.bigint_w(w_int)
++        return num.ulonglongmask()
++
+ @cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL)
+ def PyInt_AS_LONG(space, w_int):
+     """Return the value of the object w_int. No error checking is performed."""
+diff --git a/pypy/module/cpyext/test/test_intobject.py b/pypy/module/cpyext/test/test_intobject.py
+--- a/pypy/module/cpyext/test/test_intobject.py
++++ b/pypy/module/cpyext/test/test_intobject.py
+@@ -34,6 +34,11 @@
+         assert (api.PyInt_AsUnsignedLongMask(space.wrap(10**30))
+                 == 10**30 % ((sys.maxint + 1) * 2))
+ 
++        assert (api.PyInt_AsUnsignedLongLongMask(space.wrap(sys.maxint))
++                == sys.maxint)
++        assert (api.PyInt_AsUnsignedLongLongMask(space.wrap(10**30))
++                == 10**30 % (2**64))
++
+     def test_coerce(self, space, api):
+         class Coerce(object):
+             def __int__(self):
diff --git a/pypy.spec b/pypy.spec
index e579720..2ed932b 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.9
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -164,6 +164,39 @@ Patch4: more-readable-c-code.patch
 # Not yet sent upstream
 Patch5: pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
 
+# Patch pypy.translator.platform so that stdout from "make" etc gets logged,
+# rather than just stderr, so that the command-line invocations of the compiler
+# and linker are captured:
+Patch6: 006-always-log-stdout.patch
+
+# Disable the printing of a quote from IRC on startup (these are stored in
+# ROT13 form in lib_pypy/_pypy_irc_topic.py).  Some are cute, but some could
+# cause confusion for end-users (and many are in-jokes within the PyPy
+# community that won't make sense outside of it).  [Sorry to be a killjoy]
+Patch7: 007-remove-startup-message.patch
+
+# With pypy-1.9-1.fc17.x86_64, the pypy binary exposes about 200k symbols to
+# the dynamic linker:
+#    $ eu-readelf -s $(which pypy) | head
+#    Symbol table [ 5] '.dynsym' contains 194163 entries:
+# which is far more than necessary.
+# Fix the version script for the linker as invoked thus in the Makefile:
+#   "-Wl,--export-dynamic,--version-script=../dynamic-symbols-6"
+# so that it contains a "local: *;" clause, thus hiding the bulk of the
+# symbols from the dynamic linker.
+# Ideally we'd add:
+#   __attribute__ ((visibility ("hidden")))
+# to most symbols, allowing the compiler to potentially generate better code.
+# Not yet reported upstream
+Patch8: 008-fix-dynamic-symbols-script.patch
+
+
+# Cherrypick upstream patch to add PyInt_AsUnsignedLongLongMask (used by
+# the rpm python bindings); see https://bugs.pypy.org/issue1211
+# This is https://bitbucket.org/pypy/pypy/changeset/542d481517d3
+Patch9: 009-add-PyInt_AsUnsignedLongLongMask.patch
+
+
 # Build-time requirements:
 
 # pypy's can be rebuilt using itself, rather than with CPython; doing so
@@ -358,6 +391,11 @@ Build of PyPy with support for micro-threads for massive concurrency
 #   [translation:ERROR]  AttributeError: 'Block' object has no attribute 'isstartblock'
 
 %patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+
 
 # Replace /usr/local/bin/python shebangs with /usr/bin/python:
 find -name "*.py" -exec \
@@ -696,15 +734,31 @@ mkdir -p %{buildroot}%{pypy_debuginfo_dir}
 # copy over everything:
 cp -a pypy %{buildroot}%{pypy_debuginfo_dir}
 
-# ...then delete files that aren't .py files:
+# ...then delete files that aren't:
+#   - *.py files
+#   - the Makefile
+#   - typeids.txt
+#   - dynamic-symbols-*
 find \
-  %{buildroot}%{pypy_debuginfo_dir} \
-  \( -type f                        \
-     -a                             \
-     \! -name "*.py"                \
-  \)                                \
+  %{buildroot}%{pypy_debuginfo_dir}  \
+  \( -type f                         \
+     -a                              \
+     \! \( -name "*.py"              \
+           -o                        \
+           -name "Makefile"          \
+           -o                        \
+           -name "typeids.txt"       \
+           -o                        \
+           -name "dynamic-symbols-*" \
+        \)                           \
+  \)                                 \
   -delete
 
+# Alternatively, we could simply keep everything.  This leads to a ~350MB
+# debuginfo package, but it makes it easy to hack on the Makefile and C build
+# flags by rebuilding/linking the sources.
+# To do so, remove the above "find" command.
+
 # We don't need bytecode for these files; they are being included for reference
 # purposes.
 # There are some rpmlint warnings from these files:
@@ -890,6 +944,14 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Jul 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-3
+- log all output from "make" (patch 6)
+- disable the MOTD at startup (patch 7)
+- hide symbols from the dynamic linker (patch 8)
+- add PyInt_AsUnsignedLongLongMask (patch 9)
+- capture the Makefile, the typeids.txt, and the dynamic-symbols file within
+the debuginfo package
+
 * Mon Jun 18 2012 Peter Robinson <pbrobinson at fedoraproject.org> - 1.9-2
 - Compile with PIC, fixes FTBFS on ARM
 
-- 
cgit v0.10.2


From cd9f89c255519e6d52d820882b9cc72cc74932b7 Mon Sep 17 00:00:00 2001
From: Dennis Gilmore <dennis at ausil.us>
Date: Fri, 20 Jul 2012 23:22:27 -0500
Subject: - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild


diff --git a/pypy.spec b/pypy.spec
index 2ed932b..057fbdd 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        1.9
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -944,6 +944,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sat Jul 21 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.9-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
 * Tue Jul 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-3
 - log all output from "make" (patch 6)
 - disable the MOTD at startup (patch 7)
-- 
cgit v0.10.2


From 8e0c0345a5ec642705520ed20aad13dfb15ec7c2 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm at redhat.com>
Date: Thu, 13 Dec 2012 06:16:11 -0500
Subject: 2.0-0.1.b1


diff --git a/.gitignore b/.gitignore
index 4c551cc..2793282 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
 /release-1.7.tar.bz2
 /release-1.8.tar.bz2
 /release-1.9.tar.bz2
+/release-2.0-beta-1.tar.bz2
diff --git a/009-add-PyInt_AsUnsignedLongLongMask.patch b/009-add-PyInt_AsUnsignedLongLongMask.patch
deleted file mode 100644
index dae7e16..0000000
--- a/009-add-PyInt_AsUnsignedLongLongMask.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py
---- a/pypy/module/cpyext/intobject.py
-+++ b/pypy/module/cpyext/intobject.py
-@@ -6,7 +6,7 @@
-     PyObject, PyObjectFields, CONST_STRING, CANNOT_FAIL, Py_ssize_t)
- from pypy.module.cpyext.pyobject import (
-     make_typedescr, track_reference, RefcountState, from_ref)
--from pypy.rlib.rarithmetic import r_uint, intmask, LONG_TEST
-+from pypy.rlib.rarithmetic import r_uint, intmask, LONG_TEST, r_ulonglong
- from pypy.objspace.std.intobject import W_IntObject
- import sys
- 
-@@ -83,6 +83,20 @@
-         num = space.bigint_w(w_int)
-         return num.uintmask()
- 
-+ at cpython_api([PyObject], rffi.ULONGLONG, error=-1)
-+def PyInt_AsUnsignedLongLongMask(space, w_obj):
-+    """Will first attempt to cast the object to a PyIntObject or
-+    PyLongObject, if it is not already one, and then return its value as
-+    unsigned long long, without checking for overflow.
-+    """
-+    w_int = space.int(w_obj)
-+    if space.is_true(space.isinstance(w_int, space.w_int)):
-+        num = space.int_w(w_int)
-+        return r_ulonglong(num)
-+    else:
-+        num = space.bigint_w(w_int)
-+        return num.ulonglongmask()
-+
- @cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL)
- def PyInt_AS_LONG(space, w_int):
-     """Return the value of the object w_int. No error checking is performed."""
-diff --git a/pypy/module/cpyext/test/test_intobject.py b/pypy/module/cpyext/test/test_intobject.py
---- a/pypy/module/cpyext/test/test_intobject.py
-+++ b/pypy/module/cpyext/test/test_intobject.py
-@@ -34,6 +34,11 @@
-         assert (api.PyInt_AsUnsignedLongMask(space.wrap(10**30))
-                 == 10**30 % ((sys.maxint + 1) * 2))
- 
-+        assert (api.PyInt_AsUnsignedLongLongMask(space.wrap(sys.maxint))
-+                == sys.maxint)
-+        assert (api.PyInt_AsUnsignedLongLongMask(space.wrap(10**30))
-+                == 10**30 % (2**64))
-+
-     def test_coerce(self, space, api):
-         class Coerce(object):
-             def __int__(self):
diff --git a/pypy.spec b/pypy.spec
index 057fbdd..b29583d 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,8 @@
+%global alphatag b1
+
 Name:           pypy
-Version:        1.9
-Release:        4%{?dist}
+Version:        2.0
+Release:        0.1.%{alphatag}%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -130,7 +132,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:        https://bitbucket.org/pypy/pypy/get/release-%{version}.tar.bz2
+Source0:        https://bitbucket.org/pypy/pypy/get/release-2.0-beta-1.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -191,12 +193,6 @@ Patch7: 007-remove-startup-message.patch
 Patch8: 008-fix-dynamic-symbols-script.patch
 
 
-# Cherrypick upstream patch to add PyInt_AsUnsignedLongLongMask (used by
-# the rpm python bindings); see https://bugs.pypy.org/issue1211
-# This is https://bitbucket.org/pypy/pypy/changeset/542d481517d3
-Patch9: 009-add-PyInt_AsUnsignedLongLongMask.patch
-
-
 # Build-time requirements:
 
 # pypy's can be rebuilt using itself, rather than with CPython; doing so
@@ -353,7 +349,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-pypy-341e1e3821ff
+%setup -q -n pypy-pypy-07e08e9c885c
 %patch0 -p1 -b .configure-fedora
 %patch1 -p1 -b .suppress-mandelbrot-set-during-tty-build
 
@@ -394,7 +390,6 @@ Build of PyPy with support for micro-threads for massive concurrency
 %patch6 -p1
 %patch7 -p1
 %patch8 -p1
-%patch9 -p1
 
 
 # Replace /usr/local/bin/python shebangs with /usr/bin/python:
@@ -631,6 +626,10 @@ cp -a lib_pypy %{buildroot}/%{pypyprefix}
 # Remove a text file that documents which selftests fail on Win32:
 rm %{buildroot}/%{pypyprefix}/lib-python/win32-failures.txt
 
+# Remove a text file containing upstream's recipe for syncing stdlib in
+# their hg repository with cpython's:
+rm %{buildroot}/%{pypyprefix}/lib-python/stdlib-upgrade.txt
+
 # Remove shebang lines from .py files that aren't executable, and
 # remove executability from .py files that don't have a shebang line:
 find \
@@ -944,6 +943,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Dec 11 2012 David Malcolm <dmalcolm at redhat.com> - 2.0-0.1.b1
+- 2.0b1 (drop upstreamed patch 9)
+
 * Sat Jul 21 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.9-4
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
 
diff --git a/sources b/sources
index 2a64332..e7d211b 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-f92c0171a9578a3e4a0f74947ec596ab  release-1.9.tar.bz2
+4a346df59983e4a5c50e8ee211f80619  release-2.0-beta-1.tar.bz2
-- 
cgit v0.10.2


From fd80b8a933ad44429dfb88ee58aecaf24faf9135 Mon Sep 17 00:00:00 2001
From: Dennis Gilmore <dennis at ausil.us>
Date: Thu, 14 Feb 2013 12:48:36 -0600
Subject: - Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild


diff --git a/pypy.spec b/pypy.spec
index b29583d..dbcbc8d 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -2,7 +2,7 @@
 
 Name:           pypy
 Version:        2.0
-Release:        0.1.%{alphatag}%{?dist}
+Release:        0.2.%{alphatag}%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -943,6 +943,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0-0.2.b1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
 * Tue Dec 11 2012 David Malcolm <dmalcolm at redhat.com> - 2.0-0.1.b1
 - 2.0b1 (drop upstreamed patch 9)
 
-- 
cgit v0.10.2


From c3a10ade23f8dac35b5ef0edc6f2c23856705044 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Mon, 24 Jun 2013 08:57:35 +0200
Subject: Updated to 2.0.2


diff --git a/006-always-log-stdout.patch b/006-always-log-stdout.patch
index 2df1f00..5d49335 100644
--- a/006-always-log-stdout.patch
+++ b/006-always-log-stdout.patch
@@ -1,6 +1,7 @@
---- pypy-pypy-341e1e3821ff/pypy/translator/platform/__init__.py.always_log_stdout	2012-07-06 11:13:46.878979461 -0400
-+++ pypy-pypy-341e1e3821ff/pypy/translator/platform/__init__.py	2012-07-06 11:25:26.281235732 -0400
-@@ -126,6 +126,8 @@ class Platform(object):
+diff -rup pypy-pypy-f66246c46ca3/rpython/translator/platform/__init__.py pypy-pypy-f66246c46ca3/rpython/translator/platform/__init__.py
+--- pypy-pypy-f66246c46ca3/rpython/translator/platform/__init__.py	2013-05-27 10:35:37.680237338 +0200
++++ pypy-pypy-f66246c46ca3/rpython/translator/platform/__init__.py	2013-05-27 10:41:04.113098738 +0200
+@@ -138,6 +138,8 @@ class Platform(object):
          self._handle_error(returncode, stdout, stderr, outname)
  
      def _handle_error(self, returncode, stdout, stderr, outname):
diff --git a/007-remove-startup-message.patch b/007-remove-startup-message.patch
index e05586b..1dddb69 100644
--- a/007-remove-startup-message.patch
+++ b/007-remove-startup-message.patch
@@ -1,21 +1,12 @@
---- pypy-pypy-341e1e3821ff/lib_pypy/_pypy_interact.py.remove_startup_message	2012-07-06 12:10:46.504228264 -0400
-+++ pypy-pypy-341e1e3821ff/lib_pypy/_pypy_interact.py	2012-07-06 12:11:01.986034714 -0400
-@@ -13,18 +13,6 @@ def interactive_console(mainmodule=None)
-         sys.ps2 = '.... '
-     #
-     try:
--        from _pypy_irc_topic import some_topic
--        text = "And now for something completely different: ``%s''" % (
--            some_topic(),)
--        while len(text) >= 80:
--            i = text[:80].rfind(' ')
--            print text[:i]
--            text = text[i+1:]
--        print text
--    except ImportError:
--        pass
--    #
--    try:
-         if not os.isatty(sys.stdin.fileno()):
-             # Bail out if stdin is not tty-like, as pyrepl wouldn't be happy
-             # For example, with:
+diff -rup pypy-pypy-f66246c46ca3/lib_pypy/_pypy_interact.py pypy-pypy-f66246c46ca3/lib_pypy/_pypy_interact.py
+--- pypy-pypy-f66246c46ca3/lib_pypy/_pypy_interact.py	2013-05-27 10:35:37.612236951 +0200
++++ pypy-pypy-f66246c46ca3/lib_pypy/_pypy_interact.py	2013-05-27 10:37:25.602852747 +0200
+@@ -4,7 +4,7 @@ import sys
+ import os
+ 
+ 
+-def interactive_console(mainmodule=None, quiet=False):
++def interactive_console(mainmodule=None, quiet=True):
+     # set sys.{ps1,ps2} just before invoking the interactive interpreter. This
+     # mimics what CPython does in pythonrun.c
+     if not hasattr(sys, 'ps1'):
diff --git a/config.patch b/config.patch
index a11f397..bf81d7d 100644
--- a/config.patch
+++ b/config.patch
@@ -1,7 +1,7 @@
-diff -up pypy-pypy-2346207d9946/pypy/translator/platform/linux.py.configure-fedora pypy-pypy-2346207d9946/pypy/translator/platform/linux.py
---- pypy-pypy-2346207d9946/pypy/translator/platform/linux.py.configure-fedora	2012-02-09 13:27:19.000000000 -0500
-+++ pypy-pypy-2346207d9946/pypy/translator/platform/linux.py	2012-02-10 09:06:20.393066016 -0500
-@@ -31,13 +31,14 @@ class BaseLinux(BasePosix):
+diff -rup pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py
+--- pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py	2013-05-27 10:35:37.679237332 +0200
++++ pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py	2013-05-27 10:47:41.506354482 +0200
+@@ -32,19 +32,20 @@ class BaseLinux(BasePosix):
          return self._pkg_config("libffi", "--libs-only-L",
                                  ['/usr/lib/libffi'])
  
@@ -9,15 +9,27 @@ diff -up pypy-pypy-2346207d9946/pypy/translator/platform/linux.py.configure-fedo
 -        # places where we need to look for libffi.a
 -        # XXX obscuuure!  only look for libffi.a if run with translate.py
 -        if 'translate' in sys.modules:
--            return self.library_dirs_for_libffi() + ['/usr/lib']
+-            if sys.maxint > 2**32:
+-                host = 'x86_64'
+-            else:
+-                host = 'x86'
+-            return self.library_dirs_for_libffi() + [
+-                '/usr/lib',
+-                '/usr/lib/%s-linux-gnu/' % host]
 -        else:
 -            return []
-+    # Fedora, at least, has the shared version but not the static:
++    #Fedora, at least, has the shared version but not the static:
 +    #def library_dirs_for_libffi_a(self):
 +    #    # places where we need to look for libffi.a
 +    #    # XXX obscuuure!  only look for libffi.a if run with translate.py
 +    #    if 'translate' in sys.modules:
-+    #        return self.library_dirs_for_libffi() + ['/usr/lib']
++    #        if sys.maxint > 2**32:
++    #            host = 'x86_64'
++    #        else:
++    #            host = 'x86'
++    #        return self.library_dirs_for_libffi() + [
++    #            '/usr/lib',
++    #            '/usr/lib/%s-linux-gnu/' % host]
 +    #    else:
 +    #        return []
  
diff --git a/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch b/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
index 9071be5..2391f32 100644
--- a/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
+++ b/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
@@ -1,6 +1,7 @@
---- pypy-pypy-2346207d9946/lib-python/2.7/test/test_subprocess.py.orig	2012-02-09 13:27:19.000000000 -0500
-+++ pypy-pypy-2346207d9946/lib-python/2.7/test/test_subprocess.py	2012-02-10 09:14:08.312216221 -0500
-@@ -570,7 +570,7 @@ class ProcessTestCase(BaseTestCase):
+diff -rup pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py
+--- pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py	2013-05-27 10:35:37.762237806 +0200
++++ pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py	2013-05-28 10:13:03.182536196 +0200
+@@ -587,7 +587,7 @@ class ProcessTestCase(BaseTestCase):
          for i in range(1024):
              # Windows raises IOError.  Others raise OSError.
              with self.assertRaises(EnvironmentError) as c:
diff --git a/pypy.spec b/pypy.spec
index dbcbc8d..1ce9198 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,8 +1,8 @@
 %global alphatag b1
 
 Name:           pypy
-Version:        2.0
-Release:        0.2.%{alphatag}%{?dist}
+Version:        2.0.2
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -123,7 +123,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 %global pylibver 2.7
 
 # We refer to this subdir of the source tree in a few places during the build:
-%global goal_dir pypy/translator/goal
+%global goal_dir pypy/goal
 
 
 # Turn off the brp-python-bytecompile postprocessing script
@@ -132,7 +132,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:        https://bitbucket.org/pypy/pypy/get/release-2.0-beta-1.tar.bz2
+Source0:	https://bitbucket.org/pypy/pypy/get/release-2.0.2.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -177,21 +177,6 @@ Patch6: 006-always-log-stdout.patch
 # community that won't make sense outside of it).  [Sorry to be a killjoy]
 Patch7: 007-remove-startup-message.patch
 
-# With pypy-1.9-1.fc17.x86_64, the pypy binary exposes about 200k symbols to
-# the dynamic linker:
-#    $ eu-readelf -s $(which pypy) | head
-#    Symbol table [ 5] '.dynsym' contains 194163 entries:
-# which is far more than necessary.
-# Fix the version script for the linker as invoked thus in the Makefile:
-#   "-Wl,--export-dynamic,--version-script=../dynamic-symbols-6"
-# so that it contains a "local: *;" clause, thus hiding the bulk of the
-# symbols from the dynamic linker.
-# Ideally we'd add:
-#   __attribute__ ((visibility ("hidden")))
-# to most symbols, allowing the compiler to potentially generate better code.
-# Not yet reported upstream
-Patch8: 008-fix-dynamic-symbols-script.patch
-
 
 # Build-time requirements:
 
@@ -349,7 +334,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-pypy-07e08e9c885c
+%setup -q -n pypy-pypy-f66246c46ca3
 %patch0 -p1 -b .configure-fedora
 %patch1 -p1 -b .suppress-mandelbrot-set-during-tty-build
 
@@ -389,7 +374,6 @@ Build of PyPy with support for micro-threads for massive concurrency
 %patch5 -p1
 %patch6 -p1
 %patch7 -p1
-%patch8 -p1
 
 
 # Replace /usr/local/bin/python shebangs with /usr/bin/python:
@@ -408,9 +392,7 @@ find . -path '*/.svn*' -delete
 # Remove DOS batch files:
 find -name "*.bat"|xargs rm -f
 
-# The "demo" directory gets auto-installed by virture of being listed in %doc
-# Remove shebang lines from demo .py files, and remove executability from them:
-for f in demo/bpnn.py ; do
+for f in rpython/translator/goal/bpnn.py ; do
    # Detect shebang lines && remove them:
    sed -e '/^#!/Q 0' -e 'Q 1' $f \
       && sed -i '1d' $f
@@ -522,15 +504,11 @@ BuildPyPy() {
     RPM_BUILD_ROOT= \
     PYPY_USESSION_DIR=$(pwd) \
     PYPY_USESSION_BASENAME=$ExeName \
-    $INTERP translate.py \
-%if 0%{verbose_logs}
-    --translation-verbose \
-%endif
-    --cflags="$CFLAGS" \
-    --batch \
+    $INTERP ../../rpython/bin/rpython  \
     --output=$ExeName \
     %{gcrootfinder_options} \
-    $Options
+    $Options \
+    targetpypystandalone
 
   echo "--------------------------------------------------------------"
   echo "--------------------------------------------------------------"
@@ -559,7 +537,7 @@ BuildPyPy \
 %endif
 
 %if %{with_emacs}
-%{_emacs_bytecompile} pypy/jit/tool/pypytrace-mode.el
+%{_emacs_bytecompile} rpython/jit/tool/pypytrace-mode.el
 %endif
 
 %install
@@ -772,7 +750,7 @@ find \
 # Install the JIT trace mode for Emacs:
 %if %{with_emacs}
 mkdir -p %{buildroot}/%{_emacs_sitelispdir}
-cp -a pypy/jit/tool/pypytrace-mode.el* %{buildroot}/%{_emacs_sitelispdir}
+cp -a rpython/jit/tool/pypytrace-mode.el* %{buildroot}/%{_emacs_sitelispdir}
 %endif
 
 # Install macros for rpm:
@@ -908,7 +886,7 @@ rm -rf $RPM_BUILD_ROOT
 
 %files libs
 %defattr(-,root,root,-)
-%doc LICENSE README demo
+%doc LICENSE README.rst
 
 %dir %{pypyprefix}
 %dir %{pypyprefix}/lib-python
@@ -924,7 +902,7 @@ rm -rf $RPM_BUILD_ROOT
 
 %files
 %defattr(-,root,root,-)
-%doc LICENSE README
+%doc LICENSE README.rst
 %{_bindir}/pypy
 %{pypyprefix}/pypy
 
@@ -937,12 +915,15 @@ rm -rf $RPM_BUILD_ROOT
 %if 0%{with_stackless}
 %files stackless
 %defattr(-,root,root,-)
-%doc LICENSE README
+%doc LICENSE README.rst
 %{_bindir}/pypy-stackless
 %endif
 
 
 %changelog
+* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-1
+- 2.0.2, patch 8 does not seem necessary anymore
+
 * Thu Feb 14 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0-0.2.b1
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
 
-- 
cgit v0.10.2


From 5694529edb24cba3edd56720cee077b791e8378c Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Mon, 24 Jun 2013 09:24:07 +0200
Subject: Fixed Source URL


diff --git a/pypy.spec b/pypy.spec
index 1ce9198..66a66a9 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -2,7 +2,7 @@
 
 Name:           pypy
 Version:        2.0.2
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -132,7 +132,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:	https://bitbucket.org/pypy/pypy/get/release-2.0.2.tar.bz2
+Source0:	https://bitbucket.org/pypy/pypy/get/release-2.0.2.tar.bz2#/pypy-pypy-f66246c46ca3.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -921,6 +921,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-2
+- Fixed Source URL
+
 * Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-1
 - 2.0.2, patch 8 does not seem necessary anymore
 
-- 
cgit v0.10.2


From 8c737bc2aa985ae04d4540daefef663e827f8ba2 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Mon, 24 Jun 2013 10:29:01 +0200
Subject: Yet another Sources fix


diff --git a/.gitignore b/.gitignore
index 2793282..63a65d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
 /release-1.8.tar.bz2
 /release-1.9.tar.bz2
 /release-2.0-beta-1.tar.bz2
+/release-2.0.2.tar.bz2
diff --git a/pypy.spec b/pypy.spec
index 66a66a9..2470609 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -2,7 +2,7 @@
 
 Name:           pypy
 Version:        2.0.2
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -132,7 +132,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:	https://bitbucket.org/pypy/pypy/get/release-2.0.2.tar.bz2#/pypy-pypy-f66246c46ca3.tar.bz2
+Source0:	https://bitbucket.org/pypy/pypy/get/release-2.0.2.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -921,6 +921,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-3
+- Yet another Sources fix
+
 * Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-2
 - Fixed Source URL
 
diff --git a/sources b/sources
index e7d211b..a37f747 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-4a346df59983e4a5c50e8ee211f80619  release-2.0-beta-1.tar.bz2
+328a509c092b5477f99be8dd452d81c2  release-2.0.2.tar.bz2
-- 
cgit v0.10.2


From b4e1c2185a5384e5ba4d898fe7fbca0ad3db45c2 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Mon, 24 Jun 2013 10:44:06 +0200
Subject: Patch1 fix


diff --git a/pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch b/pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
index 257f60f..c97eaf3 100644
--- a/pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
+++ b/pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
@@ -1,7 +1,6 @@
-diff --git a/pypy/tool/ansi_print.py b/pypy/tool/ansi_print.py
-index 3eff27c..fac4ba2 100644
---- a/pypy/tool/ansi_print.py
-+++ b/pypy/tool/ansi_print.py
+diff -rup pypy-pypy-f66246c46ca3/rpython/tool/ansi_print.py pypy-pypy-f66246c46ca3/rpython/tool/ansi_print.py
+--- pypy-pypy-f66246c46ca3/rpython/tool/ansi_print.py	2013-05-27 10:35:37.648237156 +0200
++++ pypy-pypy-f66246c46ca3/rpython/tool/ansi_print.py	2013-05-28 10:15:58.200426205 +0200
 @@ -25,7 +25,7 @@ class AnsiLog:
          self.kw_to_color = self.KW_TO_COLOR.copy()
          self.kw_to_color.update(kw_to_color)
diff --git a/pypy.spec b/pypy.spec
index 2470609..8f28baf 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -2,7 +2,7 @@
 
 Name:           pypy
 Version:        2.0.2
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -921,6 +921,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-4
+- Patch1 fix
+
 * Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-3
 - Yet another Sources fix
 
-- 
cgit v0.10.2


From 309e1cf6aab2cc2ecf9ae9897a22f271a9d4fb9c Mon Sep 17 00:00:00 2001
From: Dennis Gilmore <dennis at ausil.us>
Date: Sun, 4 Aug 2013 01:04:23 -0500
Subject: - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild


diff --git a/pypy.spec b/pypy.spec
index 8f28baf..1c72138 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -2,7 +2,7 @@
 
 Name:           pypy
 Version:        2.0.2
-Release:        4%{?dist}
+Release:        5%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -921,6 +921,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sun Aug 04 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0.2-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
 * Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-4
 - Patch1 fix
 
-- 
cgit v0.10.2


From febbbdb0e4b360dffdd77a04e5101afc16e463a8 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Fri, 16 Aug 2013 10:12:29 +0200
Subject: Updated to 2.1.0


diff --git a/.gitignore b/.gitignore
index 63a65d6..cad553e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@
 /release-1.9.tar.bz2
 /release-2.0-beta-1.tar.bz2
 /release-2.0.2.tar.bz2
+/release-2.1.0.tar.bz2
diff --git a/pypy.spec b/pypy.spec
index 1c72138..e7ef81f 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,8 +1,6 @@
-%global alphatag b1
-
 Name:           pypy
-Version:        2.0.2
-Release:        5%{?dist}
+Version:        2.1.0
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -132,50 +130,28 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:	https://bitbucket.org/pypy/pypy/get/release-2.0.2.tar.bz2
+Source0:	https://bitbucket.org/pypy/pypy/get/release-2.1.0.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
-Source2:        macros.pypy
-
-# Edit a translator file for linux in order to configure our cflags and dynamic libffi
-Patch0:         config.patch
+Source2: macros.pypy
 
 # By default, if built at a tty, the translation process renders a Mandelbrot
 # set to indicate progress.
 # This obscures useful messages, and may waste CPU cycles, so suppress it, and
 # merely render dots:
-Patch1:         pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
-
-# Try to improve the readability of the generated .c code, by adding in the
-# RPython source as comments where possible.
-# A version of this was sent upstream as:
-#  http://codespeak.net/pipermail/pypy-dev/2010q4/006532.html
-# TODO: get this into the upstream bug tracker, and finish inlining
-# support (rhbz#666963)
-Patch4: more-readable-c-code.patch
-
-# In my koji builds, /root/bin is in the PATH for some reason
-# This leads to test_subprocess.py failing, due to "test_leaking_fds_on_error"
-# trying every dir in PATH for "nonexisting_i_hope", which leads to it raising
-#  OSError: [Errno 13] Permission denied
-# when it tries to read /root/bin, rather than raising "No such file"
-#
-# Work around this by specifying an absolute path for the non-existant
-# executable
-# Not yet sent upstream
-Patch5: pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
+Patch0: pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
 
 # Patch pypy.translator.platform so that stdout from "make" etc gets logged,
 # rather than just stderr, so that the command-line invocations of the compiler
 # and linker are captured:
-Patch6: 006-always-log-stdout.patch
+Patch1: 006-always-log-stdout.patch
 
 # Disable the printing of a quote from IRC on startup (these are stored in
 # ROT13 form in lib_pypy/_pypy_irc_topic.py).  Some are cute, but some could
 # cause confusion for end-users (and many are in-jokes within the PyPy
 # community that won't make sense outside of it).  [Sorry to be a killjoy]
-Patch7: 007-remove-startup-message.patch
+Patch2: 007-remove-startup-message.patch
 
 
 # Build-time requirements:
@@ -186,37 +162,7 @@ Patch7: 007-remove-startup-message.patch
 # Turn it off with this boolean, to revert back to rebuilding using CPython
 # and avoid a cycle in the build-time dependency graph:
 
-# I'm disabling the self-hosting for now, due to a fatal error seen inside the
-# JIT, presumably whilst JIT-compiling something within the translator's
-# inliner.
-# 
-# Specifically, building pypy-1.4.1-7.fc15.src.rpm on x86_64 using pypy-1.4.1-5.fc15.x86_64 
-#   http://koji.fedoraproject.org/koji/taskinfo?taskID=2721517
-# failed with this RPython traceback:
-#     ... snip ...
-#   [rtyper:WARNING] prebuilt instance <pypy.rpython.memory.gctransform.asmgcroot.ShapeDecompressor instance at 0x00000000f0b5bc80> has no attribute 'addr'
-#   [rtyper] specializing: 179300 / 180508 blocks   (99%)
-#   [rtyper] specializing: 180500 / 180566 blocks   (99%)
-#   [rtyper] -=- specialized 1363 more blocks -=-
-#   [rtyper] specializing: 180600 / 180777 blocks   (99%)
-#   [rtyper] -=- specialized 211 more blocks -=-
-#   [backendopt:inlining] phase with threshold factor: 32.4
-#   [backendopt:inlining] heuristic: pypy.translator.backendopt.inline.inlining_heuristic
-#   [x86/regalloc] Bogus arg in operation 76 at 0
-#   RPython traceback:
-#     File "implement_62.c", line 39979, in send_bridge_to_backend
-#     File "implement_69.c", line 65301, in Assembler386_assemble_bridge
-#     File "implement_72.c", line 8078, in RegAlloc_prepare_bridge
-#     File "implement_40.c", line 53061, in RegAlloc__prepare
-#     File "implement_44.c", line 14305, in RegAlloc__compute_vars_longevity
-#   Fatal RPython error: NotImplementedError
-#
-# This appears to be deep within pypy/jit/backend/x86/regalloc.py which has
-# called "not_implemented" to emit this message to stderr, before raising the
-# exception:
-#   [x86/regalloc] Bogus arg in operation 76 at 0
-
-%global use_self_when_building 0
+%global use_self_when_building 1
 %if 0%{use_self_when_building}
 BuildRequires: pypy
 %global bootstrap_python_interp pypy
@@ -234,12 +180,6 @@ BuildRequires: python-devel
 
 %endif
 
-
-# FIXME: I'm seeing errors like this in the logs:
-#   [translation:WARNING] The module '_rawffi' is disabled
-#   [translation:WARNING] because importing pypy.rlib.libffi raised ImportError
-#   [translation:WARNING] 'libffi.a' not found in ['/usr/lib/libffi', '/usr/lib']
-# Presumably we need to fix things to support dynamically-linked libffi
 BuildRequires:  libffi-devel
 
 BuildRequires:  zlib-devel
@@ -269,11 +209,6 @@ BuildRequires:  /usr/bin/execstack
 BuildRequires:  emacs
 %endif
 
-# pypy is bundling these so we delete them in %%prep.  I don't think they are
-# needed unless we build pypy targetted at running on the jvm.
-#BuildRequires:  jna
-#BuildRequires: jasmin  # Not yet in Fedora
-
 
 # Metadata for the core package (the JIT build):
 Requires: pypy-libs = %{version}-%{release}
@@ -334,47 +269,10 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-pypy-f66246c46ca3
-%patch0 -p1 -b .configure-fedora
-%patch1 -p1 -b .suppress-mandelbrot-set-during-tty-build
-
-# Disabled for now, as it needs regenerating for 1.8
-#patch4 -p1 -b .more-readable-c-code
-# Fails on 1.8 with this error:
-#   [translation:ERROR] Error:
-#   [translation:ERROR]  Traceback (most recent call last):
-#   [translation:ERROR]    File "translate.py", line 309, in main
-#   [translation:ERROR]     drv.proceed(goals)
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/driver.py", line 811, in proceed
-#   [translation:ERROR]     return self._execute(goals, task_skip = self._maybe_skip())
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/tool/taskengine.py", line 116, in _execute
-#   [translation:ERROR]     res = self._do(goal, taskcallable, *args, **kwds)
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/driver.py", line 287, in _do
-#   [translation:ERROR]     res = func()
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/driver.py", line 530, in task_source_c
-#   [translation:ERROR]     exe_name=exe_name)
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/genc.py", line 252, in generate_source
-#   [translation:ERROR]     split=self.split)
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/genc.py", line 989, in gen_source
-#   [translation:ERROR]     sg.gen_readable_parts_of_source(f)
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/genc.py", line 843, in gen_readable_parts_of_source
-#   [translation:ERROR]     for node, impl in nodeiter:
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/genc.py", line 729, in subiter
-#   [translation:ERROR]     impl = '\n'.join(list(node.implementation())).split('\n')
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/node.py", line 867, in implementation
-#   [translation:ERROR]     for s in self.funcgen_implementation(funcgen):
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/node.py", line 901, in funcgen_implementation
-#   [translation:ERROR]     for line in bodyiter:
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/funcgen.py", line 272, in cfunction_body
-#   [translation:ERROR]     blocks.sort(block_comparator)
-#   [translation:ERROR]    File "/builddir/build/BUILD/pypy-pypy-2346207d9946/pypy/translator/c/funcgen.py", line 34, in block_comparator
-#   [translation:ERROR]     if blk0.isstartblock:
-#   [translation:ERROR]  AttributeError: 'Block' object has no attribute 'isstartblock'
-
-%patch5 -p1
-%patch6 -p1
-%patch7 -p1
-
+%setup -q -n pypy-pypy-352c78d2e80f
+%patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
+%patch1 -p1
+%patch2 -p1
 
 # Replace /usr/local/bin/python shebangs with /usr/bin/python:
 find -name "*.py" -exec \
@@ -383,15 +281,6 @@ find -name "*.py" -exec \
     "{}" \
     \;
 
-find . -name '*.jar' -exec rm \{\} \;
-
-# Remove stray ".svn" directories present within the 1.4.1 tarball
-# (reported as https://codespeak.net/issue/pypy-dev/issue612 )
-find . -path '*/.svn*' -delete
-
-# Remove DOS batch files:
-find -name "*.bat"|xargs rm -f
-
 for f in rpython/translator/goal/bpnn.py ; do
    # Detect shebang lines && remove them:
    sed -e '/^#!/Q 0' -e 'Q 1' $f \
@@ -399,6 +288,7 @@ for f in rpython/translator/goal/bpnn.py ; do
    chmod a-x $f
 done
 
+
 %build
 
 BuildPyPy() {
@@ -540,10 +430,10 @@ BuildPyPy \
 %{_emacs_bytecompile} rpython/jit/tool/pypytrace-mode.el
 %endif
 
+
 %install
 rm -rf $RPM_BUILD_ROOT
 
-
 # Install the various executables:
 
 InstallPyPy() {
@@ -921,6 +811,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Aug 15 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.1-1
+- Updated to 2.1.0
+
 * Sun Aug 04 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0.2-5
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
 
diff --git a/sources b/sources
index a37f747..fff5a1a 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-328a509c092b5477f99be8dd452d81c2  release-2.0.2.tar.bz2
+59af571317843a1759cb1ff392c26260  release-2.1.0.tar.bz2
-- 
cgit v0.10.2


From 66ffb916e263ca7b45e75d7a209248c04f918264 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Tue, 12 Nov 2013 10:19:28 +0100
Subject: Updated to 2.2.0


diff --git a/.gitignore b/.gitignore
index cad553e..fa54eea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@
 /release-2.0-beta-1.tar.bz2
 /release-2.0.2.tar.bz2
 /release-2.1.0.tar.bz2
+/pypy-2.2-src.tar.bz2
diff --git a/pypy.spec b/pypy.spec
index e7ef81f..cd225b9 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,5 +1,5 @@
 Name:           pypy
-Version:        2.1.0
+Version:        2.2.0
 Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
@@ -130,7 +130,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:	https://bitbucket.org/pypy/pypy/get/release-2.1.0.tar.bz2
+Source0:	https://bitbucket.org/pypy/pypy/downloads/pypy-2.2-src.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -162,7 +162,7 @@ Patch2: 007-remove-startup-message.patch
 # Turn it off with this boolean, to revert back to rebuilding using CPython
 # and avoid a cycle in the build-time dependency graph:
 
-%global use_self_when_building 1
+%global use_self_when_building 0
 %if 0%{use_self_when_building}
 BuildRequires: pypy
 %global bootstrap_python_interp pypy
@@ -269,7 +269,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-pypy-352c78d2e80f
+%setup -q -n pypy-2.2-src
 %patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
 %patch1 -p1
 %patch2 -p1
@@ -811,6 +811,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Nov 14 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.2.0-1
+- Updated to 2.2.0
+
 * Thu Aug 15 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.1-1
 - Updated to 2.1.0
 
diff --git a/sources b/sources
index fff5a1a..d5b9932 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-59af571317843a1759cb1ff392c26260  release-2.1.0.tar.bz2
+5a5a3822605d7d811066b1b279da3c6e  pypy-2.2-src.tar.bz2
-- 
cgit v0.10.2


From a79a105a7453f9b3f55d296774b2b28a256d8318 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Thu, 2 Jan 2014 10:45:26 +0100
Subject: Bytecompiled bunch of modules


diff --git a/pypy.spec b/pypy.spec
index cd225b9..cfb219f 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -181,6 +181,10 @@ BuildRequires: python-devel
 %endif
 
 BuildRequires:  libffi-devel
+BuildRequires:  tcl-devel
+BuildRequires:  tk-devel
+
+BuildRequires:  sqlite-devel
 
 BuildRequires:  zlib-devel
 BuildRequires:  bzip2-devel
@@ -577,6 +581,10 @@ mkdir -p %{buildroot}/%{pypyprefix}/site-packages
   %{buildroot}/%{_bindir}/pypy \
   0
 
+%{goal_dir}/pypy -c 'import _tkinter'
+%{goal_dir}/pypy -c 'import _sqlite3'
+%{goal_dir}/pypy -c 'import _curses'
+%{goal_dir}/pypy -c 'import syslog'
 
 # Header files for C extension modules.
 # Upstream's packaging process (pypy/tool/release/package.py)
-- 
cgit v0.10.2


From 2cbecfd01cab504997f12fd8b434035e083dcec6 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Thu, 2 Jan 2014 10:47:41 +0100
Subject: Update to 2.2.1


diff --git a/.gitignore b/.gitignore
index fa54eea..da7257b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@
 /release-2.0.2.tar.bz2
 /release-2.1.0.tar.bz2
 /pypy-2.2-src.tar.bz2
+/pypy-2.2.1-src.tar.bz2
diff --git a/pypy.spec b/pypy.spec
index cfb219f..21987ac 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,5 +1,5 @@
 Name:           pypy
-Version:        2.2.0
+Version:        2.2.1
 Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
@@ -130,7 +130,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:	https://bitbucket.org/pypy/pypy/downloads/pypy-2.2-src.tar.bz2
+Source0:	https://bitbucket.org/pypy/pypy/downloads/pypy-2.2.1-src.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -273,7 +273,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-2.2-src
+%setup -q -n pypy-2.2.1-src
 %patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
 %patch1 -p1
 %patch2 -p1
@@ -768,6 +768,11 @@ CheckPyPy() {
     echo "--------------------------------------------------------------"
 }
 
+#python testrunner/runner.py --logfile=pytest-A.log --config=pypy/pytest-A.cfg --config=pypy/pytest-A.py --root=pypy --timeout=3600
+#python pypy/test_all.py --pypy=pypy/goal/pypy --timeout=3600 --resultlog=cpython.log lib-python
+#python pypy/test_all.py --pypy=pypy/goal/pypy --resultlog=pypyjit.log pypy/module/pypyjit/test
+#pypy/goal/pypy pypy/test_all.py --resultlog=pypyjit_new.log
+
 %if %{run_selftests}
 CheckPyPy pypy
 
@@ -819,6 +824,12 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Dec 05 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-1
+- Updated to 2.2.1
+- Several bundled modules (tkinter, sqlite3, curses, syslog) were
+  not bytecompiled properly during build, that is now fixed
+- prepared new tests, not enabled yet
+
 * Thu Nov 14 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.2.0-1
 - Updated to 2.2.0
 
diff --git a/sources b/sources
index d5b9932..f8f0564 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-5a5a3822605d7d811066b1b279da3c6e  pypy-2.2-src.tar.bz2
+7ec9f48702323f9e93654ba73dd46720  pypy-2.2.1-src.tar.bz2
-- 
cgit v0.10.2


From f8a7311107aa7a76736e8e763a17148340131c32 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Fri, 17 Jan 2014 10:46:17 +0100
Subject: Fix errors due to missing __pycache__


diff --git a/pypy.spec b/pypy.spec
index 21987ac..8604207 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.2.1
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -581,10 +581,13 @@ mkdir -p %{buildroot}/%{pypyprefix}/site-packages
   %{buildroot}/%{_bindir}/pypy \
   0
 
-%{goal_dir}/pypy -c 'import _tkinter'
-%{goal_dir}/pypy -c 'import _sqlite3'
-%{goal_dir}/pypy -c 'import _curses'
-%{goal_dir}/pypy -c 'import syslog'
+%{buildroot}/%{pypyprefix}/pypy -c 'import _tkinter'
+%{buildroot}/%{pypyprefix}/pypy -c 'import Tkinter'
+%{buildroot}/%{pypyprefix}/pypy -c 'import _sqlite3'
+%{buildroot}/%{pypyprefix}/pypy -c 'import _curses'
+%{buildroot}/%{pypyprefix}/pypy -c 'import curses'
+%{buildroot}/%{pypyprefix}/pypy -c 'import syslog'
+%{buildroot}/%{pypyprefix}/pypy -c 'from _sqlite3 import *'
 
 # Header files for C extension modules.
 # Upstream's packaging process (pypy/tool/release/package.py)
@@ -824,6 +827,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu Jan 16 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-2
+- Fixed errors due to missing __pycache__
+
 * Thu Dec 05 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-1
 - Updated to 2.2.1
 - Several bundled modules (tkinter, sqlite3, curses, syslog) were
-- 
cgit v0.10.2


From 355feb2755aa6396e4fa0b512652ce25c2502ca7 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Mon, 3 Feb 2014 13:24:01 +0100
Subject: Put rpm macros in proper location


diff --git a/pypy.spec b/pypy.spec
index 8604207..6e73099 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -655,8 +655,8 @@ cp -a rpython/jit/tool/pypytrace-mode.el* %{buildroot}/%{_emacs_sitelispdir}
 %endif
 
 # Install macros for rpm:
-mkdir -p %{buildroot}/%{_sysconfdir}/rpm
-install -m 644 %{SOURCE2} %{buildroot}/%{_sysconfdir}/rpm
+mkdir -p %{buildroot}/%{_rpmconfigdir}/macros.d
+install -m 644 %{SOURCE2} %{buildroot}/%{_rpmconfigdir}/macros.d
 
 %check
 topdir=$(pwd)
-- 
cgit v0.10.2


From 4dbc78c1aab1cf75870cf055ad54a46262e3fafb Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Mon, 10 Mar 2014 09:17:48 +0100
Subject: Also add changelog entry


diff --git a/pypy.spec b/pypy.spec
index 6e73099..85003c1 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.2.1
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -827,6 +827,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Mar 10 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-3
+- Put RPM macros in proper location
+
 * Thu Jan 16 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-2
 - Fixed errors due to missing __pycache__
 
-- 
cgit v0.10.2


From bca3bcda512353328ab9a768e28d0ac7b6904aa6 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Tue, 11 Mar 2014 09:05:43 +0100
Subject: Also chenge files section


diff --git a/pypy.spec b/pypy.spec
index 85003c1..c46997a 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -816,7 +816,7 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %dir %{pypy_include_dir}
 %{pypy_include_dir}/*.h
-%config(noreplace) %{_sysconfdir}/rpm/macros.pypy
+%config(noreplace) %{_rpmconfigdir}/macros.d/macros.pypy
 
 %if 0%{with_stackless}
 %files stackless
-- 
cgit v0.10.2


From db10290f0939d5c2dfd4d437bc2f98888752a48b Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Wed, 14 May 2014 12:40:14 +0200
Subject: Update to 2.3


diff --git a/.gitignore b/.gitignore
index da7257b..f59302b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@
 /release-2.1.0.tar.bz2
 /pypy-2.2-src.tar.bz2
 /pypy-2.2.1-src.tar.bz2
+/pypy-2.3-src.tar.bz2
diff --git a/007-remove-startup-message.patch b/007-remove-startup-message.patch
index 1dddb69..2ff9068 100644
--- a/007-remove-startup-message.patch
+++ b/007-remove-startup-message.patch
@@ -2,7 +2,7 @@ diff -rup pypy-pypy-f66246c46ca3/lib_pypy/_pypy_interact.py pypy-pypy-f66246c46c
 --- pypy-pypy-f66246c46ca3/lib_pypy/_pypy_interact.py	2013-05-27 10:35:37.612236951 +0200
 +++ pypy-pypy-f66246c46ca3/lib_pypy/_pypy_interact.py	2013-05-27 10:37:25.602852747 +0200
 @@ -4,7 +4,7 @@ import sys
- import os
+ irc_header = "And now for something completely different"
  
  
 -def interactive_console(mainmodule=None, quiet=False):
diff --git a/pypy.spec b/pypy.spec
index c46997a..6e050f3 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
-Version:        2.2.1
-Release:        3%{?dist}
+Version:        2.3
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -130,7 +130,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:	https://bitbucket.org/pypy/pypy/downloads/pypy-2.2.1-src.tar.bz2
+Source0:	https://bitbucket.org/pypy/pypy/downloads/pypy-2.3-src.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -273,7 +273,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-2.2.1-src
+%setup -q -n pypy-pypy-394146e9bb67
 %patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
 %patch1 -p1
 %patch2 -p1
@@ -827,6 +827,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue May 13 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3-1
+- Updated to 2.3
+
 * Mon Mar 10 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-3
 - Put RPM macros in proper location
 
diff --git a/sources b/sources
index f8f0564..8f25b0c 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-7ec9f48702323f9e93654ba73dd46720  pypy-2.2.1-src.tar.bz2
+c93a8e47f3b3109af2f66d2bd766eb97  pypy-2.3-src.tar.bz2
-- 
cgit v0.10.2


From a3993a30d37ff85750008622cc987a4650786896 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Thu, 15 May 2014 12:20:24 +0200
Subject: Rebuilt (f21-python)


diff --git a/pypy.spec b/pypy.spec
index 6e050f3..39b18d8 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.3
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -827,6 +827,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Thu May 15 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3-2
+- Rebuilt (f21-python)
+
 * Tue May 13 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3-1
 - Updated to 2.3
 
-- 
cgit v0.10.2


From ce731cfa651140b831eeeabd176c041b6f9f4943 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad at redhat.com>
Date: Wed, 21 May 2014 12:32:28 +0200
Subject: - Rebuilt for https://fedoraproject.org/wiki/Changes/f21tcl86


diff --git a/pypy.spec b/pypy.spec
index 39b18d8..096bd7d 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.3
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -827,6 +827,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Wed May 21 2014 Jaroslav Škarvada <jskarvad at redhat.com> - 2.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Changes/f21tcl86
+
 * Thu May 15 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3-2
 - Rebuilt (f21-python)
 
-- 
cgit v0.10.2


From a0374180ff792eb0a2b41434d1a3a47efe340d3e Mon Sep 17 00:00:00 2001
From: Dennis Gilmore <dennis at ausil.us>
Date: Tue, 27 May 2014 16:16:43 -0500
Subject: valgrind is available everywhere except 31 bit s390


diff --git a/pypy.spec b/pypy.spec
index 096bd7d..6bdb671 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.3
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -191,7 +191,7 @@ BuildRequires:  bzip2-devel
 BuildRequires:  ncurses-devel
 BuildRequires:  expat-devel
 BuildRequires:  openssl-devel
-%ifarch %{ix86} x86_64 ppc ppc64 s390x
+%ifnarch s390
 BuildRequires:  valgrind-devel
 %endif
 
@@ -827,6 +827,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue May 27 2014 Dennis Gilmore <dennis at ausil.us> - 2.3-4
+- valgrind is available everywhere except 31 bit s390
+
 * Wed May 21 2014 Jaroslav Škarvada <jskarvad at redhat.com> - 2.3-3
 - Rebuilt for https://fedoraproject.org/wiki/Changes/f21tcl86
 
-- 
cgit v0.10.2


From 1972c9c31b94769515b1972a39a9d4efe493e6d6 Mon Sep 17 00:00:00 2001
From: Dennis Gilmore <dennis at ausil.us>
Date: Sat, 7 Jun 2014 13:12:20 -0500
Subject: - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild


diff --git a/pypy.spec b/pypy.spec
index 6bdb671..96e21d5 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.3
-Release:        4%{?dist}
+Release:        5%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -827,6 +827,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
 * Tue May 27 2014 Dennis Gilmore <dennis at ausil.us> - 2.3-4
 - valgrind is available everywhere except 31 bit s390
 
-- 
cgit v0.10.2


From edc736c1c58fc920291a8e672c906b76d6e87a31 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Sun, 8 Jun 2014 20:55:40 +0200
Subject: Update to 2.3.1


diff --git a/.gitignore b/.gitignore
index f59302b..1babd6b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@
 /pypy-2.2-src.tar.bz2
 /pypy-2.2.1-src.tar.bz2
 /pypy-2.3-src.tar.bz2
+/release-2.3.1.tar.bz2
diff --git a/pypy.spec b/pypy.spec
index 96e21d5..7c4106a 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
-Version:        2.3
-Release:        5%{?dist}
+Version:        2.3.1
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -130,7 +130,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0:	https://bitbucket.org/pypy/pypy/downloads/pypy-2.3-src.tar.bz2
+Source0: https://bitbucket.org/pypy/pypy/get/release-2.3.1.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -273,7 +273,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-pypy-394146e9bb67
+%setup -q -n pypy-pypy-32f35069a16d
 %patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
 %patch1 -p1
 %patch2 -p1
@@ -827,6 +827,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sun Jun 08 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3.1-1
+- Update to 2.3.1
+
 * Sat Jun 07 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3-5
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
 
diff --git a/sources b/sources
index 8f25b0c..b80a17c 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-c93a8e47f3b3109af2f66d2bd766eb97  pypy-2.3-src.tar.bz2
+e9d26e6ed2ca809a791d88137e90629b  release-2.3.1.tar.bz2
-- 
cgit v0.10.2


From 43ee7785260fd8f42b86e62be70de5bc361a34d7 Mon Sep 17 00:00:00 2001
From: Peter Robinson <pbrobinson at gmail.com>
Date: Mon, 7 Jul 2014 23:07:38 +0100
Subject: ARMv7 is supported for JIT, no prelink on aarch64/ppc64le


diff --git a/pypy.spec b/pypy.spec
index 7c4106a..8ab5959 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.3.1
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -78,20 +78,20 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 #
 # Unfortunately, the JIT support is only available on some architectures.
 #
-# pypy-1.4/pypy/jit/backend/detect_cpu.py:getcpuclassname currently supports the
+# rpython/jit/backend/detect_cpu.py:getcpuclassname currently supports the
 # following options:
 #  'i386', 'x86'
 #  'x86-without-sse2':
 #  'x86_64'
+#  'armv6', 'armv7' (versions 6 and 7, hard- and soft-float ABI)
 #  'cli'
 #  'llvm'
 #
 # We will only build with JIT support on those architectures, and build without
 # it on the other archs.  The resulting binary will typically be slower than
 # CPython for the latter case.
-#
-%ifarch %{ix86} x86_64
-# FIXME: is there a better way of expressing "intel" here?
+
+%ifarch %{ix86} x86_64 %{arm}
 %global with_jit 1
 %else
 %global with_jit 0
@@ -206,7 +206,10 @@ BuildRequires:  time
 BuildRequires:  perl
 %endif
 
+# No prelink on these arches
+%ifnarch aarch64 ppc64le
 BuildRequires:  /usr/bin/execstack
+%endif
 
 # For byte-compiling the JIT-viewing mode:
 %if %{with_emacs}
@@ -466,7 +469,9 @@ InstallPyPy() {
     #
     # I tried various approaches involving fixing the build, but the simplest
     # approach is to postprocess the ELF file:
+%ifnarch aarch64 ppc64le
     execstack --clear-execstack %{buildroot}/%{pypyprefix}/$ExeName
+%endif
 }
 
 mkdir -p %{buildroot}/%{_bindir}
@@ -827,6 +832,10 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Jul  7 2014 Peter Robinson <pbrobinson at fedoraproject.org> 2.3.1-2
+- ARMv7 is supported for JIT
+- no prelink on aarch64/ppc64le
+
 * Sun Jun 08 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3.1-1
 - Update to 2.3.1
 
-- 
cgit v0.10.2


From 7498717b84a98b28987846d94baf9177cf5b36ee Mon Sep 17 00:00:00 2001
From: Peter Robinson <pbrobinson at fedoraproject.org>
Date: Sun, 17 Aug 2014 20:41:57 +0000
Subject: - Rebuilt for
 https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild


diff --git a/pypy.spec b/pypy.spec
index 8ab5959..f811755 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.3.1
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -832,6 +832,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
 * Mon Jul  7 2014 Peter Robinson <pbrobinson at fedoraproject.org> 2.3.1-2
 - ARMv7 is supported for JIT
 - no prelink on aarch64/ppc64le
-- 
cgit v0.10.2


From 5efcdc8fe2e02fffb9ffce1004f3d25a8e86d593 Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Tue, 2 Sep 2014 09:57:46 +0200
Subject: Move devel subpackage requires so that it gets picked up by rpm

Up to this point it belonged to the description, so pypy-devel
did not require pypy.

diff --git a/pypy.spec b/pypy.spec
index f811755..6f90d89 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -250,11 +250,11 @@ Libraries required by the various PyPy implementations of Python.
 %package devel
 Group:    Development/Languages
 Summary:  Development tools for working with PyPy
+Requires: pypy = %{version}-%{release}
+
 %description devel
 Header files for building C extension modules against PyPy
 
-Requires: pypy = %{version}-%{release}
-
 
 %if 0%{with_stackless}
 %package stackless
-- 
cgit v0.10.2


From f7434bab3f45aaf75e2d6b05664c9fd78197c10a Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Tue, 2 Sep 2014 10:01:18 +0200
Subject: Bump spec


diff --git a/pypy.spec b/pypy.spec
index 6f90d89..daf5015 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
 Version:        2.3.1
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -832,6 +832,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Sep 02 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3.1-4
+- Move devel subpackage requires so that it gets picked up by rpm
+
 * Sun Aug 17 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3.1-3
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
 
-- 
cgit v0.10.2


From e76c4a29685bfaf725af1ae1991d5b1fb7b7701c Mon Sep 17 00:00:00 2001
From: Matej Stuchlik <mstuchli at redhat.com>
Date: Tue, 23 Sep 2014 12:20:25 +0200
Subject: Update to 2.4.0


diff --git a/.gitignore b/.gitignore
index 1babd6b..a61aa79 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@
 /pypy-2.2.1-src.tar.bz2
 /pypy-2.3-src.tar.bz2
 /release-2.3.1.tar.bz2
+/pypy-2.4.0-src.tar.bz2
diff --git a/pypy.spec b/pypy.spec
index daf5015..4a3e56c 100644
--- a/pypy.spec
+++ b/pypy.spec
@@ -1,6 +1,6 @@
 Name:           pypy
-Version:        2.3.1
-Release:        4%{?dist}
+Version:        2.4.0
+Release:        1%{?dist}
 Summary:        Python implementation with a Just-In-Time compiler
 
 Group:          Development/Languages
@@ -130,7 +130,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
 
 # Source and patches:
-Source0: https://bitbucket.org/pypy/pypy/get/release-2.3.1.tar.bz2
+Source0: https://bitbucket.org/pypy/pypy/downloads/pypy-2.4.0-src.tar.bz2
 
 # Supply various useful RPM macros for building python modules against pypy:
 #  __pypy, pypy_sitelib, pypy_sitearch
@@ -276,7 +276,7 @@ Build of PyPy with support for micro-threads for massive concurrency
 
 
 %prep
-%setup -q -n pypy-pypy-32f35069a16d
+%setup -q -n pypy-2.4.0-src
 %patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
 %patch1 -p1
 %patch2 -p1
@@ -295,6 +295,8 @@ for f in rpython/translator/goal/bpnn.py ; do
    chmod a-x $f
 done
 
+rm -rf lib-python/3
+
 
 %build
 
@@ -832,6 +834,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Wed Sep 10 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.4.0-1
+- Update to 2.4.0
+
 * Tue Sep 02 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3.1-4
 - Move devel subpackage requires so that it gets picked up by rpm
 
diff --git a/sources b/sources
index b80a17c..ab6b8f5 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-e9d26e6ed2ca809a791d88137e90629b  release-2.3.1.tar.bz2
+6a25a212e7c5121f1f3988c118d05695  pypy-2.4.0-src.tar.bz2
-- 
cgit v0.10.2


From 26c3863db65451cb67c67cd4e72a826698ef7bdf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Sat, 25 Apr 2015 00:48:59 +0200
Subject: Change pypy2 spec to pypy3


diff --git a/.gitignore b/.gitignore
index a61aa79..c9f3d9d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,14 +1 @@
-/pypy-1.4.1-src.tar.bz2
-/pypy-1.5-src.tar.bz2
-/release-1.6.tar.bz2
-/release-1.7.tar.bz2
-/release-1.8.tar.bz2
-/release-1.9.tar.bz2
-/release-2.0-beta-1.tar.bz2
-/release-2.0.2.tar.bz2
-/release-2.1.0.tar.bz2
-/pypy-2.2-src.tar.bz2
-/pypy-2.2.1-src.tar.bz2
-/pypy-2.3-src.tar.bz2
-/release-2.3.1.tar.bz2
-/pypy-2.4.0-src.tar.bz2
+/pypy3-2.4.0-src.tar.bz2
diff --git a/macros.pypy b/macros.pypy
deleted file mode 100644
index 5f40b6f..0000000
--- a/macros.pypy
+++ /dev/null
@@ -1,5 +0,0 @@
-%__pypy /usr/bin/pypy
-%pypy_sitelib %(%{__pypy} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")
-%pypy_sitearch %(%{__pypy} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")
-%pypy_version %(%{__pypy} -c "import sys; sys.stdout.write(sys.version[:3])")
-%pypydir %{_builddir}/pypy-%{name}-%{version}-%{release}
diff --git a/macros.pypy3 b/macros.pypy3
new file mode 100644
index 0000000..ef1f600
--- /dev/null
+++ b/macros.pypy3
@@ -0,0 +1,5 @@
+%__pypy3 /usr/bin/pypy3
+%pypy3_sitelib %(%{__pypy3} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")
+%pypy3_sitearch %(%{__pypy3} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")
+%pypy3_version %(%{__pypy3} -c "import sys; sys.stdout.write(sys.version[:3])")
+%pypy3dir %{_builddir}/pypy3-%{name}-%{version}-%{release}
diff --git a/pypy.spec b/pypy.spec
deleted file mode 100644
index 4a3e56c..0000000
--- a/pypy.spec
+++ /dev/null
@@ -1,1067 +0,0 @@
-Name:           pypy
-Version:        2.4.0
-Release:        1%{?dist}
-Summary:        Python implementation with a Just-In-Time compiler
-
-Group:          Development/Languages
-# LGPL and another free license we'd need to ask spot about are present in some
-# java jars that we're not building with atm (in fact, we're deleting them
-# before building).  If we restore those we'll have to work out the new
-# licensing terms
-License:        MIT and Python and UCD
-URL:            http://pypy.org/
-BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-
-# High-level configuration of the build:
-
-# PyPy consists of an implementation of an interpreter (with JIT compilation)
-# for the full Python language  written in a high-level language, leaving many
-# of the implementation details as "pluggable" policies.
-#
-# The implementation language is then compiled down to .c code, from which we
-# obtain a binary.
-#
-# This allows us to build a near-arbitrary collection of different
-# implementations of Python with differing tradeoffs
-#
-# (As it happens, the implementation language is itself Python, albeit a
-# restricted subset "RPython", chosen to making it amenable to being compiled.
-# The result implements the full Python language though)
-
-# We could build many different implementations of Python.
-# For now, let's focus on the implementation that appears to be receiving the
-# most attention upstream: the JIT-enabled build, with all standard
-# optimizations
-
-# Building a configuration can take significant time:
-
-# A build of pypy (with jit) on i686 took 77 mins:
-#  [Timer] Timings:
-#  [Timer] annotate                       ---  583.3 s
-#  [Timer] rtype_lltype                   ---  760.9 s
-#  [Timer] pyjitpl_lltype                 ---  567.3 s
-#  [Timer] backendopt_lltype              ---  375.6 s
-#  [Timer] stackcheckinsertion_lltype     ---   54.1 s
-#  [Timer] database_c                     ---  852.2 s
-#  [Timer] source_c                       --- 1007.3 s
-#  [Timer] compile_c                      ---  419.9 s
-#  [Timer] ===========================================
-#  [Timer] Total:                         --- 4620.5 s
-#
-# A build of pypy (nojit) on x86_64 took about an hour:
-#  [Timer] Timings:
-#  [Timer] annotate                       ---  537.5 s
-#  [Timer] rtype_lltype                   ---  667.3 s
-#  [Timer] backendopt_lltype              ---  385.4 s
-#  [Timer] stackcheckinsertion_lltype     ---   42.5 s
-#  [Timer] database_c                     ---  625.3 s
-#  [Timer] source_c                       --- 1040.2 s
-#  [Timer] compile_c                      ---  273.9 s
-#  [Timer] ===========================================
-#  [Timer] Total:                         --- 3572.0 s
-#
-#
-# A build of pypy-stackless on i686 took about 87 mins:
-#  [Timer] Timings:
-#  [Timer] annotate                       ---  584.2 s
-#  [Timer] rtype_lltype                   ---  777.3 s
-#  [Timer] backendopt_lltype              ---  365.9 s
-#  [Timer] stackcheckinsertion_lltype     ---   39.3 s
-#  [Timer] database_c                     --- 1089.6 s
-#  [Timer] source_c                       --- 1868.6 s
-#  [Timer] compile_c                      ---  490.4 s
-#  [Timer] ===========================================
-#  [Timer] Total:                         --- 5215.3 s
-
-
-# We will build a "pypy" binary.
-#
-# Unfortunately, the JIT support is only available on some architectures.
-#
-# rpython/jit/backend/detect_cpu.py:getcpuclassname currently supports the
-# following options:
-#  'i386', 'x86'
-#  'x86-without-sse2':
-#  'x86_64'
-#  'armv6', 'armv7' (versions 6 and 7, hard- and soft-float ABI)
-#  'cli'
-#  'llvm'
-#
-# We will only build with JIT support on those architectures, and build without
-# it on the other archs.  The resulting binary will typically be slower than
-# CPython for the latter case.
-
-%ifarch %{ix86} x86_64 %{arm}
-%global with_jit 1
-%else
-%global with_jit 0
-%endif
-
-# Should we build a "pypy-stackless" binary?
-%global with_stackless 0
-
-# Should we build the emacs JIT-viewing mode?
-%if 0%{?rhel} == 5 || 0%{?rhel} == 6
-%global with_emacs 0
-%else
-%global with_emacs 1
-%endif
-
-# Easy way to enable/disable verbose logging:
-%global verbose_logs 0
-
-# Forcibly use the shadow-stack option for detecting GC roots, rather than
-# relying on hacking up generated assembler with regexps:
-%global shadow_stack 1
-
-# Easy way to turn off the selftests:
-%global run_selftests 1
-
-%global pypyprefix %{_libdir}/pypy-%{version}
-%global pylibver 2.7
-
-# We refer to this subdir of the source tree in a few places during the build:
-%global goal_dir pypy/goal
-
-
-# Turn off the brp-python-bytecompile postprocessing script
-# We manually invoke it later on, using the freshly built pypy binary
-%global __os_install_post \
-  %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
-
-# Source and patches:
-Source0: https://bitbucket.org/pypy/pypy/downloads/pypy-2.4.0-src.tar.bz2
-
-# Supply various useful RPM macros for building python modules against pypy:
-#  __pypy, pypy_sitelib, pypy_sitearch
-Source2: macros.pypy
-
-# By default, if built at a tty, the translation process renders a Mandelbrot
-# set to indicate progress.
-# This obscures useful messages, and may waste CPU cycles, so suppress it, and
-# merely render dots:
-Patch0: pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
-
-# Patch pypy.translator.platform so that stdout from "make" etc gets logged,
-# rather than just stderr, so that the command-line invocations of the compiler
-# and linker are captured:
-Patch1: 006-always-log-stdout.patch
-
-# Disable the printing of a quote from IRC on startup (these are stored in
-# ROT13 form in lib_pypy/_pypy_irc_topic.py).  Some are cute, but some could
-# cause confusion for end-users (and many are in-jokes within the PyPy
-# community that won't make sense outside of it).  [Sorry to be a killjoy]
-Patch2: 007-remove-startup-message.patch
-
-
-# Build-time requirements:
-
-# pypy's can be rebuilt using itself, rather than with CPython; doing so
-# halves the build time.
-#
-# Turn it off with this boolean, to revert back to rebuilding using CPython
-# and avoid a cycle in the build-time dependency graph:
-
-%global use_self_when_building 0
-%if 0%{use_self_when_building}
-BuildRequires: pypy
-%global bootstrap_python_interp pypy
-%else
-
-# Python 2.6 or later is needed, so on RHEL5 (2.4) we need to use the alternate
-# python26 rpm:
-%if 0%{?rhel} == 5
-BuildRequires: python26-devel
-%global bootstrap_python_interp python26
-%else
-BuildRequires: python-devel
-%global bootstrap_python_interp python
-%endif
-
-%endif
-
-BuildRequires:  libffi-devel
-BuildRequires:  tcl-devel
-BuildRequires:  tk-devel
-
-BuildRequires:  sqlite-devel
-
-BuildRequires:  zlib-devel
-BuildRequires:  bzip2-devel
-BuildRequires:  ncurses-devel
-BuildRequires:  expat-devel
-BuildRequires:  openssl-devel
-%ifnarch s390
-BuildRequires:  valgrind-devel
-%endif
-
-%if %{run_selftests}
-# Used by the selftests, though not by the build:
-BuildRequires:  gc-devel
-
-# For use in the selftests, for recording stats:
-BuildRequires:  time
-
-# For use in the selftests, for imposing a per-test timeout:
-BuildRequires:  perl
-%endif
-
-# No prelink on these arches
-%ifnarch aarch64 ppc64le
-BuildRequires:  /usr/bin/execstack
-%endif
-
-# For byte-compiling the JIT-viewing mode:
-%if %{with_emacs}
-BuildRequires:  emacs
-%endif
-
-
-# Metadata for the core package (the JIT build):
-Requires: pypy-libs = %{version}-%{release}
-
-%description
-PyPy's implementation of Python, featuring a Just-In-Time compiler on some CPU
-architectures, and various optimized implementations of the standard types
-(strings, dictionaries, etc)
-
-%if 0%{with_jit}
-This build of PyPy has JIT-compilation enabled.
-%else
-This build of PyPy has JIT-compilation disabled, as it is not supported on this
-CPU architecture.
-%endif
-
-
-%package libs
-Group:    Development/Languages
-Summary:  Run-time libraries used by PyPy implementations of Python
-
-# We supply an emacs mode for the JIT viewer.
-# (This doesn't bring in all of emacs, just the directory structure)
-%if %{with_emacs}
-Requires: emacs-filesystem >= %{_emacs_version}
-%endif
-
-%description libs
-Libraries required by the various PyPy implementations of Python.
-
-
-%package devel
-Group:    Development/Languages
-Summary:  Development tools for working with PyPy
-Requires: pypy = %{version}-%{release}
-
-%description devel
-Header files for building C extension modules against PyPy
-
-
-%if 0%{with_stackless}
-%package stackless
-Group:    Development/Languages
-Summary:  Stackless Python interpreter built using PyPy
-Requires: pypy-libs = %{version}-%{release}
-%description stackless
-Build of PyPy with support for micro-threads for massive concurrency
-%endif
-
-%if 0%{with_stackless}
-%package stackless
-Group:    Development/Languages
-Summary:  Stackless Python interpreter built using PyPy
-Requires: pypy-libs = %{version}-%{release}
-%description stackless
-Build of PyPy with support for micro-threads for massive concurrency
-%endif
-
-
-%prep
-%setup -q -n pypy-2.4.0-src
-%patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
-%patch1 -p1
-%patch2 -p1
-
-# Replace /usr/local/bin/python shebangs with /usr/bin/python:
-find -name "*.py" -exec \
-  sed \
-    -i -e "s|/usr/local/bin/python|/usr/bin/python|" \
-    "{}" \
-    \;
-
-for f in rpython/translator/goal/bpnn.py ; do
-   # Detect shebang lines && remove them:
-   sed -e '/^#!/Q 0' -e 'Q 1' $f \
-      && sed -i '1d' $f
-   chmod a-x $f
-done
-
-rm -rf lib-python/3
-
-
-%build
-
-BuildPyPy() {
-  ExeName=$1
-  Options=$2
-
-  echo "--------------------------------------------------------------"
-  echo "--------------------------------------------------------------"
-  echo "--------------------------------------------------------------"
-  echo "STARTING BUILD OF: $ExeName"
-  echo "--------------------------------------------------------------"
-  echo "--------------------------------------------------------------"
-  echo "--------------------------------------------------------------"
-
-  pushd %{goal_dir}
-
-  # The build involves invoking a python script, passing in particular
-  # arguments, environment variables, etc.
-  # Some notes on those follow:
-
-  # The generated binary embeds copies of the values of all environment
-  # variables.  We need to unset "RPM_BUILD_ROOT" to avoid a fatal error from
-  #  /usr/lib/rpm/check-buildroot
-  # during the postprocessing of the rpmbuild, complaining about this
-  # reference to the buildroot
-
-
-  # By default, pypy's autogenerated C code is placed in
-  #    /tmp/usession-N
-  #  
-  # and it appears that this stops rpm from extracting the source code to the
-  # debuginfo package
-  #
-  # The logic in pypy-1.4/pypy/tool/udir.py indicates that it is generated in:
-  #    $PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-N    
-  # and so we set PYPY_USESSION_DIR so that this tempdir is within the build
-  # location, and set $PYPY_USESSION_BASENAME so that the tempdir is unique
-  # for each invocation of BuildPyPy
-
-  # Compilation flags for C code:
-  #   pypy-1.4/pypy/translator/c/genc.py:gen_makefile
-  # assembles a Makefile within
-  #   THE_UDIR/testing_1/Makefile
-  # calling out to platform.gen_makefile
-  # For us, that's
-  #   pypy-1.4/pypy/translator/platform/linux.py: class BaseLinux(BasePosix):
-  # which by default has:
-  #   CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
-  #             '-Wall', '-Wno-unused']
-  # plus all substrings from CFLAGS in the environment.
-  # This is used to generate a value for CFLAGS that's written into the Makefile
-
-  # How will we track garbage-collection roots in the generated code?
-  #   http://pypy.readthedocs.org/en/latest/config/translation.gcrootfinder.html
-
-%if 0%{shadow_stack}
-  # This is the most portable option, and avoids a reliance on non-guaranteed
-  # behaviors within GCC's code generator: use an explicitly-maintained stack
-  # of root pointers:
-  %define gcrootfinder_options --gcrootfinder=shadowstack
-
-  export CFLAGS=$(echo "$RPM_OPT_FLAGS")
-
-%else
-  # Go with the default, which is "asmgcc"
-
-  %define gcrootfinder_options %{nil}
-
-  # https://bugzilla.redhat.com/show_bug.cgi?id=588941#c18
-  # The generated Makefile compiles the .c files into assembler (.s), rather
-  # than direct to .o  It then post-processes this assembler to locate
-  # garbage-collection roots (building .lbl.s and .gcmap files, and a
-  # "gcmaptable.s").  (The modified .lbl.s files have extra code injected
-  # within them).
-  # Unfortunately, the code to do this:
-  #   pypy-1.4/pypy/translator/c/gcc/trackgcroot.py
-  # doesn't interract well with the results of using our standard build flags.
-  # For now, filter our CFLAGS of everything that could be conflicting with
-  # pypy.  Need to check these and reenable ones that are okay later.
-  # Filed as https://bugzilla.redhat.com/show_bug.cgi?id=666966
-  export CFLAGS=$(echo "$RPM_OPT_FLAGS" | sed -e 's/-Wp,-D_FORTIFY_SOURCE=2//' -e 's/-fexceptions//' -e 's/-fstack-protector//' -e 's/--param=ssp-buffer-size=4//' -e 's/-O2//' -e 's/-fasynchronous-unwind-tables//' -e 's/-march=i686//' -e 's/-mtune=atom//')
-
-%endif
-
-  # The generated C code leads to many thousands of warnings of the form:
-  #   warning: variable 'l_v26003' set but not used [-Wunused-but-set-variable]
-  # Suppress them:
-  export CFLAGS=$(echo "$CFLAGS" -Wno-unused -fPIC)
-
-  # If we're already built the JIT-enabled "pypy", then use it for subsequent
-  # builds (of other configurations):
-  if test -x './pypy' ; then
-    INTERP='./pypy'
-  else
-    # First pypy build within this rpm build?
-    # Fall back to using the bootstrap python interpreter, which might be a
-    # system copy of pypy from an earlier rpm, or be cpython's /usr/bin/python:
-    INTERP='%{bootstrap_python_interp}'
-  fi
-
-  # Here's where we actually invoke the build:
-  time \
-    RPM_BUILD_ROOT= \
-    PYPY_USESSION_DIR=$(pwd) \
-    PYPY_USESSION_BASENAME=$ExeName \
-    $INTERP ../../rpython/bin/rpython  \
-    --output=$ExeName \
-    %{gcrootfinder_options} \
-    $Options \
-    targetpypystandalone
-
-  echo "--------------------------------------------------------------"
-  echo "--------------------------------------------------------------"
-  echo "--------------------------------------------------------------"
-  echo "FINISHED BUILDING: $ExeName"
-  echo "--------------------------------------------------------------"
-  echo "--------------------------------------------------------------"
-  echo "--------------------------------------------------------------"
-
-  popd
-}
-
-BuildPyPy \
-  pypy \
-%if 0%{with_jit}
-  "-Ojit" \
-%else
-  "-O2" \
-%endif
-  %{nil}
-
-%if 0%{with_stackless}
-BuildPyPy \
-  pypy-stackless \
-   "--stackless"
-%endif
-
-%if %{with_emacs}
-%{_emacs_bytecompile} rpython/jit/tool/pypytrace-mode.el
-%endif
-
-
-%install
-rm -rf $RPM_BUILD_ROOT
-
-# Install the various executables:
-
-InstallPyPy() {
-    ExeName=$1
-
-    # To ensure compatibility with virtualenv, pypy finds its libraries
-    # relative to itself; this happens within
-    #    pypy/translator/goal/app_main.py:get_library_path
-    # which calls sys.pypy_initial_path(dirname) on the dir containing
-    # the executable, with symlinks resolved.
-    #
-    # Hence we make /usr/bin/pypy be a symlink to the real binary, which we
-    # place within /usr/lib[64]/pypy-1.* as pypy
-    #
-    # This ought to enable our pypy build to work with virtualenv
-    # (rhbz#742641)
-    install -m 755 %{goal_dir}/$ExeName %{buildroot}/%{pypyprefix}/$ExeName
-    ln -s %{pypyprefix}/$ExeName %{buildroot}/%{_bindir}
-
-    # The generated machine code doesn't need an executable stack,  but
-    # one of the assembler files (gcmaptable.s) doesn't have the necessary
-    # metadata to inform gcc of that, and thus gcc pessimistically assumes
-    # that the built binary does need an executable stack.
-    #
-    # Reported upstream as: https://codespeak.net/issue/pypy-dev/issue610
-    #
-    # I tried various approaches involving fixing the build, but the simplest
-    # approach is to postprocess the ELF file:
-%ifnarch aarch64 ppc64le
-    execstack --clear-execstack %{buildroot}/%{pypyprefix}/$ExeName
-%endif
-}
-
-mkdir -p %{buildroot}/%{_bindir}
-mkdir -p %{buildroot}/%{pypyprefix}
-
-InstallPyPy pypy
-
-%if 0%{with_stackless}
-InstallPyPy pypy-stackless
-%endif
-
-
-# Install the various support libraries as described at:
-#   http://codespeak.net/pypy/dist/pypy/doc/getting-started-python.html#installation
-# which refers to a "PREFIX" found relative to the location of the binary.
-# Given that the pypy binaries will be in /usr/bin, PREFIX can be
-# "../share/pypy-1.2" relative to that directory, i.e. /usr/share/pypy-1.2
-# 
-# Running "strace" on a built binary indicates that it searches within
-#   PREFIX/lib-python/modified-2.5.2
-# not
-#   PREFIX/lib-python/modified.2.5.2
-# as given on the above page, i.e. it uses '-' not '.'
-
-cp -a lib-python %{buildroot}/%{pypyprefix}
-
-cp -a lib_pypy %{buildroot}/%{pypyprefix}
-
-# Remove a text file that documents which selftests fail on Win32:
-rm %{buildroot}/%{pypyprefix}/lib-python/win32-failures.txt
-
-# Remove a text file containing upstream's recipe for syncing stdlib in
-# their hg repository with cpython's:
-rm %{buildroot}/%{pypyprefix}/lib-python/stdlib-upgrade.txt
-
-# Remove shebang lines from .py files that aren't executable, and
-# remove executability from .py files that don't have a shebang line:
-find \
-  %{buildroot}                                                           \
-  -name "*.py"                                                           \
-    \(                                                                   \
-       \( \! -perm /u+x,g+x,o+x -exec sed -e '/^#!/Q 0' -e 'Q 1' {} \;   \
-             -print -exec sed -i '1d' {} \;                              \
-          \)                                                             \
-       -o                                                                \
-       \(                                                                \
-             -perm /u+x,g+x,o+x ! -exec grep -m 1 -q '^#!' {} \;         \
-             -exec chmod a-x {} \;                                       \
-        \)                                                               \
-    \)
-
-mkdir -p %{buildroot}/%{pypyprefix}/site-packages
-
-
-# pypy uses .pyc files by default (--objspace-usepycfiles), but has a slightly
-# different bytecode format to CPython.  It doesn't use .pyo files: the -O flag
-# is treated as a "dummy optimization flag for compatibility with C Python"
-#
-# pypy-1.4/pypy/module/imp/importing.py has this comment:
-    # XXX picking a magic number is a mess.  So far it works because we
-    # have only two extra opcodes, which bump the magic number by +1 and
-    # +2 respectively, and CPython leaves a gap of 10 when it increases
-    # its own magic number.  To avoid assigning exactly the same numbers
-    # as CPython we always add a +2.  We'll have to think again when we
-    # get at the fourth new opcode :-(
-    #
-    #  * CALL_LIKELY_BUILTIN    +1
-    #  * CALL_METHOD            +2
-    #
-    # In other words:
-    #
-    #     default_magic        -- used by CPython without the -U option
-    #     default_magic + 1    -- used by CPython with the -U option
-    #     default_magic + 2    -- used by PyPy without any extra opcode
-    #     ...
-    #     default_magic + 5    -- used by PyPy with both extra opcodes
-#
-
-# pypy-1.4/pypy/interpreter/pycode.py has:
-#
-#  default_magic = (62141+2) | 0x0a0d0000                  # this PyPy's magic
-#                                                          # (62131=CPython 2.5.1)
-# giving a value for "default_magic" for PyPy of 0xa0df2bf.
-# Note that this corresponds to the "default_magic + 2" from the comment above
-
-# In my builds:
-#   $ ./pypy --info | grep objspace.opcodes
-#                objspace.opcodes.CALL_LIKELY_BUILTIN: False
-#                        objspace.opcodes.CALL_METHOD: True
-# so I'd expect the magic number to be:
-#    0x0a0df2bf + 2 (the flag for CALL_METHOD)
-# giving
-#    0x0a0df2c1
-#
-# I'm seeing
-#   c1 f2 0d 0a
-# as the first four bytes of the .pyc files, which is consistent with this.
-
-
-# Bytecompile all of the .py files we ship, using our pypy binary, giving us
-# .pyc files for pypy.  The script actually does the work twice (passing in -O
-# the second time) but it's simplest to reuse that script.
-#
-# The script has special-casing for .py files below
-#    /usr/lib{64}/python[0-9].[0-9]
-# but given that we're installing into a different path, the supplied "default"
-# implementation gets used instead.
-#
-# Note that some of the test files deliberately contain syntax errors, so
-# we pass 0 for the second argument ("errors_terminate"):
-/usr/lib/rpm/brp-python-bytecompile \
-  %{buildroot}/%{_bindir}/pypy \
-  0
-
-%{buildroot}/%{pypyprefix}/pypy -c 'import _tkinter'
-%{buildroot}/%{pypyprefix}/pypy -c 'import Tkinter'
-%{buildroot}/%{pypyprefix}/pypy -c 'import _sqlite3'
-%{buildroot}/%{pypyprefix}/pypy -c 'import _curses'
-%{buildroot}/%{pypyprefix}/pypy -c 'import curses'
-%{buildroot}/%{pypyprefix}/pypy -c 'import syslog'
-%{buildroot}/%{pypyprefix}/pypy -c 'from _sqlite3 import *'
-
-# Header files for C extension modules.
-# Upstream's packaging process (pypy/tool/release/package.py)
-# creates an "include" subdir and copies all *.h/*.inl from "include" there
-# (it also has an apparently out-of-date comment about copying them from
-# pypy/_interfaces, but this directory doesn't seem to exist, and it doesn't
-# seem to do this as of 2011-01-13)
-
-# FIXME: arguably these should be instead put into a subdir below /usr/include,
-# it's not yet clear to me how upstream plan to deal with the C extension
-# interface going forward, so let's just mimic upstream for now.
-%global pypy_include_dir  %{pypyprefix}/include
-mkdir -p %{buildroot}/%{pypy_include_dir}
-cp include/*.h %{buildroot}/%{pypy_include_dir}
-
-
-# Capture the RPython source code files from the build within the debuginfo
-# package (rhbz#666975)
-%global pypy_debuginfo_dir /usr/src/debug/pypy-%{version}-src
-mkdir -p %{buildroot}%{pypy_debuginfo_dir}
-
-# copy over everything:
-cp -a pypy %{buildroot}%{pypy_debuginfo_dir}
-
-# ...then delete files that aren't:
-#   - *.py files
-#   - the Makefile
-#   - typeids.txt
-#   - dynamic-symbols-*
-find \
-  %{buildroot}%{pypy_debuginfo_dir}  \
-  \( -type f                         \
-     -a                              \
-     \! \( -name "*.py"              \
-           -o                        \
-           -name "Makefile"          \
-           -o                        \
-           -name "typeids.txt"       \
-           -o                        \
-           -name "dynamic-symbols-*" \
-        \)                           \
-  \)                                 \
-  -delete
-
-# Alternatively, we could simply keep everything.  This leads to a ~350MB
-# debuginfo package, but it makes it easy to hack on the Makefile and C build
-# flags by rebuilding/linking the sources.
-# To do so, remove the above "find" command.
-
-# We don't need bytecode for these files; they are being included for reference
-# purposes.
-# There are some rpmlint warnings from these files:
-#   non-executable-script
-#   wrong-script-interpreter
-#   zero-length
-#   script-without-shebang
-#   dangling-symlink
-# but given that the objective is to preserve a copy of the source code, those
-# are acceptable.
-
-# Install the JIT trace mode for Emacs:
-%if %{with_emacs}
-mkdir -p %{buildroot}/%{_emacs_sitelispdir}
-cp -a rpython/jit/tool/pypytrace-mode.el* %{buildroot}/%{_emacs_sitelispdir}
-%endif
-
-# Install macros for rpm:
-mkdir -p %{buildroot}/%{_rpmconfigdir}/macros.d
-install -m 644 %{SOURCE2} %{buildroot}/%{_rpmconfigdir}/macros.d
-
-%check
-topdir=$(pwd)
-
-SkipTest() {
-    TEST_NAME=$1
-    sed -i -e"s|^$TEST_NAME$||g" testnames.txt
-}
-
-CheckPyPy() {
-    # We'll be exercising one of the freshly-built binaries using the
-    # test suite from the standard library (overridden in places by pypy's
-    # modified version)
-    ExeName=$1
-
-    echo "--------------------------------------------------------------"
-    echo "--------------------------------------------------------------"
-    echo "--------------------------------------------------------------"
-    echo "STARTING TEST OF: $ExeName"
-    echo "--------------------------------------------------------------"
-    echo "--------------------------------------------------------------"
-    echo "--------------------------------------------------------------"
-
-    pushd %{goal_dir}
-
-    # I'm seeing numerous cases where tests seem to hang, or fail unpredictably
-    # So we'll run each test in its own process, with a timeout
-
-    # Use regrtest to explicitly list all tests:
-    ( ./$ExeName -c \
-         "from test.regrtest import findtests; print '\n'.join(findtests())"
-    ) > testnames.txt
-
-    # Skip some tests:
-      # "audioop" doesn't exist for pypy yet:
-      SkipTest test_audioop
-
-      # The gdb CPython hooks haven't been ported to cpyext:
-      SkipTest test_gdb
-
-      # hotshot relies heavily on _hotshot, which doesn't exist:
-      SkipTest test_hotshot
-
-      # "strop" module doesn't exist for pypy yet:
-      SkipTest test_strop
-
-      # I'm seeing Koji builds hanging e.g.:
-      #   http://koji.fedoraproject.org/koji/getfile?taskID=3386821&name=build.log
-      # The only test that seems to have timed out in that log is
-      # test_multiprocessing, so skip it for now:
-      SkipTest test_multiprocessing
-
-    echo "== Test names =="
-    cat testnames.txt
-    echo "================="
-
-    echo "" > failed-tests.txt
-
-    for TestName in $(cat testnames.txt) ; do
-
-        echo "===================" $TestName "===================="
-
-        # Use /usr/bin/time (rather than the shell "time" builtin) to gather
-        # info on the process (time/CPU/memory).  This passes on the exit
-        # status of the underlying command
-        #
-        # Use perl's alarm command to impose a timeout
-        #   900 seconds is 15 minutes per test.
-        # If a test hangs, that test should get terminated, allowing the build
-        # to continue.
-        #
-        # Invoke pypy on test.regrtest to run the specific test suite
-        # verbosely
-        #
-        # For now, || true, so that any failures don't halt the build:
-        ( /usr/bin/time \
-           perl -e 'alarm shift @ARGV; exec @ARGV' 900 \
-             ./$ExeName -m test.regrtest -v $TestName ) \
-        || (echo $TestName >> failed-tests.txt) \
-        || true
-    done
-
-    echo "== Failed tests =="
-    cat failed-tests.txt
-    echo "================="
-
-    popd
-
-    # Doublecheck pypy's own test suite, using the built pypy binary:
-
-    # Disabled for now:
-    #   x86_64 shows various failures inside:
-    #     jit/backend/x86/test
-    #   followed by a segfault inside
-    #     jit/backend/x86/test/test_runner.py
-    #
-    #   i686 shows various failures inside:
-    #     jit/backend/x86/test
-    #   with the x86_64 failure leading to cancellation of the i686 build
-
-    # Here's the disabled code:
-    #    pushd pypy
-    #    time translator/goal/$ExeName test_all.py
-    #    popd
-
-    echo "--------------------------------------------------------------"
-    echo "--------------------------------------------------------------"
-    echo "--------------------------------------------------------------"
-    echo "FINISHED TESTING: $ExeName"
-    echo "--------------------------------------------------------------"
-    echo "--------------------------------------------------------------"
-    echo "--------------------------------------------------------------"
-}
-
-#python testrunner/runner.py --logfile=pytest-A.log --config=pypy/pytest-A.cfg --config=pypy/pytest-A.py --root=pypy --timeout=3600
-#python pypy/test_all.py --pypy=pypy/goal/pypy --timeout=3600 --resultlog=cpython.log lib-python
-#python pypy/test_all.py --pypy=pypy/goal/pypy --resultlog=pypyjit.log pypy/module/pypyjit/test
-#pypy/goal/pypy pypy/test_all.py --resultlog=pypyjit_new.log
-
-%if %{run_selftests}
-CheckPyPy pypy
-
-%if 0%{with_stackless}
-CheckPyPy pypy-stackless
-%endif
-
-%endif # run_selftests
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
-%files libs
-%defattr(-,root,root,-)
-%doc LICENSE README.rst
-
-%dir %{pypyprefix}
-%dir %{pypyprefix}/lib-python
-%{pypyprefix}/lib-python/stdlib-version.txt
-%{pypyprefix}/lib-python/%{pylibver}/
-%{pypyprefix}/lib-python/conftest.py*
-%{pypyprefix}/lib_pypy/
-%{pypyprefix}/site-packages/
-%if %{with_emacs}
-%{_emacs_sitelispdir}/pypytrace-mode.el
-%{_emacs_sitelispdir}/pypytrace-mode.elc
-%endif
-
-%files
-%defattr(-,root,root,-)
-%doc LICENSE README.rst
-%{_bindir}/pypy
-%{pypyprefix}/pypy
-
-%files devel
-%defattr(-,root,root,-)
-%dir %{pypy_include_dir}
-%{pypy_include_dir}/*.h
-%config(noreplace) %{_rpmconfigdir}/macros.d/macros.pypy
-
-%if 0%{with_stackless}
-%files stackless
-%defattr(-,root,root,-)
-%doc LICENSE README.rst
-%{_bindir}/pypy-stackless
-%endif
-
-
-%changelog
-* Wed Sep 10 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.4.0-1
-- Update to 2.4.0
-
-* Tue Sep 02 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3.1-4
-- Move devel subpackage requires so that it gets picked up by rpm
-
-* Sun Aug 17 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3.1-3
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
-
-* Mon Jul  7 2014 Peter Robinson <pbrobinson at fedoraproject.org> 2.3.1-2
-- ARMv7 is supported for JIT
-- no prelink on aarch64/ppc64le
-
-* Sun Jun 08 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3.1-1
-- Update to 2.3.1
-
-* Sat Jun 07 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3-5
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
-
-* Tue May 27 2014 Dennis Gilmore <dennis at ausil.us> - 2.3-4
-- valgrind is available everywhere except 31 bit s390
-
-* Wed May 21 2014 Jaroslav Škarvada <jskarvad at redhat.com> - 2.3-3
-- Rebuilt for https://fedoraproject.org/wiki/Changes/f21tcl86
-
-* Thu May 15 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3-2
-- Rebuilt (f21-python)
-
-* Tue May 13 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3-1
-- Updated to 2.3
-
-* Mon Mar 10 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-3
-- Put RPM macros in proper location
-
-* Thu Jan 16 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-2
-- Fixed errors due to missing __pycache__
-
-* Thu Dec 05 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-1
-- Updated to 2.2.1
-- Several bundled modules (tkinter, sqlite3, curses, syslog) were
-  not bytecompiled properly during build, that is now fixed
-- prepared new tests, not enabled yet
-
-* Thu Nov 14 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.2.0-1
-- Updated to 2.2.0
-
-* Thu Aug 15 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.1-1
-- Updated to 2.1.0
-
-* Sun Aug 04 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0.2-5
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
-
-* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-4
-- Patch1 fix
-
-* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-3
-- Yet another Sources fix
-
-* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-2
-- Fixed Source URL
-
-* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-1
-- 2.0.2, patch 8 does not seem necessary anymore
-
-* Thu Feb 14 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0-0.2.b1
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
-
-* Tue Dec 11 2012 David Malcolm <dmalcolm at redhat.com> - 2.0-0.1.b1
-- 2.0b1 (drop upstreamed patch 9)
-
-* Sat Jul 21 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.9-4
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
-
-* Tue Jul 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-3
-- log all output from "make" (patch 6)
-- disable the MOTD at startup (patch 7)
-- hide symbols from the dynamic linker (patch 8)
-- add PyInt_AsUnsignedLongLongMask (patch 9)
-- capture the Makefile, the typeids.txt, and the dynamic-symbols file within
-the debuginfo package
-
-* Mon Jun 18 2012 Peter Robinson <pbrobinson at fedoraproject.org> - 1.9-2
-- Compile with PIC, fixes FTBFS on ARM
-
-* Fri Jun  8 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-1
-- 1.9
-
-* Fri Feb 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.8-2
-- disable C readability patch for now (patch 4)
-
-* Thu Feb  9 2012 David Malcolm <dmalcolm at redhat.com> - 1.8-1
-- 1.8; regenerate config patch (patch 0); drop selinux patch (patch 2);
-regenerate patch 5
-
-* Tue Jan 31 2012 David Malcolm <dmalcolm at redhat.com> - 1.7-4
-- fix an incompatibility with virtualenv (rhbz#742641)
-
-* Sat Jan 14 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.7-3
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
-
-* Fri Dec 16 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-2
-- use --gcrootfinder=shadowstack, and use standard Fedora compilation flags,
-with -Wno-unused (rhbz#666966 and rhbz#707707)
-
-* Mon Nov 21 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-1
-- 1.7: refresh patch 0 (configuration) and patch 4 (readability of generated
-code)
-
-* Tue Oct  4 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-7
-- skip test_multiprocessing
-
-* Tue Sep 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-6
-- don't ship the emacs JIT-viewer on el5 and el6 (missing emacs-filesystem;
-missing _emacs_bytecompile macro on el5)
-
-* Mon Sep 12 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-5
-- build using python26 on el5 (2.4 is too early)
-* Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-4
-- fix SkipTest function to avoid corrupting the name of "test_gdbm"
-
-* Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-3
-- add rpm macros file to the devel subpackage (source 2)
-- skip some tests that can't pass yet
-
-* Sat Aug 20 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-2
-- work around test_subprocess failure seen in koji (patch 5)
-
-* Thu Aug 18 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-1
-- 1.6
-- rewrite the %%check section, introducing per-test timeouts
-
-* Tue Aug  2 2011 David Malcolm <dmalcolm at redhat.com> - 1.5-2
-- add pypytrace-mode.el to the pypy-libs subpackage, for viewing JIT trace
-logs in emacs
-
-* Mon May  2 2011 David Malcolm <dmalcolm at redhat.com> - 1.5-1
-- 1.5
-
-* Wed Apr 20 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-10
-- build a /usr/bin/pypy (but without the JIT compiler) on architectures that
-don't support the JIT, so that they do at least have something that runs
-
-* Tue Feb 08 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.4.1-9
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
-
-* Fri Jan 14 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-8
-- disable self-hosting for now, due to fatal error seen JIT-compiling the
-translator
-
-* Fri Jan 14 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-7
-- skip test_ioctl for now
-
-* Thu Jan 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-6
-- add a "pypy-devel" subpackage, and install the header files there
-- in %%check, re-run failed tests in verbose mode
-
-* Fri Jan  7 2011 Dan Horák <dan[at]danny.cz> - 1.4.1-5
-- valgrind available only on selected architectures
-
-* Wed Jan  5 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-4
-- rebuild pypy using itself, for speed, with a boolean to break this cycle in
-the build-requirement graph (falling back to using "python-devel" aka CPython)
-- add work-in-progress patch to try to make generated c more readable
-(rhbz#666963)
-- capture the RPython source code files from the build within the debuginfo
-package (rhbz#666975)
-
-* Wed Dec 22 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-3
-- try to respect the FHS by installing libraries below libdir, rather than
-datadir; patch app_main.py to look in this installation location first when
-scanning for the pypy library directories.
-- clarifications and corrections to the comments in the specfile
-
-* Wed Dec 22 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-2
-- remove .svn directories
-- disable verbose logging
-- add a %%check section
-- introduce %%goal_dir variable, to avoid repetition
-- remove shebang line from demo/bpnn.py, as we're treating this as a
-documentation file
-- regenerate patch 2 to apply without generating a .orig file
-
-* Tue Dec 21 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-1
-- 1.4.1; fixup %%setup to reflect change in toplevel directory in upstream
-source tarball
-- apply SELinux fix to the bundled test_commands.py (patch 2)
-
-* Wed Dec 15 2010 David Malcolm <dmalcolm at redhat.com> - 1.4-4
-- rename the jit build and subpackge to just "pypy", and remove the nojit and
-sandbox builds, as upstream now seems to be focussing on the JIT build (with
-only stackless called out in the getting-started-python docs); disable
-stackless for now
-- add a verbose_logs specfile boolean; leave it enabled for now (whilst fixing
-build issues)
-- add more comments, and update others to reflect 1.2 -> 1.4 changes
-- re-enable debuginfo within CFLAGS ("-g")
-- add the LICENSE and README to all subpackages
-- ensure the built binaries don't have the "I need an executable stack" flag
-- remove DOS batch files during %%prep (idlelib.bat)
-- remove shebang lines from .py files that aren't executable, and remove
-executability from .py files that don't have a shebang line (taken from
-our python3.spec)
-- bytecompile the .py files into .pyc files in pypy's bytecode format
-
-* Sun Nov 28 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-3
-- BuildRequire valgrind-devel
-- Install pypy library from the new directory
-- Disable building with our CFLAGS for now because they are causing a build failure.
-- Include site-packages directory
-
-* Sat Nov 27 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-2
-- Add patch to configure the build to use our CFLAGS and link libffi
-  dynamically
-
-* Sat Nov 27 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-1
-- Update to 1.4
-- Drop patch for py2.6 that's in this build
-- Switch to building pypy with itself once pypy is built once as recommended by
-  upstream
-- Remove bundled, prebuilt java libraries
-- Fix license tag
-- Fix source url
-- Version pypy-libs Req
-
-* Tue May  4 2010 David Malcolm <dmalcolm at redhat.com> - 1.2-2
-- cherrypick r72073 from upstream SVN in order to fix the build against
-python 2.6.5 (patch 2)
-
-* Wed Apr 28 2010 David Malcolm <dmalcolm at redhat.com> - 1.2-1
-- initial packaging
-
diff --git a/pypy3.spec b/pypy3.spec
new file mode 100644
index 0000000..95ee959
--- /dev/null
+++ b/pypy3.spec
@@ -0,0 +1,1052 @@
+Name:           pypy3
+Version:        2.4.0
+Release:        1%{?dist}
+Summary:        Python 3 implementation with a Just-In-Time compiler
+
+Group:          Development/Languages
+# LGPL and another free license we'd need to ask spot about are present in some
+# java jars that we're not building with atm (in fact, we're deleting them
+# before building).  If we restore those we'll have to work out the new
+# licensing terms
+License:        MIT and Python and UCD
+URL:            http://pypy.org/
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+# High-level configuration of the build:
+
+# PyPy consists of an implementation of an interpreter (with JIT compilation)
+# for the full Python language  written in a high-level language, leaving many
+# of the implementation details as "pluggable" policies.
+#
+# The implementation language is then compiled down to .c code, from which we
+# obtain a binary.
+#
+# This allows us to build a near-arbitrary collection of different
+# implementations of Python with differing tradeoffs
+#
+# (As it happens, the implementation language is itself Python, albeit a
+# restricted subset "RPython", chosen to making it amenable to being compiled.
+# The result implements the full Python language though)
+
+# We could build many different implementations of Python.
+# For now, let's focus on the implementation that appears to be receiving the
+# most attention upstream: the JIT-enabled build, with all standard
+# optimizations
+
+# Building a configuration can take significant time:
+
+# A build of pypy (with jit) on i686 took 77 mins:
+#  [Timer] Timings:
+#  [Timer] annotate                       ---  583.3 s
+#  [Timer] rtype_lltype                   ---  760.9 s
+#  [Timer] pyjitpl_lltype                 ---  567.3 s
+#  [Timer] backendopt_lltype              ---  375.6 s
+#  [Timer] stackcheckinsertion_lltype     ---   54.1 s
+#  [Timer] database_c                     ---  852.2 s
+#  [Timer] source_c                       --- 1007.3 s
+#  [Timer] compile_c                      ---  419.9 s
+#  [Timer] ===========================================
+#  [Timer] Total:                         --- 4620.5 s
+#
+# A build of pypy (nojit) on x86_64 took about an hour:
+#  [Timer] Timings:
+#  [Timer] annotate                       ---  537.5 s
+#  [Timer] rtype_lltype                   ---  667.3 s
+#  [Timer] backendopt_lltype              ---  385.4 s
+#  [Timer] stackcheckinsertion_lltype     ---   42.5 s
+#  [Timer] database_c                     ---  625.3 s
+#  [Timer] source_c                       --- 1040.2 s
+#  [Timer] compile_c                      ---  273.9 s
+#  [Timer] ===========================================
+#  [Timer] Total:                         --- 3572.0 s
+#
+#
+# A build of pypy-stackless on i686 took about 87 mins:
+#  [Timer] Timings:
+#  [Timer] annotate                       ---  584.2 s
+#  [Timer] rtype_lltype                   ---  777.3 s
+#  [Timer] backendopt_lltype              ---  365.9 s
+#  [Timer] stackcheckinsertion_lltype     ---   39.3 s
+#  [Timer] database_c                     --- 1089.6 s
+#  [Timer] source_c                       --- 1868.6 s
+#  [Timer] compile_c                      ---  490.4 s
+#  [Timer] ===========================================
+#  [Timer] Total:                         --- 5215.3 s
+
+
+# We will build a "pypy" binary.
+#
+# Unfortunately, the JIT support is only available on some architectures.
+#
+# rpython/jit/backend/detect_cpu.py:getcpuclassname currently supports the
+# following options:
+#  'i386', 'x86'
+#  'x86-without-sse2':
+#  'x86_64'
+#  'armv6', 'armv7' (versions 6 and 7, hard- and soft-float ABI)
+#  'cli'
+#  'llvm'
+#
+# We will only build with JIT support on those architectures, and build without
+# it on the other archs.  The resulting binary will typically be slower than
+# CPython for the latter case.
+
+%ifarch %{ix86} x86_64 %{arm}
+%global with_jit 1
+%else
+%global with_jit 0
+%endif
+
+# Should we build a "pypy-stackless" binary?
+%global with_stackless 0
+
+# Should we build the emacs JIT-viewing mode?
+%if 0%{?rhel} == 5 || 0%{?rhel} == 6
+%global with_emacs 0
+%else
+%global with_emacs 1
+%endif
+
+# Easy way to enable/disable verbose logging:
+%global verbose_logs 0
+
+# Forcibly use the shadow-stack option for detecting GC roots, rather than
+# relying on hacking up generated assembler with regexps:
+%global shadow_stack 1
+
+# Easy way to turn off the selftests:
+%global run_selftests 1
+
+%global pypyprefix %{_libdir}/pypy3-%{version}
+%global pylibver 3
+
+# We refer to this subdir of the source tree in a few places during the build:
+%global goal_dir pypy/goal
+
+
+# Turn off the brp-python-bytecompile postprocessing script
+# We manually invoke it later on, using the freshly built pypy binary
+%global __os_install_post \
+  %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
+
+# Source and patches:
+Source0: https://bitbucket.org/pypy/pypy/downloads/pypy3-2.4.0-src.tar.bz2
+
+# Supply various useful RPM macros for building python modules against pypy:
+#  __pypy, pypy_sitelib, pypy_sitearch
+Source2: macros.pypy3
+
+# By default, if built at a tty, the translation process renders a Mandelbrot
+# set to indicate progress.
+# This obscures useful messages, and may waste CPU cycles, so suppress it, and
+# merely render dots:
+Patch0: pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
+
+# Patch pypy.translator.platform so that stdout from "make" etc gets logged,
+# rather than just stderr, so that the command-line invocations of the compiler
+# and linker are captured:
+Patch1: 006-always-log-stdout.patch
+
+# Disable the printing of a quote from IRC on startup (these are stored in
+# ROT13 form in lib_pypy/_pypy_irc_topic.py).  Some are cute, but some could
+# cause confusion for end-users (and many are in-jokes within the PyPy
+# community that won't make sense outside of it).  [Sorry to be a killjoy]
+Patch2: 007-remove-startup-message.patch
+
+
+# Build-time requirements:
+
+# pypy's can be rebuilt using itself, rather than with CPython; doing so
+# halves the build time.
+#
+# Turn it off with this boolean, to revert back to rebuilding using CPython
+# and avoid a cycle in the build-time dependency graph:
+
+%global use_self_when_building 0
+%if 0%{use_self_when_building}
+# pypy3 can only be build with pypy2
+BuildRequires: pypy
+%global bootstrap_python_interp pypy
+%else
+
+
+# pypy3 can only be build with python2
+BuildRequires: python-devel
+%global bootstrap_python_interp python
+
+%endif
+
+BuildRequires:  libffi-devel
+BuildRequires:  tcl-devel
+BuildRequires:  tk-devel
+
+BuildRequires:  sqlite-devel
+
+BuildRequires:  zlib-devel
+BuildRequires:  bzip2-devel
+BuildRequires:  ncurses-devel
+BuildRequires:  expat-devel
+BuildRequires:  openssl-devel
+%ifnarch s390
+BuildRequires:  valgrind-devel
+%endif
+
+%if %{run_selftests}
+# Used by the selftests, though not by the build:
+BuildRequires:  gc-devel
+
+# For use in the selftests, for recording stats:
+BuildRequires:  time
+
+# For use in the selftests, for imposing a per-test timeout:
+BuildRequires:  perl
+%endif
+
+# No prelink on these arches
+%ifnarch aarch64 ppc64le
+BuildRequires:  /usr/bin/execstack
+%endif
+
+# For byte-compiling the JIT-viewing mode:
+%if %{with_emacs}
+BuildRequires:  emacs
+%endif
+
+
+# Metadata for the core package (the JIT build):
+Requires: pypy3-libs = %{version}-%{release}
+
+%description
+PyPy's implementation of Python 3, featuring a Just-In-Time compiler on some CPU
+architectures, and various optimized implementations of the standard types
+(strings, dictionaries, etc)
+
+%if 0%{with_jit}
+This build of PyPy has JIT-compilation enabled.
+%else
+This build of PyPy has JIT-compilation disabled, as it is not supported on this
+CPU architecture.
+%endif
+
+
+%package libs
+Group:    Development/Languages
+Summary:  Run-time libraries used by PyPy implementations of Python 3
+
+# We supply an emacs mode for the JIT viewer.
+# (This doesn't bring in all of emacs, just the directory structure)
+%if %{with_emacs}
+Requires: emacs-filesystem >= %{_emacs_version}
+%endif
+
+%description libs
+Libraries required by the various PyPy implementations of Python 3.
+
+
+%package devel
+Group:    Development/Languages
+Summary:  Development tools for working with PyPy3
+Requires: pypy3 = %{version}-%{release}
+
+%description devel
+Header files for building C extension modules against PyPy3
+
+
+%if 0%{with_stackless}
+%package stackless
+Group:    Development/Languages
+Summary:  Stackless Python interpreter built using PyPy3
+Requires: pypy3-libs = %{version}-%{release}
+%description stackless
+Build of PyPy3 with support for micro-threads for massive concurrency
+%endif
+
+%prep
+%setup -q -n pypy3-2.4.0-src
+%patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
+%patch1 -p1
+%patch2 -p1
+
+# Replace /usr/local/bin/python shebangs with /usr/bin/python:
+find -name "*.py" -exec \
+  sed \
+    -i -e "s|/usr/local/bin/python|/usr/bin/python|" \
+    "{}" \
+    \;
+
+for f in rpython/translator/goal/bpnn.py ; do
+   # Detect shebang lines && remove them:
+   sed -e '/^#!/Q 0' -e 'Q 1' $f \
+      && sed -i '1d' $f
+   chmod a-x $f
+done
+
+
+%build
+
+BuildPyPy() {
+  ExeName=$1
+  Options=$2
+
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "STARTING BUILD OF: $ExeName"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+
+  pushd %{goal_dir}
+
+  # The build involves invoking a python script, passing in particular
+  # arguments, environment variables, etc.
+  # Some notes on those follow:
+
+  # The generated binary embeds copies of the values of all environment
+  # variables.  We need to unset "RPM_BUILD_ROOT" to avoid a fatal error from
+  #  /usr/lib/rpm/check-buildroot
+  # during the postprocessing of the rpmbuild, complaining about this
+  # reference to the buildroot
+
+
+  # By default, pypy's autogenerated C code is placed in
+  #    /tmp/usession-N
+  #  
+  # and it appears that this stops rpm from extracting the source code to the
+  # debuginfo package
+  #
+  # The logic in pypy-1.4/pypy/tool/udir.py indicates that it is generated in:
+  #    $PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-N    
+  # and so we set PYPY_USESSION_DIR so that this tempdir is within the build
+  # location, and set $PYPY_USESSION_BASENAME so that the tempdir is unique
+  # for each invocation of BuildPyPy
+
+  # Compilation flags for C code:
+  #   pypy-1.4/pypy/translator/c/genc.py:gen_makefile
+  # assembles a Makefile within
+  #   THE_UDIR/testing_1/Makefile
+  # calling out to platform.gen_makefile
+  # For us, that's
+  #   pypy-1.4/pypy/translator/platform/linux.py: class BaseLinux(BasePosix):
+  # which by default has:
+  #   CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
+  #             '-Wall', '-Wno-unused']
+  # plus all substrings from CFLAGS in the environment.
+  # This is used to generate a value for CFLAGS that's written into the Makefile
+
+  # How will we track garbage-collection roots in the generated code?
+  #   http://pypy.readthedocs.org/en/latest/config/translation.gcrootfinder.html
+
+%if 0%{shadow_stack}
+  # This is the most portable option, and avoids a reliance on non-guaranteed
+  # behaviors within GCC's code generator: use an explicitly-maintained stack
+  # of root pointers:
+  %define gcrootfinder_options --gcrootfinder=shadowstack
+
+  export CFLAGS=$(echo "$RPM_OPT_FLAGS")
+
+%else
+  # Go with the default, which is "asmgcc"
+
+  %define gcrootfinder_options %{nil}
+
+  # https://bugzilla.redhat.com/show_bug.cgi?id=588941#c18
+  # The generated Makefile compiles the .c files into assembler (.s), rather
+  # than direct to .o  It then post-processes this assembler to locate
+  # garbage-collection roots (building .lbl.s and .gcmap files, and a
+  # "gcmaptable.s").  (The modified .lbl.s files have extra code injected
+  # within them).
+  # Unfortunately, the code to do this:
+  #   pypy-1.4/pypy/translator/c/gcc/trackgcroot.py
+  # doesn't interract well with the results of using our standard build flags.
+  # For now, filter our CFLAGS of everything that could be conflicting with
+  # pypy.  Need to check these and reenable ones that are okay later.
+  # Filed as https://bugzilla.redhat.com/show_bug.cgi?id=666966
+  export CFLAGS=$(echo "$RPM_OPT_FLAGS" | sed -e 's/-Wp,-D_FORTIFY_SOURCE=2//' -e 's/-fexceptions//' -e 's/-fstack-protector//' -e 's/--param=ssp-buffer-size=4//' -e 's/-O2//' -e 's/-fasynchronous-unwind-tables//' -e 's/-march=i686//' -e 's/-mtune=atom//')
+
+%endif
+
+  # The generated C code leads to many thousands of warnings of the form:
+  #   warning: variable 'l_v26003' set but not used [-Wunused-but-set-variable]
+  # Suppress them:
+  export CFLAGS=$(echo "$CFLAGS" -Wno-unused -fPIC)
+
+  # If we're already built the JIT-enabled "pypy", then use it for subsequent
+  # builds (of other configurations):
+  if test -x './pypy' ; then
+    INTERP='./pypy'
+  else
+    # First pypy build within this rpm build?
+    # Fall back to using the bootstrap python interpreter, which might be a
+    # system copy of pypy from an earlier rpm, or be cpython's /usr/bin/python:
+    INTERP='%{bootstrap_python_interp}'
+  fi
+
+  # Here's where we actually invoke the build:
+  time \
+    RPM_BUILD_ROOT= \
+    PYPY_USESSION_DIR=$(pwd) \
+    PYPY_USESSION_BASENAME=$ExeName \
+    $INTERP ../../rpython/bin/rpython  \
+    --output=$ExeName \
+    %{gcrootfinder_options} \
+    $Options \
+    targetpypystandalone
+
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "FINISHED BUILDING: $ExeName"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+  echo "--------------------------------------------------------------"
+
+  popd
+}
+
+BuildPyPy \
+  pypy3 \
+%if 0%{with_jit}
+  "-Ojit" \
+%else
+  "-O2" \
+%endif
+  %{nil}
+
+%if 0%{with_stackless}
+BuildPyPy \
+  pypy3-stackless \
+   "--stackless"
+%endif
+
+%if %{with_emacs}
+%{_emacs_bytecompile} rpython/jit/tool/pypytrace-mode.el
+%endif
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+# Install the various executables:
+
+InstallPyPy() {
+    ExeName=$1
+
+    # To ensure compatibility with virtualenv, pypy finds its libraries
+    # relative to itself; this happens within
+    #    pypy/translator/goal/app_main.py:get_library_path
+    # which calls sys.pypy_initial_path(dirname) on the dir containing
+    # the executable, with symlinks resolved.
+    #
+    # Hence we make /usr/bin/pypy be a symlink to the real binary, which we
+    # place within /usr/lib[64]/pypy-1.* as pypy
+    #
+    # This ought to enable our pypy build to work with virtualenv
+    # (rhbz#742641)
+    install -m 755 %{goal_dir}/$ExeName %{buildroot}/%{pypyprefix}/$ExeName
+    ln -s %{pypyprefix}/$ExeName %{buildroot}/%{_bindir}
+
+    # The generated machine code doesn't need an executable stack,  but
+    # one of the assembler files (gcmaptable.s) doesn't have the necessary
+    # metadata to inform gcc of that, and thus gcc pessimistically assumes
+    # that the built binary does need an executable stack.
+    #
+    # Reported upstream as: https://codespeak.net/issue/pypy-dev/issue610
+    #
+    # I tried various approaches involving fixing the build, but the simplest
+    # approach is to postprocess the ELF file:
+%ifnarch aarch64 ppc64le
+    execstack --clear-execstack %{buildroot}/%{pypyprefix}/$ExeName
+%endif
+}
+
+mkdir -p %{buildroot}/%{_bindir}
+mkdir -p %{buildroot}/%{pypyprefix}
+
+InstallPyPy pypy3
+
+%if 0%{with_stackless}
+InstallPyPy pypy3-stackless
+%endif
+
+
+# Install the various support libraries as described at:
+#   http://codespeak.net/pypy/dist/pypy/doc/getting-started-python.html#installation
+# which refers to a "PREFIX" found relative to the location of the binary.
+# Given that the pypy binaries will be in /usr/bin, PREFIX can be
+# "../share/pypy-1.2" relative to that directory, i.e. /usr/share/pypy-1.2
+# 
+# Running "strace" on a built binary indicates that it searches within
+#   PREFIX/lib-python/modified-2.5.2
+# not
+#   PREFIX/lib-python/modified.2.5.2
+# as given on the above page, i.e. it uses '-' not '.'
+
+cp -a lib-python %{buildroot}/%{pypyprefix}
+
+cp -a lib_pypy %{buildroot}/%{pypyprefix}
+
+# Remove a text file that documents which selftests fail on Win32:
+rm %{buildroot}/%{pypyprefix}/lib-python/win32-failures.txt
+
+# Remove a text file containing upstream's recipe for syncing stdlib in
+# their hg repository with cpython's:
+rm %{buildroot}/%{pypyprefix}/lib-python/stdlib-upgrade.txt
+
+# Remove shebang lines from .py files that aren't executable, and
+# remove executability from .py files that don't have a shebang line:
+find \
+  %{buildroot}                                                           \
+  -name "*.py"                                                           \
+    \(                                                                   \
+       \( \! -perm /u+x,g+x,o+x -exec sed -e '/^#!/Q 0' -e 'Q 1' {} \;   \
+             -print -exec sed -i '1d' {} \;                              \
+          \)                                                             \
+       -o                                                                \
+       \(                                                                \
+             -perm /u+x,g+x,o+x ! -exec grep -m 1 -q '^#!' {} \;         \
+             -exec chmod a-x {} \;                                       \
+        \)                                                               \
+    \)
+
+mkdir -p %{buildroot}/%{pypyprefix}/site-packages
+
+
+# pypy uses .pyc files by default (--objspace-usepycfiles), but has a slightly
+# different bytecode format to CPython.  It doesn't use .pyo files: the -O flag
+# is treated as a "dummy optimization flag for compatibility with C Python"
+#
+# pypy-1.4/pypy/module/imp/importing.py has this comment:
+    # XXX picking a magic number is a mess.  So far it works because we
+    # have only two extra opcodes, which bump the magic number by +1 and
+    # +2 respectively, and CPython leaves a gap of 10 when it increases
+    # its own magic number.  To avoid assigning exactly the same numbers
+    # as CPython we always add a +2.  We'll have to think again when we
+    # get at the fourth new opcode :-(
+    #
+    #  * CALL_LIKELY_BUILTIN    +1
+    #  * CALL_METHOD            +2
+    #
+    # In other words:
+    #
+    #     default_magic        -- used by CPython without the -U option
+    #     default_magic + 1    -- used by CPython with the -U option
+    #     default_magic + 2    -- used by PyPy without any extra opcode
+    #     ...
+    #     default_magic + 5    -- used by PyPy with both extra opcodes
+#
+
+# pypy-1.4/pypy/interpreter/pycode.py has:
+#
+#  default_magic = (62141+2) | 0x0a0d0000                  # this PyPy's magic
+#                                                          # (62131=CPython 2.5.1)
+# giving a value for "default_magic" for PyPy of 0xa0df2bf.
+# Note that this corresponds to the "default_magic + 2" from the comment above
+
+# In my builds:
+#   $ ./pypy --info | grep objspace.opcodes
+#                objspace.opcodes.CALL_LIKELY_BUILTIN: False
+#                        objspace.opcodes.CALL_METHOD: True
+# so I'd expect the magic number to be:
+#    0x0a0df2bf + 2 (the flag for CALL_METHOD)
+# giving
+#    0x0a0df2c1
+#
+# I'm seeing
+#   c1 f2 0d 0a
+# as the first four bytes of the .pyc files, which is consistent with this.
+
+
+# Bytecompile all of the .py files we ship, using our pypy binary, giving us
+# .pyc files for pypy.  The script actually does the work twice (passing in -O
+# the second time) but it's simplest to reuse that script.
+#
+# The script has special-casing for .py files below
+#    /usr/lib{64}/python[0-9].[0-9]
+# but given that we're installing into a different path, the supplied "default"
+# implementation gets used instead.
+#
+# Note that some of the test files deliberately contain syntax errors, so
+# we pass 0 for the second argument ("errors_terminate"):
+/usr/lib/rpm/brp-python-bytecompile \
+  %{buildroot}/%{_bindir}/pypy3 \
+  0
+
+%{buildroot}/%{pypyprefix}/pypy3 -c 'import _tkinter'
+%{buildroot}/%{pypyprefix}/pypy3 -c 'import tkinter'
+%{buildroot}/%{pypyprefix}/pypy3 -c 'import _sqlite3'
+%{buildroot}/%{pypyprefix}/pypy3 -c 'import _curses'
+%{buildroot}/%{pypyprefix}/pypy3 -c 'import curses'
+%{buildroot}/%{pypyprefix}/pypy3 -c 'import syslog'
+%{buildroot}/%{pypyprefix}/pypy3 -c 'from _sqlite3 import *'
+
+# Header files for C extension modules.
+# Upstream's packaging process (pypy/tool/release/package.py)
+# creates an "include" subdir and copies all *.h/*.inl from "include" there
+# (it also has an apparently out-of-date comment about copying them from
+# pypy/_interfaces, but this directory doesn't seem to exist, and it doesn't
+# seem to do this as of 2011-01-13)
+
+# FIXME: arguably these should be instead put into a subdir below /usr/include,
+# it's not yet clear to me how upstream plan to deal with the C extension
+# interface going forward, so let's just mimic upstream for now.
+%global pypy_include_dir  %{pypyprefix}/include
+mkdir -p %{buildroot}/%{pypy_include_dir}
+cp include/*.h %{buildroot}/%{pypy_include_dir}
+
+
+# Capture the RPython source code files from the build within the debuginfo
+# package (rhbz#666975)
+%global pypy_debuginfo_dir /usr/src/debug/pypy-%{version}-src
+mkdir -p %{buildroot}%{pypy_debuginfo_dir}
+
+# copy over everything:
+cp -a pypy %{buildroot}%{pypy_debuginfo_dir}
+
+# ...then delete files that aren't:
+#   - *.py files
+#   - the Makefile
+#   - typeids.txt
+#   - dynamic-symbols-*
+find \
+  %{buildroot}%{pypy_debuginfo_dir}  \
+  \( -type f                         \
+     -a                              \
+     \! \( -name "*.py"              \
+           -o                        \
+           -name "Makefile"          \
+           -o                        \
+           -name "typeids.txt"       \
+           -o                        \
+           -name "dynamic-symbols-*" \
+        \)                           \
+  \)                                 \
+  -delete
+
+# Alternatively, we could simply keep everything.  This leads to a ~350MB
+# debuginfo package, but it makes it easy to hack on the Makefile and C build
+# flags by rebuilding/linking the sources.
+# To do so, remove the above "find" command.
+
+# We don't need bytecode for these files; they are being included for reference
+# purposes.
+# There are some rpmlint warnings from these files:
+#   non-executable-script
+#   wrong-script-interpreter
+#   zero-length
+#   script-without-shebang
+#   dangling-symlink
+# but given that the objective is to preserve a copy of the source code, those
+# are acceptable.
+
+# Install the JIT trace mode for Emacs:
+%if %{with_emacs}
+mkdir -p %{buildroot}/%{_emacs_sitelispdir}
+cp -a rpython/jit/tool/pypytrace-mode.el %{buildroot}/%{_emacs_sitelispdir}/pypy3trace-mode.el
+cp -a rpython/jit/tool/pypytrace-mode.elc %{buildroot}/%{_emacs_sitelispdir}/pypy3trace-mode.elc
+%endif
+
+# Install macros for rpm:
+mkdir -p %{buildroot}/%{_rpmconfigdir}/macros.d
+install -m 644 %{SOURCE2} %{buildroot}/%{_rpmconfigdir}/macros.d
+
+%check
+topdir=$(pwd)
+
+SkipTest() {
+    TEST_NAME=$1
+    sed -i -e"s|^$TEST_NAME$||g" testnames.txt
+}
+
+CheckPyPy() {
+    # We'll be exercising one of the freshly-built binaries using the
+    # test suite from the standard library (overridden in places by pypy's
+    # modified version)
+    ExeName=$1
+
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "STARTING TEST OF: $ExeName"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+
+    pushd %{goal_dir}
+
+    # I'm seeing numerous cases where tests seem to hang, or fail unpredictably
+    # So we'll run each test in its own process, with a timeout
+
+    # Use regrtest to explicitly list all tests:
+    ( ./$ExeName -c \
+         "from test.regrtest import findtests; print('\n'.join(findtests()))"
+    ) > testnames.txt
+
+    # Skip some tests:
+      # "audioop" doesn't exist for pypy yet:
+      SkipTest test_audioop
+
+      # The gdb CPython hooks haven't been ported to cpyext:
+      SkipTest test_gdb
+
+      # hotshot relies heavily on _hotshot, which doesn't exist:
+      SkipTest test_hotshot
+
+      # "strop" module doesn't exist for pypy yet:
+      SkipTest test_strop
+
+      # I'm seeing Koji builds hanging e.g.:
+      #   http://koji.fedoraproject.org/koji/getfile?taskID=3386821&name=build.log
+      # The only test that seems to have timed out in that log is
+      # test_multiprocessing, so skip it for now:
+      SkipTest test_multiprocessing
+
+    echo "== Test names =="
+    cat testnames.txt
+    echo "================="
+
+    echo "" > failed-tests.txt
+
+    for TestName in $(cat testnames.txt) ; do
+
+        echo "===================" $TestName "===================="
+
+        # Use /usr/bin/time (rather than the shell "time" builtin) to gather
+        # info on the process (time/CPU/memory).  This passes on the exit
+        # status of the underlying command
+        #
+        # Use perl's alarm command to impose a timeout
+        #   900 seconds is 15 minutes per test.
+        # If a test hangs, that test should get terminated, allowing the build
+        # to continue.
+        #
+        # Invoke pypy on test.regrtest to run the specific test suite
+        # verbosely
+        #
+        # For now, || true, so that any failures don't halt the build:
+        ( /usr/bin/time \
+           perl -e 'alarm shift @ARGV; exec @ARGV' 900 \
+             ./$ExeName -m test.regrtest -v $TestName ) \
+        || (echo $TestName >> failed-tests.txt) \
+        || true
+    done
+
+    echo "== Failed tests =="
+    cat failed-tests.txt
+    echo "================="
+
+    popd
+
+    # Doublecheck pypy's own test suite, using the built pypy binary:
+
+    # Disabled for now:
+    #   x86_64 shows various failures inside:
+    #     jit/backend/x86/test
+    #   followed by a segfault inside
+    #     jit/backend/x86/test/test_runner.py
+    #
+    #   i686 shows various failures inside:
+    #     jit/backend/x86/test
+    #   with the x86_64 failure leading to cancellation of the i686 build
+
+    # Here's the disabled code:
+    #    pushd pypy
+    #    time translator/goal/$ExeName test_all.py
+    #    popd
+
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "FINISHED TESTING: $ExeName"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+    echo "--------------------------------------------------------------"
+}
+
+#python testrunner/runner.py --logfile=pytest-A.log --config=pypy/pytest-A.cfg --config=pypy/pytest-A.py --root=pypy --timeout=3600
+#python pypy/test_all.py --pypy=pypy/goal/pypy --timeout=3600 --resultlog=cpython.log lib-python
+#python pypy/test_all.py --pypy=pypy/goal/pypy --resultlog=pypyjit.log pypy/module/pypyjit/test
+#pypy/goal/pypy pypy/test_all.py --resultlog=pypyjit_new.log
+
+%if %{run_selftests}
+CheckPyPy pypy3
+
+%if 0%{with_stackless}
+CheckPyPy pypy3-stackless
+%endif
+
+%endif # run_selftests
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files libs
+%defattr(-,root,root,-)
+%doc LICENSE README.rst
+
+%dir %{pypyprefix}
+%dir %{pypyprefix}/lib-python
+%{pypyprefix}/lib-python/stdlib-version.txt
+%{pypyprefix}/lib-python/%{pylibver}/
+%{pypyprefix}/lib-python/conftest.py*
+%{pypyprefix}/lib_pypy/
+%{pypyprefix}/site-packages/
+%if %{with_emacs}
+%{_emacs_sitelispdir}/pypy3trace-mode.el
+%{_emacs_sitelispdir}/pypy3trace-mode.elc
+%endif
+
+%files
+%defattr(-,root,root,-)
+%doc LICENSE README.rst
+%{_bindir}/pypy3
+%{pypyprefix}/pypy3
+
+%files devel
+%defattr(-,root,root,-)
+%dir %{pypy_include_dir}
+%{pypy_include_dir}/*.h
+%config(noreplace) %{_rpmconfigdir}/macros.d/macros.pypy3
+
+%if 0%{with_stackless}
+%files stackless
+%defattr(-,root,root,-)
+%doc LICENSE README.rst
+%{_bindir}/pypy-stackless
+%endif
+
+
+%changelog
+* Wed Sep 10 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.4.0-1
+- Update to 2.4.0
+
+* Tue Sep 02 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3.1-4
+- Move devel subpackage requires so that it gets picked up by rpm
+
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Mon Jul  7 2014 Peter Robinson <pbrobinson at fedoraproject.org> 2.3.1-2
+- ARMv7 is supported for JIT
+- no prelink on aarch64/ppc64le
+
+* Sun Jun 08 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3.1-1
+- Update to 2.3.1
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Tue May 27 2014 Dennis Gilmore <dennis at ausil.us> - 2.3-4
+- valgrind is available everywhere except 31 bit s390
+
+* Wed May 21 2014 Jaroslav Škarvada <jskarvad at redhat.com> - 2.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Changes/f21tcl86
+
+* Thu May 15 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3-2
+- Rebuilt (f21-python)
+
+* Tue May 13 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.3-1
+- Updated to 2.3
+
+* Mon Mar 10 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-3
+- Put RPM macros in proper location
+
+* Thu Jan 16 2014 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-2
+- Fixed errors due to missing __pycache__
+
+* Thu Dec 05 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.2.1-1
+- Updated to 2.2.1
+- Several bundled modules (tkinter, sqlite3, curses, syslog) were
+  not bytecompiled properly during build, that is now fixed
+- prepared new tests, not enabled yet
+
+* Thu Nov 14 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.2.0-1
+- Updated to 2.2.0
+
+* Thu Aug 15 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.1-1
+- Updated to 2.1.0
+
+* Sun Aug 04 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0.2-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-4
+- Patch1 fix
+
+* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-3
+- Yet another Sources fix
+
+* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-2
+- Fixed Source URL
+
+* Mon Jun 24 2013 Matej Stuchlik <mstuchli at redhat.com> - 2.0.2-1
+- 2.0.2, patch 8 does not seem necessary anymore
+
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0-0.2.b1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Tue Dec 11 2012 David Malcolm <dmalcolm at redhat.com> - 2.0-0.1.b1
+- 2.0b1 (drop upstreamed patch 9)
+
+* Sat Jul 21 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.9-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jul 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-3
+- log all output from "make" (patch 6)
+- disable the MOTD at startup (patch 7)
+- hide symbols from the dynamic linker (patch 8)
+- add PyInt_AsUnsignedLongLongMask (patch 9)
+- capture the Makefile, the typeids.txt, and the dynamic-symbols file within
+the debuginfo package
+
+* Mon Jun 18 2012 Peter Robinson <pbrobinson at fedoraproject.org> - 1.9-2
+- Compile with PIC, fixes FTBFS on ARM
+
+* Fri Jun  8 2012 David Malcolm <dmalcolm at redhat.com> - 1.9-1
+- 1.9
+
+* Fri Feb 10 2012 David Malcolm <dmalcolm at redhat.com> - 1.8-2
+- disable C readability patch for now (patch 4)
+
+* Thu Feb  9 2012 David Malcolm <dmalcolm at redhat.com> - 1.8-1
+- 1.8; regenerate config patch (patch 0); drop selinux patch (patch 2);
+regenerate patch 5
+
+* Tue Jan 31 2012 David Malcolm <dmalcolm at redhat.com> - 1.7-4
+- fix an incompatibility with virtualenv (rhbz#742641)
+
+* Sat Jan 14 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.7-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Fri Dec 16 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-2
+- use --gcrootfinder=shadowstack, and use standard Fedora compilation flags,
+with -Wno-unused (rhbz#666966 and rhbz#707707)
+
+* Mon Nov 21 2011 David Malcolm <dmalcolm at redhat.com> - 1.7-1
+- 1.7: refresh patch 0 (configuration) and patch 4 (readability of generated
+code)
+
+* Tue Oct  4 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-7
+- skip test_multiprocessing
+
+* Tue Sep 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-6
+- don't ship the emacs JIT-viewer on el5 and el6 (missing emacs-filesystem;
+missing _emacs_bytecompile macro on el5)
+
+* Mon Sep 12 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-5
+- build using python26 on el5 (2.4 is too early)
+* Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-4
+- fix SkipTest function to avoid corrupting the name of "test_gdbm"
+
+* Thu Aug 25 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-3
+- add rpm macros file to the devel subpackage (source 2)
+- skip some tests that can't pass yet
+
+* Sat Aug 20 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-2
+- work around test_subprocess failure seen in koji (patch 5)
+
+* Thu Aug 18 2011 David Malcolm <dmalcolm at redhat.com> - 1.6-1
+- 1.6
+- rewrite the %%check section, introducing per-test timeouts
+
+* Tue Aug  2 2011 David Malcolm <dmalcolm at redhat.com> - 1.5-2
+- add pypytrace-mode.el to the pypy-libs subpackage, for viewing JIT trace
+logs in emacs
+
+* Mon May  2 2011 David Malcolm <dmalcolm at redhat.com> - 1.5-1
+- 1.5
+
+* Wed Apr 20 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-10
+- build a /usr/bin/pypy (but without the JIT compiler) on architectures that
+don't support the JIT, so that they do at least have something that runs
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.4.1-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Fri Jan 14 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-8
+- disable self-hosting for now, due to fatal error seen JIT-compiling the
+translator
+
+* Fri Jan 14 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-7
+- skip test_ioctl for now
+
+* Thu Jan 13 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-6
+- add a "pypy-devel" subpackage, and install the header files there
+- in %%check, re-run failed tests in verbose mode
+
+* Fri Jan  7 2011 Dan Horák <dan[at]danny.cz> - 1.4.1-5
+- valgrind available only on selected architectures
+
+* Wed Jan  5 2011 David Malcolm <dmalcolm at redhat.com> - 1.4.1-4
+- rebuild pypy using itself, for speed, with a boolean to break this cycle in
+the build-requirement graph (falling back to using "python-devel" aka CPython)
+- add work-in-progress patch to try to make generated c more readable
+(rhbz#666963)
+- capture the RPython source code files from the build within the debuginfo
+package (rhbz#666975)
+
+* Wed Dec 22 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-3
+- try to respect the FHS by installing libraries below libdir, rather than
+datadir; patch app_main.py to look in this installation location first when
+scanning for the pypy library directories.
+- clarifications and corrections to the comments in the specfile
+
+* Wed Dec 22 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-2
+- remove .svn directories
+- disable verbose logging
+- add a %%check section
+- introduce %%goal_dir variable, to avoid repetition
+- remove shebang line from demo/bpnn.py, as we're treating this as a
+documentation file
+- regenerate patch 2 to apply without generating a .orig file
+
+* Tue Dec 21 2010 David Malcolm <dmalcolm at redhat.com> - 1.4.1-1
+- 1.4.1; fixup %%setup to reflect change in toplevel directory in upstream
+source tarball
+- apply SELinux fix to the bundled test_commands.py (patch 2)
+
+* Wed Dec 15 2010 David Malcolm <dmalcolm at redhat.com> - 1.4-4
+- rename the jit build and subpackge to just "pypy", and remove the nojit and
+sandbox builds, as upstream now seems to be focussing on the JIT build (with
+only stackless called out in the getting-started-python docs); disable
+stackless for now
+- add a verbose_logs specfile boolean; leave it enabled for now (whilst fixing
+build issues)
+- add more comments, and update others to reflect 1.2 -> 1.4 changes
+- re-enable debuginfo within CFLAGS ("-g")
+- add the LICENSE and README to all subpackages
+- ensure the built binaries don't have the "I need an executable stack" flag
+- remove DOS batch files during %%prep (idlelib.bat)
+- remove shebang lines from .py files that aren't executable, and remove
+executability from .py files that don't have a shebang line (taken from
+our python3.spec)
+- bytecompile the .py files into .pyc files in pypy's bytecode format
+
+* Sun Nov 28 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-3
+- BuildRequire valgrind-devel
+- Install pypy library from the new directory
+- Disable building with our CFLAGS for now because they are causing a build failure.
+- Include site-packages directory
+
+* Sat Nov 27 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-2
+- Add patch to configure the build to use our CFLAGS and link libffi
+  dynamically
+
+* Sat Nov 27 2010 Toshio Kuratomi <toshio at fedoraproject.org> - 1.4-1
+- Update to 1.4
+- Drop patch for py2.6 that's in this build
+- Switch to building pypy with itself once pypy is built once as recommended by
+  upstream
+- Remove bundled, prebuilt java libraries
+- Fix license tag
+- Fix source url
+- Version pypy-libs Req
+
+* Tue May  4 2010 David Malcolm <dmalcolm at redhat.com> - 1.2-2
+- cherrypick r72073 from upstream SVN in order to fix the build against
+python 2.6.5 (patch 2)
+
+* Wed Apr 28 2010 David Malcolm <dmalcolm at redhat.com> - 1.2-1
+- initial packaging
+
diff --git a/sources b/sources
index ab6b8f5..e4d98b7 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-6a25a212e7c5121f1f3988c118d05695  pypy-2.4.0-src.tar.bz2
+96ba72916114d16904e12562b5d84e51  pypy3-2.4.0-src.tar.bz2
-- 
cgit v0.10.2


From 146960e8a0ae6b7d82f10d6a2c24e60cf3eadd59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Mon, 27 Apr 2015 18:15:27 +0200
Subject: Removed deprecated statements


diff --git a/pypy3.spec b/pypy3.spec
index 95ee959..5bee793 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -10,7 +10,6 @@ Group:          Development/Languages
 # licensing terms
 License:        MIT and Python and UCD
 URL:            http://pypy.org/
-BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 # High-level configuration of the build:
 
@@ -425,8 +424,6 @@ BuildPyPy \
 
 
 %install
-rm -rf $RPM_BUILD_ROOT
-
 # Install the various executables:
 
 InstallPyPy() {
@@ -778,12 +775,7 @@ CheckPyPy pypy3-stackless
 %endif # run_selftests
 
 
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
 %files libs
-%defattr(-,root,root,-)
 %doc LICENSE README.rst
 
 %dir %{pypyprefix}
@@ -799,20 +791,17 @@ rm -rf $RPM_BUILD_ROOT
 %endif
 
 %files
-%defattr(-,root,root,-)
 %doc LICENSE README.rst
 %{_bindir}/pypy3
 %{pypyprefix}/pypy3
 
 %files devel
-%defattr(-,root,root,-)
 %dir %{pypy_include_dir}
 %{pypy_include_dir}/*.h
 %config(noreplace) %{_rpmconfigdir}/macros.d/macros.pypy3
 
 %if 0%{with_stackless}
 %files stackless
-%defattr(-,root,root,-)
 %doc LICENSE README.rst
 %{_bindir}/pypy-stackless
 %endif
-- 
cgit v0.10.2


From e7218e672da6a8e5c553080c36c8e72087e55817 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Mon, 27 Apr 2015 18:16:19 +0200
Subject: Use %license


diff --git a/pypy3.spec b/pypy3.spec
index 5bee793..99c2a31 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -776,7 +776,8 @@ CheckPyPy pypy3-stackless
 
 
 %files libs
-%doc LICENSE README.rst
+%license LICENSE
+%doc README.rst
 
 %dir %{pypyprefix}
 %dir %{pypyprefix}/lib-python
@@ -791,7 +792,8 @@ CheckPyPy pypy3-stackless
 %endif
 
 %files
-%doc LICENSE README.rst
+%license LICENSE
+%doc README.rst
 %{_bindir}/pypy3
 %{pypyprefix}/pypy3
 
@@ -802,7 +804,8 @@ CheckPyPy pypy3-stackless
 
 %if 0%{with_stackless}
 %files stackless
-%doc LICENSE README.rst
+%license LICENSE
+%doc README.rst
 %{_bindir}/pypy-stackless
 %endif
 
-- 
cgit v0.10.2


From 7e5676a0456e5e3c711d481fe1e949c0448975ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Mon, 27 Apr 2015 18:24:57 +0200
Subject: Use %autosetup


diff --git a/pypy3.spec b/pypy3.spec
index 99c2a31..93e53f0 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -261,10 +261,7 @@ Build of PyPy3 with support for micro-threads for massive concurrency
 %endif
 
 %prep
-%setup -q -n pypy3-2.4.0-src
-%patch0 -p1 -b .suppress-mandelbrot-set-during-tty-build
-%patch1 -p1
-%patch2 -p1
+%autosetup -n pypy3-2.4.0-src -p1
 
 # Replace /usr/local/bin/python shebangs with /usr/bin/python:
 find -name "*.py" -exec \
-- 
cgit v0.10.2


From 1842b1b13e95edfcea412981ed8f4cbe3e7a8383 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Mon, 27 Apr 2015 18:26:21 +0200
Subject: Require pypy3-libs with %{?_isa}


diff --git a/pypy3.spec b/pypy3.spec
index 93e53f0..85a2dfc 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -213,7 +213,7 @@ BuildRequires:  emacs
 
 
 # Metadata for the core package (the JIT build):
-Requires: pypy3-libs = %{version}-%{release}
+Requires: pypy3-libs%{?_isa} = %{version}-%{release}
 
 %description
 PyPy's implementation of Python 3, featuring a Just-In-Time compiler on some CPU
@@ -245,7 +245,7 @@ Libraries required by the various PyPy implementations of Python 3.
 %package devel
 Group:    Development/Languages
 Summary:  Development tools for working with PyPy3
-Requires: pypy3 = %{version}-%{release}
+Requires: pypy3%{?_isa} = %{version}-%{release}
 
 %description devel
 Header files for building C extension modules against PyPy3
@@ -255,7 +255,7 @@ Header files for building C extension modules against PyPy3
 %package stackless
 Group:    Development/Languages
 Summary:  Stackless Python interpreter built using PyPy3
-Requires: pypy3-libs = %{version}-%{release}
+Requires: pypy3-libs%{?_isa} = %{version}-%{release}
 %description stackless
 Build of PyPy3 with support for micro-threads for massive concurrency
 %endif
-- 
cgit v0.10.2


From 7e82938b0f41850371be195e7be814fedd889d08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Mon, 27 Apr 2015 18:35:23 +0200
Subject: Share the docdir across subpackages


diff --git a/pypy3.spec b/pypy3.spec
index 85a2dfc..d9e54fd 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -771,6 +771,10 @@ CheckPyPy pypy3-stackless
 
 %endif # run_selftests
 
+# Because there's a bunch of binary subpackages and creating
+# /usr/share/licenses/pypy3-this and /usr/share/licenses/pypy3-that
+# is just confusing for the user.
+%global _docdir_fmt %{name}
 
 %files libs
 %license LICENSE
-- 
cgit v0.10.2


From a7610e26e5c7a0bbaa8a7810daa04a625ae357af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Tue, 28 Apr 2015 19:51:45 +0200
Subject: Don't mark RPM macros in /etc as %config


diff --git a/pypy3.spec b/pypy3.spec
index d9e54fd..0c5b340 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -801,7 +801,7 @@ CheckPyPy pypy3-stackless
 %files devel
 %dir %{pypy_include_dir}
 %{pypy_include_dir}/*.h
-%config(noreplace) %{_rpmconfigdir}/macros.d/macros.pypy3
+%{_rpmconfigdir}/macros.d/macros.pypy3
 
 %if 0%{with_stackless}
 %files stackless
-- 
cgit v0.10.2


From 1120251a081f3a611d8d3f742b184985833e9998 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Tue, 28 Apr 2015 19:58:39 +0200
Subject: Change python-devel to python2-devel


diff --git a/pypy3.spec b/pypy3.spec
index 0c5b340..2f9ed15 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -170,7 +170,7 @@ BuildRequires: pypy
 
 
 # pypy3 can only be build with python2
-BuildRequires: python-devel
+BuildRequires: python2-devel
 %global bootstrap_python_interp python
 
 %endif
-- 
cgit v0.10.2


From cfca1560fdf042a07e2f7108eafc072b93f2617c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Tue, 28 Apr 2015 20:01:21 +0200
Subject: Use git in %autosetup to avoid .orig files


diff --git a/pypy3.spec b/pypy3.spec
index 2f9ed15..3b40c9a 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -261,7 +261,7 @@ Build of PyPy3 with support for micro-threads for massive concurrency
 %endif
 
 %prep
-%autosetup -n pypy3-2.4.0-src -p1
+%autosetup -n pypy3-2.4.0-src -p1 -S git
 
 # Replace /usr/local/bin/python shebangs with /usr/bin/python:
 find -name "*.py" -exec \
-- 
cgit v0.10.2


From 524d40e5a2091088f5a28f16c996b757acbeb06b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Tue, 28 Apr 2015 20:05:42 +0200
Subject: Remove build script from the package


diff --git a/pypy3.spec b/pypy3.spec
index 3b40c9a..e992b00 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -644,6 +644,9 @@ cp -a rpython/jit/tool/pypytrace-mode.elc %{buildroot}/%{_emacs_sitelispdir}/pyp
 mkdir -p %{buildroot}/%{_rpmconfigdir}/macros.d
 install -m 644 %{SOURCE2} %{buildroot}/%{_rpmconfigdir}/macros.d
 
+# Remove build script from the package
+rm %{buildroot}/%{pypyprefix}/lib_pypy/ctypes_config_cache/rebuild.py
+
 %check
 topdir=$(pwd)
 
-- 
cgit v0.10.2


From 819b9f5595c2ac93d1a8a693a647a006f2c9bbc0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Mon, 4 May 2015 12:47:32 +0200
Subject: Use %global instead of %define


diff --git a/pypy3.spec b/pypy3.spec
index e992b00..77ffa2d 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -337,14 +337,14 @@ BuildPyPy() {
   # This is the most portable option, and avoids a reliance on non-guaranteed
   # behaviors within GCC's code generator: use an explicitly-maintained stack
   # of root pointers:
-  %define gcrootfinder_options --gcrootfinder=shadowstack
+  %global gcrootfinder_options --gcrootfinder=shadowstack
 
   export CFLAGS=$(echo "$RPM_OPT_FLAGS")
 
 %else
   # Go with the default, which is "asmgcc"
 
-  %define gcrootfinder_options %{nil}
+  %global gcrootfinder_options %{nil}
 
   # https://bugzilla.redhat.com/show_bug.cgi?id=588941#c18
   # The generated Makefile compiles the .c files into assembler (.s), rather
-- 
cgit v0.10.2


From 980f988cc4d495d359155cf3c1d12b2dfc81a08f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Mon, 4 May 2015 12:48:44 +0200
Subject: BR git for %autosetup -S git


diff --git a/pypy3.spec b/pypy3.spec
index 77ffa2d..218ce3e 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -211,6 +211,8 @@ BuildRequires:  /usr/bin/execstack
 BuildRequires:  emacs
 %endif
 
+# For %%autosetup -S git
+BuildRequires:  git
 
 # Metadata for the core package (the JIT build):
 Requires: pypy3-libs%{?_isa} = %{version}-%{release}
-- 
cgit v0.10.2


From 976314ef808d7b7dbe2bc8961a5de2deae1cdc9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Mon, 4 May 2015 12:49:51 +0200
Subject: Build with pypy


diff --git a/pypy3.spec b/pypy3.spec
index 218ce3e..edbfd2f 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -161,7 +161,9 @@ Patch2: 007-remove-startup-message.patch
 # Turn it off with this boolean, to revert back to rebuilding using CPython
 # and avoid a cycle in the build-time dependency graph:
 
-%global use_self_when_building 0
+# Note, pypy3 is built with pypy2, so no dependency cycle
+
+%global use_self_when_building 1
 %if 0%{use_self_when_building}
 # pypy3 can only be build with pypy2
 BuildRequires: pypy
-- 
cgit v0.10.2


From 36afc7f79102c83960c3d6bf8f4a8620554c0137 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Tue, 5 May 2015 18:32:38 +0200
Subject: Replace all lib-python python shebangs with pypy


diff --git a/pypy3.spec b/pypy3.spec
index edbfd2f..6e6bd46 100644
--- a/pypy3.spec
+++ b/pypy3.spec
@@ -281,6 +281,11 @@ for f in rpython/translator/goal/bpnn.py ; do
    chmod a-x $f
 done
 
+# Replace all lib-python python shebangs with pypy
+find lib-python/%{pylibver} -name "*.py" -exec \
+  sed -r -i '1s|^#!\s*/usr/bin.*python.*|#!/usr/bin/%{name}|' \
+    "{}" \
+    \;
 
 %build
 
-- 
cgit v0.10.2


From 5f5775aa52401c7c7261d2e610fa796420e51b9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro at hroncok.cz>
Date: Sun, 10 May 2015 16:04:51 +0200
Subject: Remove unused patches


diff --git a/008-fix-dynamic-symbols-script.patch b/008-fix-dynamic-symbols-script.patch
deleted file mode 100644
index 5b1d551..0000000
--- a/008-fix-dynamic-symbols-script.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/pypy/translator/platform/posix.py b/pypy/translator/platform/posix.py
---- a/pypy/translator/platform/posix.py
-+++ b/pypy/translator/platform/posix.py
-@@ -48,8 +48,10 @@
-         response_file = self._make_response_file("dynamic-symbols-")
-         f = response_file.open("w")
-         f.write("{\n")
-+        f.write("  global:\n")
-         for sym in eci.export_symbols:
--            f.write("%s;\n" % (sym,))
-+            f.write("    %s;\n" % (sym,))
-+        f.write("  local:*;\n")
-         f.write("};")
-         f.close()
- 
diff --git a/config.patch b/config.patch
deleted file mode 100644
index bf81d7d..0000000
--- a/config.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-diff -rup pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py
---- pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py	2013-05-27 10:35:37.679237332 +0200
-+++ pypy-pypy-f66246c46ca3/rpython/translator/platform/linux.py	2013-05-27 10:47:41.506354482 +0200
-@@ -32,19 +32,20 @@ class BaseLinux(BasePosix):
-         return self._pkg_config("libffi", "--libs-only-L",
-                                 ['/usr/lib/libffi'])
- 
--    def library_dirs_for_libffi_a(self):
--        # places where we need to look for libffi.a
--        # XXX obscuuure!  only look for libffi.a if run with translate.py
--        if 'translate' in sys.modules:
--            if sys.maxint > 2**32:
--                host = 'x86_64'
--            else:
--                host = 'x86'
--            return self.library_dirs_for_libffi() + [
--                '/usr/lib',
--                '/usr/lib/%s-linux-gnu/' % host]
--        else:
--            return []
-+    #Fedora, at least, has the shared version but not the static:
-+    #def library_dirs_for_libffi_a(self):
-+    #    # places where we need to look for libffi.a
-+    #    # XXX obscuuure!  only look for libffi.a if run with translate.py
-+    #    if 'translate' in sys.modules:
-+    #        if sys.maxint > 2**32:
-+    #            host = 'x86_64'
-+    #        else:
-+    #            host = 'x86'
-+    #        return self.library_dirs_for_libffi() + [
-+    #            '/usr/lib',
-+    #            '/usr/lib/%s-linux-gnu/' % host]
-+    #    else:
-+    #        return []
- 
- 
- class Linux(BaseLinux):
diff --git a/more-readable-c-code.patch b/more-readable-c-code.patch
deleted file mode 100644
index 92d340f..0000000
--- a/more-readable-c-code.patch
+++ /dev/null
@@ -1,693 +0,0 @@
-diff -up pypy-pypy-release-1.7/pypy/interpreter/pycode.py.more-readable-c-code pypy-pypy-release-1.7/pypy/interpreter/pycode.py
---- pypy-pypy-release-1.7/pypy/interpreter/pycode.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/interpreter/pycode.py	2011-11-21 16:16:15.673463780 -0500
-@@ -13,6 +13,7 @@ from pypy.interpreter.gateway import Non
- from pypy.interpreter.astcompiler.consts import (
-     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
-     CO_GENERATOR, CO_CONTAINSGLOBALS)
-+from pypy.interpreter.pytraceback import offset2lineno
- from pypy.rlib.rarithmetic import intmask
- from pypy.rlib.debug import make_sure_not_resized
- from pypy.rlib import jit
-@@ -81,6 +82,7 @@ class PyCode(eval.Code):
-         self.hidden_applevel = hidden_applevel
-         self.magic = magic
-         self._signature = cpython_code_signature(self)
-+        self._cached_source = None
-         self._initialize()
- 
-     def _initialize(self):
-@@ -397,3 +399,23 @@ class PyCode(eval.Code):
- 
-     def repr(self, space):
-         return space.wrap(self.get_repr())
-+
-+    def get_linenum_for_offset(self, offset):
-+        # Given a bytecode offset, return a 1-based index into the lines of the
-+        # source code
-+        return offset2lineno(self, offset)
-+
-+    def _ensure_source(self):
-+        # Lazily grab the source lines into self._cached_source (or raise
-+        # an IOError)
-+        if not self._cached_source:
-+            f = open(self.co_filename, 'r')
-+            source = [line.rstrip() for line in f.readlines()]
-+            f.close()
-+            self._cached_source = source
-+    
-+    def get_source_text(self, linenum):
-+        # Given a 1-based index, get the corresponding line of source code (or
-+        # raise an IOError)
-+        self._ensure_source()
-+        return self._cached_source[linenum - 1]
-diff -up pypy-pypy-release-1.7/pypy/objspace/flow/model.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/model.py
---- pypy-pypy-release-1.7/pypy/objspace/flow/model.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/objspace/flow/model.py	2011-11-21 16:15:36.599466455 -0500
-@@ -31,6 +31,120 @@ from pypy.tool.identity_dict import iden
- 
- __metaclass__ = type
- 
-+class SourceLoc(object):
-+    # A srcloc is a specific location within the RPython source code,
-+    # intended for human display
-+    __slots__ = ('code', # code object
-+                 'linenum' # 1-based index, as displayed to a user
-+                 )
-+    def __init__(self, code, linenum):
-+        self.code = code
-+        self.linenum = linenum
-+
-+    def get_text(self):
-+        # Get the actual source text of this line
-+        return self.code.get_source_text(self.linenum)
-+
-+    def __eq__(self, other):
-+        return self.code == other.code and self.linenum == other.linenum
-+
-+    def __ne__(self, other):
-+        if other:
-+            return self.code != other.code or self.linenum != other.linenum
-+        else:
-+            return True
-+
-+class CodeLoc(object):
-+    # A codeloc is a specific location within the RPython bytecode
-+    __slots__ = ('code', # code object
-+                 'offset' # int index into bytecode, or -1
-+                 )
-+
-+    def __init__(self, code, offset):
-+        self.code = code
-+        self.offset = offset
-+
-+    def __str__(self):
-+        if self.offset >= 0:
-+            return "%s@%d" % (self.code.co_name, self.offset)
-+        else:
-+            return ""
-+
-+    def __ne__(self, other):
-+        if other:
-+            return self.code != other.code or self.offset != other.offset
-+        else:
-+            return True
-+
-+    def __cmp__(self, other):
-+        # Partial ordering, for those locations that have an offset:
-+        if other:
-+            if self.offset >= 0 and other.offset >= 0:
-+                return self.offset - other.offset
-+        return 0
-+
-+    def get_source_loc(self):
-+        # Convert to a SourceLoc:
-+        return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset))
-+
-+class OperationLoc(object):
-+    # An oploc is the location within the RPython source code of a given
-+    # operation
-+    # 
-+    # This is a list consisting of CodeLoc instances, some of which may be None
-+    #
-+    # For the simple case, this is list of length 1 with a single CodeLoc
-+    #
-+    # For an operation inside an inlined callsite, we have a list of length 2:
-+    #    [codeloc of callsite,
-+    #     codeloc of operation within inlined body]
-+    #
-+    # For more interesting inlined cases, we have a chain of source locations:
-+    #    [codeloc of callsite,
-+    #     codeloc of inner callsite,
-+    #     ... ,
-+    #     codeloc of innermost inlined callsite,
-+    #     codeloc of operation within inlined body]
-+    #
-+
-+    __slots__ = ('codelocs', )
-+
-+    def __init__(self, codelocs):
-+        self.codelocs = codelocs
-+
-+    def __str__(self):
-+        return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']'
-+
-+    def __cmp__(self, other):
-+        return cmp(self.codelocs, other.codelocs)
-+
-+def block_comparator(blk0, blk1):
-+    '''
-+    Sort function for blocks, putting them in an ordering that attempts to
-+    maximize readability of the generated C code
-+    '''
-+    # print 'comparing %r and %r' % (blk0, blk1)
-+    # Put the start/end block at the top/bottom:
-+    if blk0.isstartblock:
-+        return -1
-+
-+    if blk1.isstartblock:
-+        return 1
-+
-+    # Order blocks by the offset, where present:
-+    if blk0.operations:
-+        if blk1.operations:
-+            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
-+        else:
-+            return -1
-+    else:
-+        if blk1.operations:
-+            return 1
-+        else:
-+            return 0
-+
-+def edge_comparator(edge0, edge1):
-+    return block_comparator(edge0.target, edge1.target)
- 
- class FunctionGraph(object):
-     __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__']
-@@ -94,6 +208,21 @@ class FunctionGraph(object):
-                 seen[block] = True
-                 stack += block.exits[::-1]
- 
-+    def iterblocks_by_source(self):
-+        # Try to preserve logical source ordering in the blocks
-+        block = self.startblock
-+        yield block
-+        seen = {block: True}
-+        stack = list(block.exits[::-1])
-+        stack.sort(edge_comparator)
-+        while stack:
-+            block = stack.pop().target
-+            if block not in seen:
-+                yield block
-+                seen[block] = True
-+                stack += block.exits[::-1]
-+                stack.sort(edge_comparator)
-+
-     def iterlinks(self):
-         block = self.startblock
-         seen = {block: True}
-@@ -183,14 +312,14 @@ class Block(object):
-         self.exits      = []              # list of Link(s)
- 
-     def at(self):
--        if self.operations and self.operations[0].offset >= 0:
--            return "@%d" % self.operations[0].offset
-+        if self.operations:
-+            return str(self.operations[0].oploc)
-         else:
-             return ""
- 
-     def __str__(self):
-         if self.operations:
--            txt = "block@%d" % self.operations[0].offset
-+            txt = "block%s" % self.operations[0].oploc
-         else:
-             if (not self.exits) and len(self.inputargs) == 1:
-                 txt = "return block"
-@@ -245,6 +374,21 @@ class Block(object):
-         from pypy.translator.tool.graphpage import try_show
-         try_show(self)
- 
-+    def isreturnblock(self):
-+        return (not self.operations) and (not self.exits) and len(self.inputargs) == 1
-+
-+    def get_base_label(self, blocknum):
-+        # Generate a more friendly C label for this block
-+        if self.operations:
-+            txt = "block"
-+        elif (not self.exits) and len(self.inputargs) == 1:
-+            txt = "return_block"
-+        elif (not self.exits) and len(self.inputargs) == 2:
-+            txt = "raise_block"
-+        else:
-+            txt = "codeless_block"
-+        return '%s%d' % (txt, blocknum)
-+
- 
- class Variable(object):
-     __slots__ = ["_name", "_nr", "concretetype"]
-@@ -331,13 +475,15 @@ class WrapException(Exception):
- 
- 
- class SpaceOperation(object):
--    __slots__ = "opname args result offset".split()
-+    __slots__ = "opname args result oploc".split()
- 
--    def __init__(self, opname, args, result, offset=-1):
-+    def __init__(self, opname, args, result, oploc=None):
-         self.opname = intern(opname)      # operation name
-         self.args   = list(args)  # mixed list of var/const
-         self.result = result      # either Variable or Constant instance
--        self.offset = offset      # offset in code string
-+        if oploc is None:
-+            oploc = OperationLoc([None])
-+        self.oploc = oploc
- 
-     def __eq__(self, other):
-         return (self.__class__ is other.__class__ and 
-@@ -352,8 +498,9 @@ class SpaceOperation(object):
-         return hash((self.opname,tuple(self.args),self.result))
- 
-     def __repr__(self):
--        return "%r = %s(%s)" % (self.result, self.opname,
--                                ", ".join(map(repr, self.args)))
-+        return "%r = %s(%s) (%s)" % (self.result, self.opname,
-+                                     ", ".join(map(repr, self.args)),
-+                                     self.oploc)
- 
- class Atom(object):
-     def __init__(self, name):
-@@ -427,8 +574,7 @@ def copygraph(graph, shallow=False, varm
-                 for op in oplist:
-                     copyop = SpaceOperation(op.opname,
-                                             [copyvar(v) for v in op.args],
--                                            copyvar(op.result), op.offset)
--                    #copyop.offset = op.offset
-+                                            copyvar(op.result), op.oploc)
-                     result.append(copyop)
-                 return result
-             newblock.operations = copyoplist(block.operations)
-diff -up pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py
---- pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/objspace/flow/objspace.py	2011-11-21 16:15:36.600466455 -0500
-@@ -315,7 +315,9 @@ class FlowObjSpace(ObjSpace):
-     def do_operation(self, name, *args_w):
-         spaceop = SpaceOperation(name, args_w, Variable())
-         if hasattr(self, 'executioncontext'):  # not here during bootstrapping
--            spaceop.offset = self.executioncontext.crnt_offset
-+            codeloc = CodeLoc(self.executioncontext.code,
-+                              self.executioncontext.crnt_offset)
-+            spaceop.oploc = OperationLoc([codeloc])
-             self.executioncontext.recorder.append(spaceop)
-         return spaceop.result
- 
-diff -up pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py.more-readable-c-code pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py
---- pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/objspace/flow/test/test_model.py	2011-11-21 16:15:36.600466455 -0500
-@@ -119,3 +119,25 @@ def test_variable():
-     assert v2.renamed
-     assert v2.name.startswith("foobar_") and v2.name != v.name
-     assert v2.name.split('_', 1)[1].isdigit()
-+
-+def test_source_locations():
-+    # Invent some random offsets into the code:
-+    co = sample_function.__code__
-+    codelocA = CodeLoc(co, 42)
-+    codelocB = CodeLoc(co, 87)
-+
-+    assert str(codelocA) == 'sample_function at 42'
-+    assert str(codelocB) == 'sample_function at 87'
-+
-+    assert cmp(codelocA, codelocB) < 0
-+    assert cmp(codelocB, codelocA) > 0
-+    
-+    oplocA = OperationLoc([codelocA])
-+    oplocB = OperationLoc([codelocB])
-+
-+    assert str(oplocA) == '[sample_function at 42]'
-+    assert str(oplocB) == '[sample_function at 87]'
-+
-+    assert cmp(oplocA, oplocB) < 0
-+    assert cmp(oplocB, oplocA) > 0
-+
-diff -up pypy-pypy-release-1.7/pypy/rpython/rtyper.py.more-readable-c-code pypy-pypy-release-1.7/pypy/rpython/rtyper.py
---- pypy-pypy-release-1.7/pypy/rpython/rtyper.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/rpython/rtyper.py	2011-11-21 16:15:36.601466455 -0500
-@@ -800,7 +800,7 @@ class HighLevelOp(object):
-         return vars
- 
-     def genop(self, opname, args_v, resulttype=None):
--        return self.llops.genop(opname, args_v, resulttype)
-+        return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc)
- 
-     def gendirectcall(self, ll_function, *args_v):
-         return self.llops.gendirectcall(ll_function, *args_v)
-@@ -935,7 +935,7 @@ class LowLevelOpList(list):
-                                                     v.concretetype))
-         return v
- 
--    def genop(self, opname, args_v, resulttype=None):
-+    def genop(self, opname, args_v, resulttype=None, oploc=None):
-         try:
-             for v in args_v:
-                 v.concretetype
-@@ -944,7 +944,7 @@ class LowLevelOpList(list):
-                                  " and pass its result to genop(),"
-                                  " never hop.args_v directly.")
-         vresult = Variable()
--        self.append(SpaceOperation(opname, args_v, vresult))
-+        self.append(SpaceOperation(opname, args_v, vresult, oploc))
-         if resulttype is None:
-             vresult.concretetype = Void
-             return None
-diff -up pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py
---- pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/backendopt/inline.py	2011-11-21 16:15:36.601466455 -0500
-@@ -4,6 +4,7 @@ from pypy.translator.simplify import get
- from pypy.translator.unsimplify import copyvar
- from pypy.objspace.flow.model import Variable, Constant, Block, Link
- from pypy.objspace.flow.model import SpaceOperation, c_last_exception
-+from pypy.objspace.flow.model import OperationLoc
- from pypy.objspace.flow.model import FunctionGraph
- from pypy.objspace.flow.model import mkentrymap, checkgraph
- from pypy.annotation import model as annmodel
-@@ -231,6 +232,7 @@ class BaseInliner(object):
-         self.varmap = {}
-         self._copied_blocks = {}
-         self.op = block.operations[index_operation]
-+        self.callsite_oploc = self.op.oploc
-         self.graph_to_inline = self.get_graph_from_op(self.op)
-         self.exception_guarded = False
-         if (block.exitswitch == c_last_exception and
-@@ -290,7 +292,9 @@ class BaseInliner(object):
-         
-     def copy_operation(self, op):
-         args = [self.get_new_name(arg) for arg in op.args]
--        result = SpaceOperation(op.opname, args, self.get_new_name(op.result))
-+        new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:])
-+        result = SpaceOperation(op.opname, args, self.get_new_name(op.result), 
-+                                new_oploc)
-         return result
- 
-     def copy_block(self, block):
-diff -up pypy-pypy-release-1.7/pypy/translator/c/funcgen.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/c/funcgen.py
---- pypy-pypy-release-1.7/pypy/translator/c/funcgen.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/c/funcgen.py	2011-11-21 16:15:36.602466455 -0500
-@@ -1,4 +1,6 @@
- import sys
-+import inspect
-+import dis
- from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
- from pypy.translator.c.support import cdecl
- from pypy.translator.c.support import llvalue_from_constant, gen_assignments
-@@ -22,6 +24,38 @@ LOCALVAR = 'l_%s'
- 
- KEEP_INLINED_GRAPHS = False
- 
-+def block_comparator(blk0, blk1):
-+    '''
-+    Sort function for blocks, putting them in an ordering that attempts to
-+    maximize readability of the generated C code
-+    '''
-+    # print 'comparing %r and %r' % (blk0, blk1)
-+    # Put the start/end block at the top/bottom:
-+    if blk0.isstartblock:
-+        return -1
-+
-+    if blk1.isstartblock:
-+        return 1
-+
-+    # Order blocks by the offset, where present:
-+    if blk0.operations:
-+        if blk1.operations:
-+            return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc)
-+        else:
-+            return -1
-+    else:
-+        if blk1.operations:
-+            return 1
-+        else:
-+            return 0
-+
-+def escape_c_comments(py_src):
-+    # Escape C comments within RPython source, to avoid generating bogus
-+    # comments in our generated C source:
-+    py_src = py_src.replace('/*', '')
-+    py_src = py_src.replace('*/', '')
-+    return py_src
-+
- class FunctionCodeGenerator(object):
-     """
-     Collects information about a function which we have to generate
-@@ -207,14 +241,57 @@ class FunctionCodeGenerator(object):
- 
-     def cfunction_body(self):
-         graph = self.graph
--        yield 'goto block0;'    # to avoid a warning "this label is not used"
-+        # Try to print python source code:
-+        if hasattr(graph, 'func'):
-+            filename = inspect.getfile(graph.func)
-+            #yield '/* name: %r */' % filename
-+            try:
-+                src, startline = inspect.getsourcelines(graph.func)
-+            except IOError:
-+                pass # No source found
-+            except IndexError:
-+                pass # Bulletproofing
-+            else:
-+                yield '/* Python source %r' % filename
-+                for i, line in enumerate(src):
-+                    line = line.rstrip()
-+                    line = escape_c_comments(line)
-+                    # FuncNode.funcgen_implementation treats lines ending in ':'
-+                    # as C blocks, which messes up the formatting.
-+                    # Work around this:
-+                    if line.endswith(':'):
-+                        line += ' '
-+                    yield ' * %4d : %s' % (startline + i, line)
-+                yield ' */'
-+
-+        label = graph.startblock.get_base_label(self.blocknum[graph.startblock])
-+        yield 'goto %s;' % label # to avoid a warning "this label is not used"
-+
-+        # Sort the blocks into a (hopefully) readable order:
-+        blocks = list(graph.iterblocks_by_source())
-+        blocks.sort(block_comparator)
- 
-         # generate the body of each block
--        for block in graph.iterblocks():
-+        for block in blocks:
-+            cursrcloc = None
-             myblocknum = self.blocknum[block]
-             yield ''
--            yield 'block%d:' % myblocknum
-+            yield '%s:' % block.get_base_label(myblocknum)
-+            #yield "/* repr(block): %r */" % (block, )
-+            #yield "/* type(block): %r */" % (type(block), )
-             for i, op in enumerate(block.operations):
-+                #yield "/* type(op): %r */" % (type(op), )
-+                #yield "/* op.oploc: %s */" % (op.oploc, )
-+                codeloc = op.oploc.codelocs[-1]
-+                if codeloc:
-+                    srcloc = codeloc.get_source_loc()
-+                    if srcloc != cursrcloc:
-+                        try:
-+                            yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text()))
-+                            cursrcloc = srcloc
-+                        except IOError:
-+                            pass
-+
-                 for line in self.gen_op(op):
-                     yield line
-             if len(block.exits) == 0:
-@@ -306,7 +383,7 @@ class FunctionCodeGenerator(object):
-             assignments.append((a2typename, dest, src))
-         for line in gen_assignments(assignments):
-             yield line
--        label = 'block%d' % self.blocknum[link.target]
-+        label = link.target.get_base_label(self.blocknum[link.target])
-         if link.target in self.innerloops:
-             loop = self.innerloops[link.target]
-             if link is loop.links[-1]:   # link that ends a loop
-diff -up pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py
---- pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/c/test/test_genc.py	2011-11-21 16:15:36.602466455 -0500
-@@ -1,4 +1,5 @@
- import autopath, sys, os, py
-+import re
- from pypy.rpython.lltypesystem.lltype import *
- from pypy.annotation import model as annmodel
- from pypy.translator.translator import TranslationContext
-@@ -532,3 +533,130 @@ def test_inhibit_tail_call():
-     else:
-         assert 0, "the call was not found in the C source"
-     assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1]
-+
-+def get_generated_c_source(fn, types):
-+    # Return a (optimized fn, c source code, c source filename) 3-tuple
-+    t = Translation(fn)
-+    t.annotate(types)
-+    c_filename_path = t.source_c()
-+    h = c_filename_path.open()
-+    src = h.read()
-+    h.close()
-+    c_fn = t.compile_c()
-+    return (c_fn, src, c_filename_path)
-+
-+def extract_c_function(c_src, fname):
-+    # Extract the source for a given C function out of a the given src string
-+    # Makes assumptions about the layout of the source
-+    pattern = '^(.+) \**%s\(.*\) {$' % fname
-+    within_fn = False
-+    result = ''
-+    for line in c_src.splitlines():
-+        if within_fn:
-+            result += line + '\n'
-+            if line.startswith('}'):
-+                return result
-+        else:
-+            m = re.match(pattern, line)
-+            if m:
-+                within_fn = True
-+                result += line + '\n'
-+    return result
-+    
-+    
-+
-+def test_generated_c_source():
-+    # Verify that generate C source "looks good"
-+    # We'll use is_perfect_number, as it contains a loop and a conditional
-+
-+    # Generate C source code
-+    from pypy.translator.test.snippet import is_perfect_number
-+    c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number,
-+                                                        [int])
-+
-+    # Locate the C source for the type-specialized function:
-+    c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number')
-+    
-+    # Verify that the C source contains embedded comments containing the lines
-+    # of the python source:
-+    expected_comment_lines = [
-+        '/* is_perfect_number:31 :     while div < n: */',
-+        '/* is_perfect_number:32 :         if n % div == 0: */',
-+        '/* is_perfect_number:33 :             sum += div */',
-+        '/* is_perfect_number:34 :         div += 1 */',
-+        '/* is_perfect_number:35 :     return n == sum */']
-+    for exp_line in expected_comment_lines:
-+        assert exp_line in c_fn_src
-+        
-+    # Verify that the lines occur in the correct order
-+    # ...we do this by filtering the function's generated C source to just
-+    # those lines containing our comments (and dropping whitespace):
-+    lines = c_fn_src.splitlines()
-+    lines = [line.strip()
-+             for line in lines
-+             if '/* is_perfect_number:' in line]
-+
-+    # ...we should now have exact equality: the ordering should be as expected,
-+    # and each comment should appear exactly once:
-+    assert lines == expected_comment_lines
-+
-+    # Ensure that the generated C function does the right thing:
-+    assert c_fn(5) == False
-+    assert c_fn(6) == True
-+    assert c_fn(7) == False
-+
-+    assert c_fn(5.0) == False
-+    assert c_fn(6.0) == True
-+    assert c_fn(7.0) == False
-+
-+    assert c_fn(5L) == False
-+    assert c_fn(6L) == True
-+    assert c_fn(7L) == False
-+
-+    try:
-+        c_fn('hello world')
-+    except:
-+        pass
-+    else:
-+        raise 'Was expected exception'
-+    
-+def test_escaping_c_comments():
-+    # Ensure that c comments within RPython code get escaped when we generate
-+    # our .c code (to avoid generating bogus C)
-+    # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a
-+    # docstring embedding a C comment
-+    def c_style_comment(a, b):
-+        '''Here is a C-style comment within an RPython docstring:
-+                /* hello world */
-+        '''
-+        # and here's one in a string literal:
-+        return '/* hello world a:%s b:%s */' % (a, b)
-+
-+    def cplusplus_style_comment(a, b):
-+        '''Here is a C++-style comment within an RPython docstring:
-+                // hello world
-+        '''
-+        # and here are some in string literals, and one as the floor division
-+        # operator:
-+        return '// hello world: a // b = %s' % (a // b)
-+
-+    for fn_name, exp_output in [('c_style_comment',
-+                                 '/* hello world a:6 b:3 */'),
-+                                ('cplusplus_style_comment',
-+                                 '// hello world: a // b = 2')]:
-+        fn = locals()[fn_name]
-+
-+        c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int])
-+        # If the above survived, then the C compiler managed to handle
-+        # the generated C code
-+
-+        # Verify that the generated code works (i.e. that we didn't
-+        # accidentally change the meaning):
-+        assert c_fn(6, 3) == exp_output
-+
-+        # Ensure that at least part of the docstrings made it into the C
-+        # code:
-+        c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name)
-+        assert 'Here is a ' in c_fn_src
-+        assert 'style comment within an RPython docstring' in c_fn_src
-+        
-diff -up pypy-pypy-release-1.7/pypy/translator/driver.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/driver.py
---- pypy-pypy-release-1.7/pypy/translator/driver.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/driver.py	2011-11-21 16:15:36.603466455 -0500
-@@ -535,6 +535,7 @@ class TranslationDriver(SimpleTaskEngine
-             dstname = self.compute_exe_name() + '.staticdata.info'
-             shutil.copy(str(fname), str(dstname))
-             self.log.info('Static data info written to %s' % dstname)
-+        return c_source_filename
- 
-     #
-     task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
-diff -up pypy-pypy-release-1.7/pypy/translator/gensupp.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/gensupp.py
---- pypy-pypy-release-1.7/pypy/translator/gensupp.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/gensupp.py	2011-11-21 16:15:36.603466455 -0500
-@@ -14,8 +14,8 @@ def ordered_blocks(graph):
-     allblocks = []
-     for block in graph.iterblocks():
-             # first we order by offset in the code string
--            if block.operations:
--                ofs = block.operations[0].offset
-+            if block.operations and block.operations[0].oploc.codelocs[0]:
-+                ofs = block.operations[0].oploc.codelocs[0].offset
-             else:
-                 ofs = sys.maxint
-             # then we order by input variable name or value
-diff -up pypy-pypy-release-1.7/pypy/translator/interactive.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/interactive.py
---- pypy-pypy-release-1.7/pypy/translator/interactive.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/interactive.py	2011-11-21 16:15:36.604466454 -0500
-@@ -138,7 +138,7 @@ class Translation(object):
-     def source_c(self, argtypes=None, **kwds):
-         self.update_options(argtypes, kwds)
-         self.ensure_backend('c')
--        self.driver.source_c()
-+        return self.driver.source_c()
- 
-     def source_cl(self, argtypes=None, **kwds):
-         self.update_options(argtypes, kwds)
-diff -up pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py
---- pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/llsupport/wrapper.py	2011-11-21 16:15:36.604466454 -0500
-@@ -59,6 +59,8 @@ def new_wrapper(func, translator, newnam
-     # "return result"
-     block = Block(wrapper_inputargs)
-     wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
-+    if hasattr(graph, 'func'):
-+        wgraph.func = graph.func
-     translator.update_call_graph(wgraph, graph, object())
-     translator.graphs.append(wgraph)
-     block.operations[:] = newops
-diff -up pypy-pypy-release-1.7/pypy/translator/simplify.py.more-readable-c-code pypy-pypy-release-1.7/pypy/translator/simplify.py
---- pypy-pypy-release-1.7/pypy/translator/simplify.py.more-readable-c-code	2011-11-19 02:44:54.000000000 -0500
-+++ pypy-pypy-release-1.7/pypy/translator/simplify.py	2011-11-21 16:15:36.605466454 -0500
-@@ -292,7 +292,7 @@ def join_blocks(graph):
-                 return renaming.get(v, v)
-             def rename_op(op):
-                 args = [rename(a) for a in op.args]
--                op = SpaceOperation(op.opname, args, rename(op.result), op.offset)
-+                op = SpaceOperation(op.opname, args, rename(op.result), op.oploc)
-                 # special case...
-                 if op.opname == 'indirect_call':
-                     if isinstance(op.args[0], Constant):
diff --git a/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch b/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
deleted file mode 100644
index 2391f32..0000000
--- a/pypy-1.6-fix-test-subprocess-with-nonreadable-path-dir.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -rup pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py
---- pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py	2013-05-27 10:35:37.762237806 +0200
-+++ pypy-pypy-f66246c46ca3/lib-python/2.7/test/test_subprocess.py	2013-05-28 10:13:03.182536196 +0200
-@@ -587,7 +587,7 @@ class ProcessTestCase(BaseTestCase):
-         for i in range(1024):
-             # Windows raises IOError.  Others raise OSError.
-             with self.assertRaises(EnvironmentError) as c:
--                subprocess.Popen(['nonexisting_i_hope'],
-+                subprocess.Popen(['/usr/bin/nonexisting_i_hope'],
-                                  stdout=subprocess.PIPE,
-                                  stderr=subprocess.PIPE)
-             # ignore errors that indicate the command was not found
-- 
cgit v0.10.2


	http://pkgs.fedoraproject.org/cgit/pypy3.git/commit/?h=f22&id=908d523efb68df54d872af8a8c6324e0f8f7f106


More information about the scm-commits mailing list