[pypy-svn] r79915 - in pypy/branch/jitypes2: . lib-python/modified-2.5.2/distutils lib-python/modified-2.5.2/test/output lib_pypy/_ctypes lib_pypy/pypy_test pypy pypy/annotation pypy/config pypy/doc/config pypy/interpreter pypy/interpreter/pyparser pypy/interpreter/pyparser/test pypy/interpreter/test pypy/jit/backend/llsupport pypy/jit/backend/x86/test pypy/jit/codewriter pypy/jit/codewriter/test pypy/jit/metainterp pypy/jit/metainterp/optimizeopt pypy/jit/metainterp/test pypy/module/_lsprof pypy/module/_lsprof/test pypy/module/_stackless pypy/module/array/benchmark pypy/module/array/test pypy/module/cpyext pypy/module/cpyext/include pypy/module/cpyext/src pypy/module/cpyext/test pypy/module/exceptions pypy/module/imp pypy/module/pypyjit/test pypy/module/sys pypy/objspace/std pypy/objspace/std/test pypy/rlib pypy/rlib/test pypy/rpython/lltypesystem pypy/rpython/memory/gc pypy/rpython/memory/gctransform pypy/rpython/tool pypy/tool pypy/tool/release pypy/translator/goal pypy/translator/platform

antocuni at codespeak.net antocuni at codespeak.net
Thu Dec 9 09:13:12 CET 2010


Author: antocuni
Date: Thu Dec  9 09:13:06 2010
New Revision: 79915

Added:
   pypy/branch/jitypes2/pypy/doc/config/translation.jit_ffi.txt
      - copied unchanged from r79914, pypy/trunk/pypy/doc/config/translation.jit_ffi.txt
   pypy/branch/jitypes2/pypy/module/cpyext/include/fileobject.h
      - copied unchanged from r79914, pypy/trunk/pypy/module/cpyext/include/fileobject.h
   pypy/branch/jitypes2/pypy/module/cpyext/pypyintf.py
      - copied unchanged from r79914, pypy/trunk/pypy/module/cpyext/pypyintf.py
Modified:
   pypy/branch/jitypes2/   (props changed)
   pypy/branch/jitypes2/lib-python/modified-2.5.2/distutils/unixccompiler.py
   pypy/branch/jitypes2/lib-python/modified-2.5.2/test/output/test_cProfile
   pypy/branch/jitypes2/lib_pypy/_ctypes/function.py
   pypy/branch/jitypes2/lib_pypy/pypy_test/test_hashlib.py
   pypy/branch/jitypes2/pypy/   (props changed)
   pypy/branch/jitypes2/pypy/annotation/binaryop.py
   pypy/branch/jitypes2/pypy/config/pypyoption.py
   pypy/branch/jitypes2/pypy/config/translationoption.py
   pypy/branch/jitypes2/pypy/interpreter/baseobjspace.py
   pypy/branch/jitypes2/pypy/interpreter/executioncontext.py
   pypy/branch/jitypes2/pypy/interpreter/mixedmodule.py
   pypy/branch/jitypes2/pypy/interpreter/pyparser/error.py
   pypy/branch/jitypes2/pypy/interpreter/pyparser/pytokenizer.py
   pypy/branch/jitypes2/pypy/interpreter/pyparser/test/test_pyparse.py
   pypy/branch/jitypes2/pypy/interpreter/test/test_executioncontext.py
   pypy/branch/jitypes2/pypy/interpreter/test/test_function.py
   pypy/branch/jitypes2/pypy/jit/backend/llsupport/llmodel.py
   pypy/branch/jitypes2/pypy/jit/backend/x86/test/test_runner.py
   pypy/branch/jitypes2/pypy/jit/codewriter/regalloc.py
   pypy/branch/jitypes2/pypy/jit/codewriter/test/test_regalloc.py
   pypy/branch/jitypes2/pypy/jit/metainterp/optimizefindnode.py
   pypy/branch/jitypes2/pypy/jit/metainterp/optimizeopt/__init__.py
   pypy/branch/jitypes2/pypy/jit/metainterp/optimizeopt/optimizer.py   (props changed)
   pypy/branch/jitypes2/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/jitypes2/pypy/jit/metainterp/test/test_compile.py
   pypy/branch/jitypes2/pypy/jit/metainterp/test/test_fficall.py
   pypy/branch/jitypes2/pypy/jit/metainterp/test/test_optimizefficall.py
   pypy/branch/jitypes2/pypy/jit/metainterp/test/test_optimizeopt.py
   pypy/branch/jitypes2/pypy/jit/metainterp/warmspot.py
   pypy/branch/jitypes2/pypy/module/_lsprof/interp_lsprof.py
   pypy/branch/jitypes2/pypy/module/_lsprof/test/test_cprofile.py
   pypy/branch/jitypes2/pypy/module/_stackless/interp_coroutine.py
   pypy/branch/jitypes2/pypy/module/array/benchmark/Makefile   (props changed)
   pypy/branch/jitypes2/pypy/module/array/benchmark/intimg.c   (props changed)
   pypy/branch/jitypes2/pypy/module/array/benchmark/intimgtst.c   (props changed)
   pypy/branch/jitypes2/pypy/module/array/benchmark/intimgtst.py   (props changed)
   pypy/branch/jitypes2/pypy/module/array/benchmark/loop.c   (props changed)
   pypy/branch/jitypes2/pypy/module/array/benchmark/sum.c   (props changed)
   pypy/branch/jitypes2/pypy/module/array/benchmark/sumtst.c   (props changed)
   pypy/branch/jitypes2/pypy/module/array/benchmark/sumtst.py   (props changed)
   pypy/branch/jitypes2/pypy/module/array/test/test_array.py
   pypy/branch/jitypes2/pypy/module/array/test/test_array_old.py   (props changed)
   pypy/branch/jitypes2/pypy/module/cpyext/__init__.py
   pypy/branch/jitypes2/pypy/module/cpyext/api.py
   pypy/branch/jitypes2/pypy/module/cpyext/include/Python.h
   pypy/branch/jitypes2/pypy/module/cpyext/include/tupleobject.h
   pypy/branch/jitypes2/pypy/module/cpyext/intobject.py
   pypy/branch/jitypes2/pypy/module/cpyext/object.py
   pypy/branch/jitypes2/pypy/module/cpyext/pyerrors.py
   pypy/branch/jitypes2/pypy/module/cpyext/pythonrun.py
   pypy/branch/jitypes2/pypy/module/cpyext/slotdefs.py
   pypy/branch/jitypes2/pypy/module/cpyext/src/getargs.c
   pypy/branch/jitypes2/pypy/module/cpyext/state.py
   pypy/branch/jitypes2/pypy/module/cpyext/stubs.py
   pypy/branch/jitypes2/pypy/module/cpyext/test/test_cpyext.py
   pypy/branch/jitypes2/pypy/module/cpyext/test/test_intobject.py
   pypy/branch/jitypes2/pypy/module/cpyext/test/test_object.py
   pypy/branch/jitypes2/pypy/module/cpyext/test/test_pyerrors.py
   pypy/branch/jitypes2/pypy/module/cpyext/test/test_tupleobject.py
   pypy/branch/jitypes2/pypy/module/cpyext/tupleobject.py
   pypy/branch/jitypes2/pypy/module/exceptions/interp_exceptions.py
   pypy/branch/jitypes2/pypy/module/imp/importing.py
   pypy/branch/jitypes2/pypy/module/pypyjit/test/test_pypy_c.py
   pypy/branch/jitypes2/pypy/module/sys/vm.py
   pypy/branch/jitypes2/pypy/objspace/std/complexobject.py
   pypy/branch/jitypes2/pypy/objspace/std/complextype.py
   pypy/branch/jitypes2/pypy/objspace/std/floattype.py
   pypy/branch/jitypes2/pypy/objspace/std/longobject.py
   pypy/branch/jitypes2/pypy/objspace/std/strutil.py
   pypy/branch/jitypes2/pypy/objspace/std/test/test_complexobject.py
   pypy/branch/jitypes2/pypy/objspace/std/test/test_strutil.py
   pypy/branch/jitypes2/pypy/rlib/rerased.py   (props changed)
   pypy/branch/jitypes2/pypy/rlib/test/test_rerased.py   (props changed)
   pypy/branch/jitypes2/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/branch/jitypes2/pypy/rpython/memory/gc/base.py
   pypy/branch/jitypes2/pypy/rpython/memory/gc/minimark.py
   pypy/branch/jitypes2/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/jitypes2/pypy/rpython/tool/rffi_platform.py
   pypy/branch/jitypes2/pypy/tool/error.py
   pypy/branch/jitypes2/pypy/tool/release/package.py
   pypy/branch/jitypes2/pypy/translator/goal/app_main.py
   pypy/branch/jitypes2/pypy/translator/platform/darwin.py
Log:
merge from trunk: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r79770:HEAD .

Modified: pypy/branch/jitypes2/lib-python/modified-2.5.2/distutils/unixccompiler.py
==============================================================================
--- pypy/branch/jitypes2/lib-python/modified-2.5.2/distutils/unixccompiler.py	(original)
+++ pypy/branch/jitypes2/lib-python/modified-2.5.2/distutils/unixccompiler.py	Thu Dec  9 09:13:06 2010
@@ -121,7 +121,22 @@
                   }
 
     if sys.platform[:6] == "darwin":
+        import platform
+        if platform.machine() == 'i386':
+            if platform.architecture()[0] == '32bit':
+                arch = 'i386'
+            else:
+                arch = 'x86_64'
+        else:
+            # just a guess
+            arch = platform.machine()
         executables['ranlib'] = ["ranlib"]
+        executables['linker_so'] += ['-undefined', 'dynamic_lookup']
+
+        for k, v in executables.iteritems():
+            if v and v[0] == 'cc':
+                v += ['-arch', arch]
+
 
     # Needed for the filename generation methods provided by the base
     # class, CCompiler.  NB. whoever instantiates/uses a particular

Modified: pypy/branch/jitypes2/lib-python/modified-2.5.2/test/output/test_cProfile
==============================================================================
--- pypy/branch/jitypes2/lib-python/modified-2.5.2/test/output/test_cProfile	(original)
+++ pypy/branch/jitypes2/lib-python/modified-2.5.2/test/output/test_cProfile	Thu Dec  9 09:13:06 2010
@@ -14,66 +14,66 @@
         4    0.116    0.029    0.120    0.030 test_cProfile.py:78(helper1)
         2    0.000    0.000    0.140    0.070 test_cProfile.py:89(helper2_indirect)
         8    0.312    0.039    0.400    0.050 test_cProfile.py:93(helper2)
-        4    0.000    0.000    0.000    0.000 {append}
-        1    0.000    0.000    0.000    0.000 {disable}
        12    0.000    0.000    0.012    0.001 {hasattr}
+        4    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
+        1    0.000    0.000    0.000    0.000 {method 'disable' of 'Profile' objects}
         8    0.000    0.000    0.000    0.000 {range}
         4    0.000    0.000    0.000    0.000 {sys.exc_info}
 
 
    Ordered by: standard name
 
-Function                               called...
-                                           ncalls  tottime  cumtime
-<string>:1(<module>)                   ->       1    0.270    1.000  test_cProfile.py:30(testfunc)
-test_cProfile.py:103(subhelper)        ->      16    0.016    0.016  test_cProfile.py:115(__getattr__)
-                                                8    0.000    0.000  {range}
-test_cProfile.py:115(__getattr__)      ->
-test_cProfile.py:30(testfunc)          ->       1    0.014    0.130  test_cProfile.py:40(factorial)
-                                                2    0.040    0.600  test_cProfile.py:60(helper)
-test_cProfile.py:40(factorial)         ->    20/3    0.130    0.147  test_cProfile.py:40(factorial)
-                                               20    0.020    0.020  test_cProfile.py:53(mul)
-test_cProfile.py:53(mul)               ->
-test_cProfile.py:60(helper)            ->       4    0.116    0.120  test_cProfile.py:78(helper1)
-                                                2    0.000    0.140  test_cProfile.py:89(helper2_indirect)
-                                                6    0.234    0.300  test_cProfile.py:93(helper2)
-test_cProfile.py:78(helper1)           ->       4    0.000    0.000  {append}
-                                                4    0.000    0.004  {hasattr}
-                                                4    0.000    0.000  {sys.exc_info}
-test_cProfile.py:89(helper2_indirect)  ->       2    0.006    0.040  test_cProfile.py:40(factorial)
-                                                2    0.078    0.100  test_cProfile.py:93(helper2)
-test_cProfile.py:93(helper2)           ->       8    0.064    0.080  test_cProfile.py:103(subhelper)
-                                                8    0.000    0.008  {hasattr}
-{append}                               ->
-{disable}                              ->
-{hasattr}                              ->      12    0.012    0.012  test_cProfile.py:115(__getattr__)
-{range}                                ->
-{sys.exc_info}                         ->
+Function                                 called...
+                                             ncalls  tottime  cumtime
+<string>:1(<module>)                     ->       1    0.270    1.000  test_cProfile.py:30(testfunc)
+test_cProfile.py:103(subhelper)          ->      16    0.016    0.016  test_cProfile.py:115(__getattr__)
+                                                  8    0.000    0.000  {range}
+test_cProfile.py:115(__getattr__)        ->
+test_cProfile.py:30(testfunc)            ->       1    0.014    0.130  test_cProfile.py:40(factorial)
+                                                  2    0.040    0.600  test_cProfile.py:60(helper)
+test_cProfile.py:40(factorial)           ->    20/3    0.130    0.147  test_cProfile.py:40(factorial)
+                                                 20    0.020    0.020  test_cProfile.py:53(mul)
+test_cProfile.py:53(mul)                 ->
+test_cProfile.py:60(helper)              ->       4    0.116    0.120  test_cProfile.py:78(helper1)
+                                                  2    0.000    0.140  test_cProfile.py:89(helper2_indirect)
+                                                  6    0.234    0.300  test_cProfile.py:93(helper2)
+test_cProfile.py:78(helper1)             ->       4    0.000    0.004  {hasattr}
+                                                  4    0.000    0.000  {method 'append' of 'list' objects}
+                                                  4    0.000    0.000  {sys.exc_info}
+test_cProfile.py:89(helper2_indirect)    ->       2    0.006    0.040  test_cProfile.py:40(factorial)
+                                                  2    0.078    0.100  test_cProfile.py:93(helper2)
+test_cProfile.py:93(helper2)             ->       8    0.064    0.080  test_cProfile.py:103(subhelper)
+                                                  8    0.000    0.008  {hasattr}
+{hasattr}                                ->      12    0.012    0.012  test_cProfile.py:115(__getattr__)
+{method 'append' of 'list' objects}      ->
+{method 'disable' of 'Profile' objects}  ->
+{range}                                  ->
+{sys.exc_info}                           ->
 
 
    Ordered by: standard name
 
-Function                               was called by...
-                                           ncalls  tottime  cumtime
-<string>:1(<module>)                   <-
-test_cProfile.py:103(subhelper)        <-       8    0.064    0.080  test_cProfile.py:93(helper2)
-test_cProfile.py:115(__getattr__)      <-      16    0.016    0.016  test_cProfile.py:103(subhelper)
-                                               12    0.012    0.012  {hasattr}
-test_cProfile.py:30(testfunc)          <-       1    0.270    1.000  <string>:1(<module>)
-test_cProfile.py:40(factorial)         <-       1    0.014    0.130  test_cProfile.py:30(testfunc)
-                                             20/3    0.130    0.147  test_cProfile.py:40(factorial)
-                                                2    0.006    0.040  test_cProfile.py:89(helper2_indirect)
-test_cProfile.py:53(mul)               <-      20    0.020    0.020  test_cProfile.py:40(factorial)
-test_cProfile.py:60(helper)            <-       2    0.040    0.600  test_cProfile.py:30(testfunc)
-test_cProfile.py:78(helper1)           <-       4    0.116    0.120  test_cProfile.py:60(helper)
-test_cProfile.py:89(helper2_indirect)  <-       2    0.000    0.140  test_cProfile.py:60(helper)
-test_cProfile.py:93(helper2)           <-       6    0.234    0.300  test_cProfile.py:60(helper)
-                                                2    0.078    0.100  test_cProfile.py:89(helper2_indirect)
-{append}                               <-       4    0.000    0.000  test_cProfile.py:78(helper1)
-{disable}                              <-
-{hasattr}                              <-       4    0.000    0.004  test_cProfile.py:78(helper1)
-                                                8    0.000    0.008  test_cProfile.py:93(helper2)
-{range}                                <-       8    0.000    0.000  test_cProfile.py:103(subhelper)
-{sys.exc_info}                         <-       4    0.000    0.000  test_cProfile.py:78(helper1)
+Function                                 was called by...
+                                             ncalls  tottime  cumtime
+<string>:1(<module>)                     <-
+test_cProfile.py:103(subhelper)          <-       8    0.064    0.080  test_cProfile.py:93(helper2)
+test_cProfile.py:115(__getattr__)        <-      16    0.016    0.016  test_cProfile.py:103(subhelper)
+                                                 12    0.012    0.012  {hasattr}
+test_cProfile.py:30(testfunc)            <-       1    0.270    1.000  <string>:1(<module>)
+test_cProfile.py:40(factorial)           <-       1    0.014    0.130  test_cProfile.py:30(testfunc)
+                                               20/3    0.130    0.147  test_cProfile.py:40(factorial)
+                                                  2    0.006    0.040  test_cProfile.py:89(helper2_indirect)
+test_cProfile.py:53(mul)                 <-      20    0.020    0.020  test_cProfile.py:40(factorial)
+test_cProfile.py:60(helper)              <-       2    0.040    0.600  test_cProfile.py:30(testfunc)
+test_cProfile.py:78(helper1)             <-       4    0.116    0.120  test_cProfile.py:60(helper)
+test_cProfile.py:89(helper2_indirect)    <-       2    0.000    0.140  test_cProfile.py:60(helper)
+test_cProfile.py:93(helper2)             <-       6    0.234    0.300  test_cProfile.py:60(helper)
+                                                  2    0.078    0.100  test_cProfile.py:89(helper2_indirect)
+{hasattr}                                <-       4    0.000    0.004  test_cProfile.py:78(helper1)
+                                                  8    0.000    0.008  test_cProfile.py:93(helper2)
+{method 'append' of 'list' objects}      <-       4    0.000    0.000  test_cProfile.py:78(helper1)
+{method 'disable' of 'Profile' objects}  <-
+{range}                                  <-       8    0.000    0.000  test_cProfile.py:103(subhelper)
+{sys.exc_info}                           <-       4    0.000    0.000  test_cProfile.py:78(helper1)
 
 

Modified: pypy/branch/jitypes2/lib_pypy/_ctypes/function.py
==============================================================================
--- pypy/branch/jitypes2/lib_pypy/_ctypes/function.py	(original)
+++ pypy/branch/jitypes2/lib_pypy/_ctypes/function.py	Thu Dec  9 09:13:06 2010
@@ -199,9 +199,8 @@
         restype = self._restype_
         funcptr = self._getfuncptr(argtypes, restype, thisarg)
         result = funcptr(*newargs)
-        if restype and restype._ffishape == 'u':
-            # XXX: maybe it's a job of _ffi?
-            result = unichr(result)
+        result = self._wrap_result(restype, result)
+        #
         ## resbuffer = funcptr(*[arg._get_buffer_for_param()._buffer
         ##                       for arg in args])
         ## result = self._build_result(restype, resbuffer, argtypes, args)
@@ -383,6 +382,8 @@
                 wrapped_args.append(wrapped)
         return wrapped_args
 
+
+    # XXX: maybe the following two methods should be done inside _ffi?
     def _unwrap_args(self, argtypes, args):
         """
         Convert from ctypes high-level values to low-level values suitables to
@@ -399,13 +400,31 @@
             elif argtype._ffishape == 'P':
                 value = arg._buffer.buffer
                 if value > sys.maxint:
-                    # XXX: simulate overflow so that _ffi receive and int, not a long
+                    # XXX: workaround for old versions of pypy-c, as soon as
+                    # translation works again we can remove it
                     value = (-sys.maxint-1)*2 + value
             else:
                 value = arg.value
             newargs.append(value)
         return newargs
 
+    def _wrap_result(self, restype, result):
+        """
+        Convert from low-level repr of the result to the high-level python
+        one: e.g., if the restype is a pointer 0 is converted to None, and
+        for chars we convert the int value with chr, etc.
+        """
+        if not restype:
+            return None
+        elif restype._ffishape == 'u':
+            result = unichr(result)
+        elif restype._ffishape == 'P':
+            if result == 0:
+                result = None
+            else:
+                assert False, 'TODO'
+        return result
+
     def _build_result(self, restype, resbuffer, argtypes, argsandobjs):
         """Build the function result:
            If there is no OUT parameter, return the actual function result

Modified: pypy/branch/jitypes2/lib_pypy/pypy_test/test_hashlib.py
==============================================================================
--- pypy/branch/jitypes2/lib_pypy/pypy_test/test_hashlib.py	(original)
+++ pypy/branch/jitypes2/lib_pypy/pypy_test/test_hashlib.py	Thu Dec  9 09:13:06 2010
@@ -41,7 +41,8 @@
 
         # also test the pure Python implementation
         modname, constructor = pure_python_version[name].split('.')
-        builder = getattr(__import__(modname), constructor)
+        mod = __import__('lib_pypy.' + modname, None, None, ['__doc__'])
+        builder = getattr(mod, constructor)
         h = builder('')
         assert h.digest_size == expected_size
         assert h.digestsize == expected_size

Modified: pypy/branch/jitypes2/pypy/annotation/binaryop.py
==============================================================================
--- pypy/branch/jitypes2/pypy/annotation/binaryop.py	(original)
+++ pypy/branch/jitypes2/pypy/annotation/binaryop.py	Thu Dec  9 09:13:06 2010
@@ -861,7 +861,7 @@
     def getitem((p, obj)):
         assert False,"ptr %r getitem index not an int: %r" % (p.ll_ptrtype, obj)
 
-    def setitem((p, obj)):
+    def setitem((p, obj), s_value):
         assert False,"ptr %r setitem index not an int: %r" % (p.ll_ptrtype, obj)
 
 class __extend__(pairtype(SomeObject, SomePtr)):

Modified: pypy/branch/jitypes2/pypy/config/pypyoption.py
==============================================================================
--- pypy/branch/jitypes2/pypy/config/pypyoption.py	(original)
+++ pypy/branch/jitypes2/pypy/config/pypyoption.py	Thu Dec  9 09:13:06 2010
@@ -76,6 +76,7 @@
     "_rawffi": [("objspace.usemodules.struct", True)],
     "cpyext": [("translation.secondaryentrypoints", "cpyext"),
                ("translation.shared", sys.platform == "win32")],
+    "_ffi": [("translation.jit_ffi", True)],
     }
 
 module_import_dependencies = {

Modified: pypy/branch/jitypes2/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/jitypes2/pypy/config/translationoption.py	(original)
+++ pypy/branch/jitypes2/pypy/config/translationoption.py	Thu Dec  9 09:13:06 2010
@@ -117,6 +117,7 @@
     ChoiceOption("jit_profiler", "integrate profiler support into the JIT",
                  ["off", "oprofile"],
                  default="off"),
+    BoolOption("jit_ffi", "optimize libffi calls", default=False),
 
     # misc
     BoolOption("verbose", "Print extra information", default=False),

Modified: pypy/branch/jitypes2/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/jitypes2/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/jitypes2/pypy/interpreter/baseobjspace.py	Thu Dec  9 09:13:06 2010
@@ -862,14 +862,14 @@
 
     def call_args_and_c_profile(self, frame, w_func, args):
         ec = self.getexecutioncontext()
-        ec.c_call_trace(frame, w_func)
+        ec.c_call_trace(frame, w_func, args)
         try:
             w_res = self.call_args(w_func, args)
         except OperationError, e:
             w_value = e.get_w_value(self)
             ec.c_exception_trace(frame, w_value)
             raise
-        ec.c_return_trace(frame, w_func)
+        ec.c_return_trace(frame, w_func, args)
         return w_res
 
     def call_method(self, w_obj, methname, *arg_w):

Modified: pypy/branch/jitypes2/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/branch/jitypes2/pypy/interpreter/executioncontext.py	(original)
+++ pypy/branch/jitypes2/pypy/interpreter/executioncontext.py	Thu Dec  9 09:13:06 2010
@@ -27,7 +27,6 @@
     def __init__(self, space):
         self.space = space
         self.topframeref = jit.vref_None
-        self.framestackdepth = 0
         # tracing: space.frame_trace_action.fire() must be called to ensure
         # that tracing occurs whenever self.w_tracefunc or self.is_tracing
         # is modified.
@@ -54,9 +53,6 @@
         return frame
 
     def enter(self, frame):
-        if self.framestackdepth > self.space.sys.recursionlimit:
-            raise self.space.prebuilt_recursion_error
-        self.framestackdepth += 1
         frame.f_backref = self.topframeref
         self.topframeref = jit.virtual_ref(frame)
 
@@ -66,7 +62,6 @@
                 self._trace(frame, 'leaveframe', self.space.w_None)
         finally:
             self.topframeref = frame.f_backref
-            self.framestackdepth -= 1
             jit.virtual_ref_finish(frame)
 
         if self.w_tracefunc is not None and not frame.hide():
@@ -80,7 +75,6 @@
 
         def __init__(self):
             self.topframe = None
-            self.framestackdepth = 0
             self.w_tracefunc = None
             self.profilefunc = None
             self.w_profilefuncarg = None
@@ -88,7 +82,6 @@
 
         def enter(self, ec):
             ec.topframeref = jit.non_virtual_ref(self.topframe)
-            ec.framestackdepth = self.framestackdepth
             ec.w_tracefunc = self.w_tracefunc
             ec.profilefunc = self.profilefunc
             ec.w_profilefuncarg = self.w_profilefuncarg
@@ -97,7 +90,6 @@
 
         def leave(self, ec):
             self.topframe = ec.gettopframe()
-            self.framestackdepth = ec.framestackdepth
             self.w_tracefunc = ec.w_tracefunc
             self.profilefunc = ec.profilefunc
             self.w_profilefuncarg = ec.w_profilefuncarg 
@@ -105,7 +97,6 @@
 
         def clear_framestack(self):
             self.topframe = None
-            self.framestackdepth = 0
 
         # the following interface is for pickling and unpickling
         def getstate(self, space):
@@ -121,33 +112,41 @@
                 self.topframe = space.interp_w(PyFrame, frames_w[-1])
             else:
                 self.topframe = None
-            self.framestackdepth = len(frames_w)
 
         def getframestack(self):
-            index = self.framestackdepth
-            lst = [None] * index
+            lst = []
             f = self.topframe
-            while index > 0:
-                index -= 1
-                lst[index] = f
+            while f is not None:
+                lst.append(f)
                 f = f.f_backref()
-            assert f is None
+            lst.reverse()
             return lst
         # coroutine: I think this is all, folks!
 
-    def c_call_trace(self, frame, w_func):
+    def c_call_trace(self, frame, w_func, args=None):
         "Profile the call of a builtin function"
-        if self.profilefunc is None:
-            frame.is_being_profiled = False
-        else:
-            self._trace(frame, 'c_call', w_func)
+        self._c_call_return_trace(frame, w_func, args, 'c_call')
 
-    def c_return_trace(self, frame, w_retval):
+    def c_return_trace(self, frame, w_func, args=None):
         "Profile the return from a builtin function"
+        self._c_call_return_trace(frame, w_func, args, 'c_return')
+
+    def _c_call_return_trace(self, frame, w_func, args, event):
         if self.profilefunc is None:
             frame.is_being_profiled = False
         else:
-            self._trace(frame, 'c_return', w_retval)
+            # undo the effect of the CALL_METHOD bytecode, which would be
+            # that even on a built-in method call like '[].append()',
+            # w_func is actually the unbound function 'append'.
+            from pypy.interpreter.function import FunctionWithFixedCode
+            if isinstance(w_func, FunctionWithFixedCode) and args is not None:
+                w_firstarg = args.firstarg()
+                if w_firstarg is not None:
+                    from pypy.interpreter.function import descr_function_get
+                    w_func = descr_function_get(self.space, w_func, w_firstarg,
+                                                self.space.type(w_firstarg))
+            #
+            self._trace(frame, event, w_func)
 
     def c_exception_trace(self, frame, w_exc):
         "Profile function called upon OperationError."

Modified: pypy/branch/jitypes2/pypy/interpreter/mixedmodule.py
==============================================================================
--- pypy/branch/jitypes2/pypy/interpreter/mixedmodule.py	(original)
+++ pypy/branch/jitypes2/pypy/interpreter/mixedmodule.py	Thu Dec  9 09:13:06 2010
@@ -13,6 +13,10 @@
 
     applevel_name = None
     expose__file__attribute = True
+
+    # The following attribute is None as long as the module has not been
+    # imported yet, and when it has been, it is mod.__dict__.items() just
+    # after startup().
     w_initialdict = None
 
     def __init__(self, space, w_name): 
@@ -26,8 +30,14 @@
         """This is called each time the module is imported or reloaded
         """
         if self.w_initialdict is not None:
+            # the module was already imported.  Refresh its content with
+            # the saved dict, as done with built-in and extension modules
+            # on CPython.
             space.call_method(self.w_dict, 'update', self.w_initialdict)
-        Module.init(self, space)
+        else:
+            Module.init(self, space)
+            if not self.lazy and self.w_initialdict is None:
+                self.w_initialdict = space.call_method(self.w_dict, 'items')
 
     def get_applevel_name(cls):
         """ NOT_RPYTHON """
@@ -96,6 +106,7 @@
 
     def _freeze_(self):
         self.getdict()
+        self.w_initialdict = None
         self.startup_called = False
         # hint for the annotator: Modules can hold state, so they are
         # not constant

Modified: pypy/branch/jitypes2/pypy/interpreter/pyparser/error.py
==============================================================================
--- pypy/branch/jitypes2/pypy/interpreter/pyparser/error.py	(original)
+++ pypy/branch/jitypes2/pypy/interpreter/pyparser/error.py	Thu Dec  9 09:13:06 2010
@@ -2,19 +2,22 @@
 class SyntaxError(Exception):
     """Base class for exceptions raised by the parser."""
 
-    def __init__(self, msg, lineno=0, offset=0, text=None, filename=None):
+    def __init__(self, msg, lineno=0, offset=0, text=None, filename=None,
+                 lastlineno=0):
         self.msg = msg
         self.lineno = lineno
         self.offset = offset
         self.text = text
         self.filename = filename
+        self.lastlineno = lastlineno
 
     def wrap_info(self, space):
         return space.newtuple([space.wrap(self.msg),
                                space.newtuple([space.wrap(self.filename),
                                                space.wrap(self.lineno),
                                                space.wrap(self.offset),
-                                               space.wrap(self.text)])])
+                                               space.wrap(self.text),
+                                               space.wrap(self.lastlineno)])])
 
     def __str__(self):
         return "%s at pos (%d, %d) in %r" % (self.__class__.__name__,
@@ -33,8 +36,9 @@
 
 class TokenError(SyntaxError):
 
-    def __init__(self, msg, line, lineno, column, tokens):
-        SyntaxError.__init__(self, msg, lineno, column, line)
+    def __init__(self, msg, line, lineno, column, tokens, lastlineno=0):
+        SyntaxError.__init__(self, msg, lineno, column, line,
+                             lastlineno=lastlineno)
         self.tokens = tokens
 
 class TokenIndentationError(IndentationError):

Modified: pypy/branch/jitypes2/pypy/interpreter/pyparser/pytokenizer.py
==============================================================================
--- pypy/branch/jitypes2/pypy/interpreter/pyparser/pytokenizer.py	(original)
+++ pypy/branch/jitypes2/pypy/interpreter/pyparser/pytokenizer.py	Thu Dec  9 09:13:06 2010
@@ -78,6 +78,7 @@
     contline = None
     indents = [0]
     last_comment = ''
+    parenlevstart = (0, 0, "")
 
     # make the annotator happy
     endDFA = automata.DFA([], [])
@@ -85,7 +86,7 @@
     line = ''
     pos = 0
     lines.append("")
-    strstart = (0, 0)
+    strstart = (0, 0, "")
     for line in lines:
         lnum = lnum + 1
         pos, max = 0, len(line)
@@ -93,7 +94,8 @@
         if contstr:
             if not line:
                 raise TokenError("EOF while scanning triple-quoted string",
-                                 line, lnum-1, 0, token_list)
+                                 strstart[2], strstart[0], strstart[1]+1,
+                                 token_list, lnum)
             endmatch = endDFA.recognize(line)
             if endmatch >= 0:
                 pos = end = endmatch
@@ -146,6 +148,10 @@
 
         else:                                  # continued statement
             if not line:
+                if parenlev > 0:
+                    lnum1, start1, line1 = parenlevstart
+                    raise TokenError("parenthesis is never closed", line1,
+                                     lnum1, start1 + 1, token_list, lnum)
                 raise TokenError("EOF in multi-line statement", line,
                                  lnum, 0, token_list)
             continued = 0
@@ -187,7 +193,7 @@
                         token_list.append(tok)
                         last_comment = ''
                     else:
-                        strstart = (lnum, start)
+                        strstart = (lnum, start, line)
                         contstr = line[start:]
                         contline = line
                         break
@@ -195,7 +201,7 @@
                     token[:2] in single_quoted or \
                     token[:3] in single_quoted:
                     if token[-1] == '\n':                  # continued string
-                        strstart = (lnum, start)
+                        strstart = (lnum, start, line)
                         endDFA = (endDFAs[initial] or endDFAs[token[1]] or
                                    endDFAs[token[2]])
                         contstr, needcont = line[start:], 1
@@ -212,6 +218,8 @@
                     continued = 1
                 else:
                     if initial in '([{':
+                        if parenlev == 0:
+                            parenlevstart = (lnum, start, line)
                         parenlev = parenlev + 1
                     elif initial in ')]}':
                         parenlev = parenlev - 1
@@ -230,7 +238,7 @@
                     start = pos
                 if start<max and line[start] in single_quoted:
                     raise TokenError("EOL while scanning single-quoted string",
-                             line, lnum, start, token_list)
+                             line, lnum, start+1, token_list)
                 tok = (tokens.ERRORTOKEN, line[pos], lnum, pos, line)
                 token_list.append(tok)
                 last_comment = ''

Modified: pypy/branch/jitypes2/pypy/interpreter/pyparser/test/test_pyparse.py
==============================================================================
--- pypy/branch/jitypes2/pypy/interpreter/pyparser/test/test_pyparse.py	(original)
+++ pypy/branch/jitypes2/pypy/interpreter/pyparser/test/test_pyparse.py	Thu Dec  9 09:13:06 2010
@@ -64,12 +64,20 @@
         assert exc.lineno == 1
         assert exc.offset == 5
         assert exc.text.startswith("name another for")
-        exc = py.test.raises(SyntaxError, parse, "\"blah").value
+        exc = py.test.raises(SyntaxError, parse, "x = \"blah\n\n\n").value
         assert exc.msg == "EOL while scanning single-quoted string"
-        exc = py.test.raises(SyntaxError, parse, "'''\n").value
+        assert exc.lineno == 1
+        assert exc.offset == 5
+        exc = py.test.raises(SyntaxError, parse, "x = '''\n\n\n").value
         assert exc.msg == "EOF while scanning triple-quoted string"
+        assert exc.lineno == 1
+        assert exc.offset == 5
         for input in ("())", "(()", "((", "))"):
             py.test.raises(SyntaxError, parse, input)
+        exc = py.test.raises(SyntaxError, parse, "x = (\n\n(),\n(),").value
+        assert exc.msg == "EOF in multi-line statement"
+        assert exc.lineno == 1
+        assert exc.offset == 5
 
     def test_is(self):
         self.parse("x is y")

Modified: pypy/branch/jitypes2/pypy/interpreter/test/test_executioncontext.py
==============================================================================
--- pypy/branch/jitypes2/pypy/interpreter/test/test_executioncontext.py	(original)
+++ pypy/branch/jitypes2/pypy/interpreter/test/test_executioncontext.py	Thu Dec  9 09:13:06 2010
@@ -7,6 +7,10 @@
 
 
 class TestExecutionContext:
+    keywords = {}
+
+    def setup_class(cls):
+        cls.space = gettestobjspace(**cls.keywords)
 
     def test_action(self):
 
@@ -77,29 +81,43 @@
         assert l == ['call', 'return', 'call', 'return']
 
     def test_llprofile_c_call(self):
+        from pypy.interpreter.function import Function, Method
         l = []
+        seen = []
+        space = self.space
         
-        def profile_func(space, w_arg, frame, event, w_aarg):
+        def profile_func(space, w_arg, frame, event, w_func):
             assert w_arg is space.w_None
             l.append(event)
+            if event == 'c_call':
+                seen.append(w_func)
 
-        space = self.space
-        space.getexecutioncontext().setllprofile(profile_func, space.w_None)
-
-        def check_snippet(snippet):
+        def check_snippet(snippet, expected_c_call):
+            del l[:]
+            del seen[:]
+            space.getexecutioncontext().setllprofile(profile_func,
+                                                     space.w_None)
             space.appexec([], """():
             %s
             return
             """ % snippet)
             space.getexecutioncontext().setllprofile(None, None)
             assert l == ['call', 'return', 'call', 'c_call', 'c_return', 'return']
-
-        check_snippet('l = []; l.append(42)')
-        check_snippet('max(1, 2)')
-        check_snippet('args = (1, 2); max(*args)')
-        check_snippet('max(1, 2, **{})')
-        check_snippet('args = (1, 2); max(*args, **{})')
-        check_snippet('abs(val=0)')
+            if isinstance(seen[0], Method):
+                found = 'method %s of %s' % (
+                    seen[0].w_function.name,
+                    seen[0].w_class.getname(space, '?'))
+            else:
+                assert isinstance(seen[0], Function)
+                found = 'builtin %s' % seen[0].name
+            assert found == expected_c_call
+
+        check_snippet('l = []; l.append(42)', 'method append of list')
+        check_snippet('max(1, 2)', 'builtin max')
+        check_snippet('args = (1, 2); max(*args)', 'builtin max')
+        check_snippet('max(1, 2, **{})', 'builtin max')
+        check_snippet('args = (1, 2); max(*args, **{})', 'builtin max')
+        check_snippet('abs(val=0)', 'builtin abs')
         
     def test_llprofile_c_exception(self):
         l = []
@@ -243,6 +261,13 @@
         """)
 
 
+class TestExecutionContextWithCallLikelyBuiltin(TestExecutionContext):
+    keywords = {'objspace.opcodes.CALL_LIKELY_BUILTIN': True}
+
+class TestExecutionContextWithCallMethod(TestExecutionContext):
+    keywords = {'objspace.opcodes.CALL_METHOD': True}
+
+
 class AppTestDelNotBlocked:
 
     def setup_method(self, meth):

Modified: pypy/branch/jitypes2/pypy/interpreter/test/test_function.py
==============================================================================
--- pypy/branch/jitypes2/pypy/interpreter/test/test_function.py	(original)
+++ pypy/branch/jitypes2/pypy/interpreter/test/test_function.py	Thu Dec  9 09:13:06 2010
@@ -6,7 +6,7 @@
 from pypy.interpreter.argument import Arguments
 
 
-class AppTestFunctionIntrospection: 
+class AppTestFunctionIntrospection:
     def test_attributes(self):
         globals()['__name__'] = 'mymodulename'
         def f(): pass
@@ -88,10 +88,10 @@
         def f(*args):
             return 42
             raises(TypeError, "dir.func_code = f.func_code")
-            raises(TypeError, "list.append.im_func.func_code = f.func_code") 
+            raises(TypeError, "list.append.im_func.func_code = f.func_code")
 
 
-class AppTestFunction: 
+class AppTestFunction:
     def test_simple_call(self):
         def func(arg1, arg2):
             return arg1, arg2
@@ -116,7 +116,7 @@
         assert res[2] == 333
 
         raises(TypeError, func)
-        raises(TypeError, func, 1, 2, 3, 4)        
+        raises(TypeError, func, 1, 2, 3, 4)
 
     def test_simple_varargs(self):
         def func(arg1, *args):
@@ -127,7 +127,7 @@
 
         res = func(23, *(42,))
         assert res[0] == 23
-        assert res[1] == (42,)        
+        assert res[1] == (42,)
 
     def test_simple_kwargs(self):
         def func(arg1, **kwargs):
@@ -205,7 +205,7 @@
             func(**{'self': 23})
             assert False
         except TypeError:
-            pass        
+            pass
 
     def test_kwargs_confusing_name(self):
         def func(self):    # 'self' conflicts with the interp-level
@@ -287,7 +287,7 @@
         # on function types
         raises(ValueError, type(f).__setstate__, f, (1, 2, 3))
 
-class AppTestMethod: 
+class AppTestMethod:
     def test_simple_call(self):
         class A(object):
             def func(self, arg2):
@@ -308,7 +308,7 @@
 
         res = a.func(*(42,))
         assert res[0] is a
-        assert res[1] == (42,)        
+        assert res[1] == (42,)
 
     def test_obscure_varargs(self):
         class A(object):
@@ -321,14 +321,14 @@
 
         res = a.func(*(42,))
         assert res[0] is a
-        assert res[1] == 42        
+        assert res[1] == 42
 
     def test_simple_kwargs(self):
         class A(object):
             def func(self, **kwargs):
                 return self, kwargs
         a = A()
-            
+
         res = a.func(value=42)
         assert res[0] is a
         assert res[1] == {'value': 42}
@@ -382,19 +382,19 @@
         assert hash(C.m) == hash(D.m)
         assert hash(c.m) == hash(c.m)
 
-    def test_method_repr(self): 
-        class A(object): 
-            def f(self): 
+    def test_method_repr(self):
+        class A(object):
+            def f(self):
                 pass
         assert repr(A.f) == "<unbound method A.f>"
-        assert repr(A().f).startswith("<bound method A.f of <") 
-        assert repr(A().f).endswith(">>") 
+        assert repr(A().f).startswith("<bound method A.f of <")
+        assert repr(A().f).endswith(">>")
         class B:
             def f(self):
                 pass
         assert repr(B.f) == "<unbound method B.f>"
         assert repr(B().f).startswith("<bound method B.f of <")
-        assert repr(A().f).endswith(">>") 
+        assert repr(A().f).endswith(">>")
 
 
     def test_method_call(self):
@@ -487,14 +487,21 @@
         def f(): pass
         raises(TypeError, new.instancemethod, f, None)
 
+    def test_empty_arg_kwarg_call(self):
+        def f():
+            pass
 
-class TestMethod: 
+        raises(TypeError, lambda: f(*0))
+        raises(TypeError, lambda: f(**0))
+
+
+class TestMethod:
     def setup_method(self, method):
         def c(self, bar):
             return bar
         code = PyCode._from_code(self.space, c.func_code)
         self.fn = Function(self.space, code, self.space.newdict())
-        
+
     def test_get(self):
         space = self.space
         w_meth = descr_function_get(space, self.fn, space.wrap(5), space.type(space.wrap(5)))
@@ -552,7 +559,7 @@
 
     def test_call_function(self):
         space = self.space
-        
+
         d = {}
         for i in range(10):
             args = "(" + ''.join(["a%d," % a for a in range(i)]) + ")"
@@ -574,14 +581,14 @@
                  code.funcrun = bomb
                  code.funcrun_obj = bomb
 
-            args_w = map(space.wrap, range(i))            
+            args_w = map(space.wrap, range(i))
             w_res = space.call_function(fn, *args_w)
             check = space.is_true(space.eq(w_res, space.wrap(res)))
             assert check
 
     def test_flatcall(self):
         space = self.space
-        
+
         def f(a):
             return a
         code = PyCode._from_code(self.space, f.func_code)
@@ -608,7 +615,7 @@
 
     def test_flatcall_method(self):
         space = self.space
-        
+
         def f(self, a):
             return a
         code = PyCode._from_code(self.space, f.func_code)
@@ -636,7 +643,7 @@
 
     def test_flatcall_default_arg(self):
         space = self.space
-        
+
         def f(a, b):
             return a+b
         code = PyCode._from_code(self.space, f.func_code)
@@ -665,7 +672,7 @@
 
     def test_flatcall_default_arg_method(self):
         space = self.space
-        
+
         def f(self, a, b):
             return a+b
         code = PyCode._from_code(self.space, f.func_code)
@@ -688,7 +695,7 @@
         y = A().m(x)
         b = A().m
         z = b(x)
-        return y+10*z 
+        return y+10*z
         """)
 
         assert space.eq_w(w_res, space.wrap(44))

Modified: pypy/branch/jitypes2/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/backend/llsupport/llmodel.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/backend/llsupport/llmodel.py	Thu Dec  9 09:13:06 2010
@@ -17,7 +17,6 @@
 from pypy.jit.backend.llsupport.descr import get_call_descr
 from pypy.jit.backend.llsupport.descr import BaseIntCallDescr, GcPtrCallDescr
 from pypy.jit.backend.llsupport.descr import FloatCallDescr, VoidCallDescr
-from pypy.jit.backend.llsupport.ffisupport import get_call_descr_dynamic
 from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
 from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
 
@@ -247,7 +246,9 @@
         return get_call_descr(self.gc_ll_descr, ARGS, RESULT, extrainfo)
 
     def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo=None):
-        return get_call_descr_dynamic(ffi_args, ffi_result, extrainfo)
+        from pypy.jit.backend.llsupport import ffisupport
+        return ffisupport.get_call_descr_dynamic(ffi_args, ffi_result,
+                                                 extrainfo)
 
     def get_overflow_error(self):
         ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)

Modified: pypy/branch/jitypes2/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/backend/x86/test/test_runner.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/backend/x86/test/test_runner.py	Thu Dec  9 09:13:06 2010
@@ -82,7 +82,7 @@
         # relative addressing to work properly.
         addr = rffi.cast(lltype.Signed, addr)
         
-        self.cpu.assembler.setup()
+        self.cpu.assembler.setup_once()
         self.cpu.assembler.malloc_func_addr = addr
         ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0]
 

Modified: pypy/branch/jitypes2/pypy/jit/codewriter/regalloc.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/codewriter/regalloc.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/codewriter/regalloc.py	Thu Dec  9 09:13:06 2010
@@ -36,7 +36,7 @@
                             if isinstance(v1, Variable):
                                 die_at[v1] = i
                 if op.result is not None:
-                    die_at[op.result] = i
+                    die_at[op.result] = i + 1
             if isinstance(block.exitswitch, tuple):
                 for x in block.exitswitch:
                     die_at.pop(x, None)

Modified: pypy/branch/jitypes2/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/codewriter/test/test_regalloc.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/codewriter/test/test_regalloc.py	Thu Dec  9 09:13:06 2010
@@ -281,22 +281,22 @@
         # this used to produce bogus code, containing these two
         # lines in the following broken order:
         #    last_exc_value -> %r0
-        #    ref_copy %r0 -> %r2    -- but expect to read the old value of %r0!
+        #    ref_copy %r0 -> %r1    -- but expect to read the old value of %r0!
         self.check_assembler(graph, """
             residual_call_r_r $<* fn bar>, <Descr>, R[%r0] -> %r1
             -live-
-            residual_call_ir_r $<* fn g>, <Descr>, I[%i0], R[] -> %r2
+            residual_call_ir_r $<* fn g>, <Descr>, I[%i0], R[] -> %r1
             -live-
             catch_exception L1
-            ref_return %r2
+            ref_return %r1
             ---
             L1:
             goto_if_exception_mismatch $<* struct object_vtable>, L2
-            ref_copy %r0 -> %r2
+            ref_copy %r0 -> %r1
             last_exc_value -> %r0
             residual_call_r_r $<* fn foo>, <Descr>, R[%r0] -> %r0
             -live-
-            ref_return %r2
+            ref_return %r1
             ---
             L2:
             reraise

Modified: pypy/branch/jitypes2/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/optimizefindnode.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/optimizefindnode.py	Thu Dec  9 09:13:06 2010
@@ -128,6 +128,7 @@
         assert isinstance(constbox, Const)
         node = InstanceNode()
         node.unique = UNIQUE_NO
+        node.escaped = True
         node.knownvaluebox = constbox
         self.nodes[box] = node
         return node

Modified: pypy/branch/jitypes2/pypy/jit/metainterp/optimizeopt/__init__.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/optimizeopt/__init__.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/optimizeopt/__init__.py	Thu Dec  9 09:13:06 2010
@@ -3,7 +3,6 @@
 from pypy.jit.metainterp.optimizeopt.intbounds import OptIntBounds
 from pypy.jit.metainterp.optimizeopt.virtualize import OptVirtualize
 from pypy.jit.metainterp.optimizeopt.heap import OptHeap
-from pypy.jit.metainterp.optimizeopt.fficall import OptFfiCall
 from pypy.jit.metainterp.optimizeopt.string import OptString
 
 def optimize_loop_1(metainterp_sd, loop, virtuals=True):
@@ -17,6 +16,10 @@
                      OptVirtualize(),
                      OptString(),
                      OptHeap(),
+                    ]
+    if metainterp_sd.jit_ffi:
+        from pypy.jit.metainterp.optimizeopt.fficall import OptFfiCall
+        optimizations = optimizations + [
                      OptFfiCall(),
                     ]
     optimizer = Optimizer(metainterp_sd, loop, optimizations, virtuals)

Modified: pypy/branch/jitypes2/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/pyjitpl.py	Thu Dec  9 09:13:06 2010
@@ -1216,7 +1216,8 @@
     logger_ops = None
 
     def __init__(self, cpu, options,
-                 ProfilerClass=EmptyProfiler, warmrunnerdesc=None):
+                 ProfilerClass=EmptyProfiler, warmrunnerdesc=None,
+                 jit_ffi=True):
         self.cpu = cpu
         self.stats = self.cpu.stats
         self.options = options
@@ -1226,6 +1227,7 @@
         self.profiler = ProfilerClass()
         self.profiler.cpu = cpu
         self.warmrunnerdesc = warmrunnerdesc
+        self.jit_ffi = jit_ffi
 
         backendmodule = self.cpu.__module__
         backendmodule = backendmodule.split('.')[-2]

Modified: pypy/branch/jitypes2/pypy/jit/metainterp/test/test_compile.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/test/test_compile.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/test/test_compile.py	Thu Dec  9 09:13:06 2010
@@ -54,6 +54,7 @@
     stats = Stats()
     profiler = jitprof.EmptyProfiler()
     warmrunnerdesc = None
+    jit_ffi = False
     def log(self, msg, event_kind=None):
         pass
 

Modified: pypy/branch/jitypes2/pypy/jit/metainterp/test/test_fficall.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/test/test_fficall.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/test/test_fficall.py	Thu Dec  9 09:13:06 2010
@@ -44,6 +44,6 @@
                 n += 1
             return res
         #
-        res = self.meta_interp(f, [0])
+        res = self.meta_interp(f, [0], jit_ffi=True)
         return res
 

Modified: pypy/branch/jitypes2/pypy/jit/metainterp/test/test_optimizefficall.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/test/test_optimizefficall.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/test/test_optimizefficall.py	Thu Dec  9 09:13:06 2010
@@ -31,6 +31,7 @@
 
 
 class TestFfiCall(BaseTestOptimizeOpt, LLtypeMixin):
+    jit_ffi = True
 
     class namespace:
         cpu = LLtypeMixin.cpu

Modified: pypy/branch/jitypes2/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/test/test_optimizeopt.py	Thu Dec  9 09:13:06 2010
@@ -28,11 +28,12 @@
 
 class FakeMetaInterpStaticData(object):
 
-    def __init__(self, cpu):
+    def __init__(self, cpu, jit_ffi=False):
         self.cpu = cpu
         self.profiler = EmptyProfiler()
         self.options = Fake()
         self.globaldata = Fake()
+        self.jit_ffi = jit_ffi
 
 def test_store_final_boxes_in_guard():
     from pypy.jit.metainterp.compile import ResumeGuardDescr
@@ -227,6 +228,7 @@
     return sorted(boxes, key=lambda box: _kind2count[box.type])
 
 class BaseTestOptimizeOpt(BaseTest):
+    jit_ffi = False
 
     def invent_fail_descr(self, fail_args):
         if fail_args is None:
@@ -261,7 +263,7 @@
             loop.token.specnodes = self.unpack_specnodes(spectext)
         #
         self.loop = loop
-        metainterp_sd = FakeMetaInterpStaticData(self.cpu)
+        metainterp_sd = FakeMetaInterpStaticData(self.cpu, self.jit_ffi)
         if hasattr(self, 'vrefinfo'):
             metainterp_sd.virtualref_info = self.vrefinfo
         if hasattr(self, 'callinfocollection'):
@@ -1954,6 +1956,15 @@
         """
         self.optimize_loop(ops, 'Virtual(node_vtable2, nextdescr=Not, otherdescr=Not)', expected)
 
+    def test_bug_4(self):
+        ops = """
+        [p9]
+        p30 = new_with_vtable(ConstClass(node_vtable))
+        setfield_gc(ConstPtr(myptr), p9, descr=nextdescr)
+        jump(p30)
+        """
+        self.optimize_loop(ops, 'Not', ops)
+
     def test_invalid_loop_1(self):
         ops = """
         [p1]

Modified: pypy/branch/jitypes2/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/warmspot.py	Thu Dec  9 09:13:06 2010
@@ -144,7 +144,8 @@
 class WarmRunnerDesc(object):
 
     def __init__(self, translator, policy=None, backendopt=True, CPUClass=None,
-                 optimizer=None, ProfilerClass=EmptyProfiler, **kwds):
+                 optimizer=None, ProfilerClass=EmptyProfiler,
+                 jit_ffi=None, **kwds):
         pyjitpl._warmrunnerdesc = self   # this is a global for debugging only!
         self.set_translator(translator)
         self.memory_manager = memmgr.MemoryManager()
@@ -162,7 +163,7 @@
         elif self.opt.listops:
             self.prejit_optimizations_minimal_inline(policy, graphs)
 
-        self.build_meta_interp(ProfilerClass)
+        self.build_meta_interp(ProfilerClass, jit_ffi)
         self.make_args_specifications()
         #
         from pypy.jit.metainterp.virtualref import VirtualRefInfo
@@ -280,11 +281,14 @@
                        translate_support_code, gcdescr=self.gcdescr)
         self.cpu = cpu
 
-    def build_meta_interp(self, ProfilerClass):
+    def build_meta_interp(self, ProfilerClass, jit_ffi=None):
+        if jit_ffi is None:
+            jit_ffi = self.translator.config.translation.jit_ffi
         self.metainterp_sd = MetaInterpStaticData(self.cpu,
                                                   self.opt,
                                                   ProfilerClass=ProfilerClass,
-                                                  warmrunnerdesc=self)
+                                                  warmrunnerdesc=self,
+                                                  jit_ffi=jit_ffi)
 
     def make_virtualizable_infos(self):
         vinfos = {}

Modified: pypy/branch/jitypes2/pypy/module/_lsprof/interp_lsprof.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/_lsprof/interp_lsprof.py	(original)
+++ pypy/branch/jitypes2/pypy/module/_lsprof/interp_lsprof.py	Thu Dec  9 09:13:06 2010
@@ -163,8 +163,11 @@
     if isinstance(w_arg, Method):
         w_function = w_arg.w_function
         class_name = w_arg.w_class.getname(space, '?')
-        assert isinstance(w_function, Function)
-        return "{method '%s' of '%s' objects}" % (w_function.name, class_name)
+        if isinstance(w_function, Function):
+            name = w_function.name
+        else:
+            name = '?'
+        return "{method '%s' of '%s' objects}" % (name, class_name)
     elif isinstance(w_arg, Function):
         if w_arg.w_module is None:
             module = ''
@@ -176,7 +179,8 @@
                 module += '.'
         return '{%s%s}' % (module, w_arg.name)
     else:
-        return '{!!!unknown!!!}'
+        class_name = space.type(w_arg).getname(space, '?')
+        return "{'%s' object}" % (class_name,)
     
 def lsprof_call(space, w_self, frame, event, w_arg):
     assert isinstance(w_self, W_Profiler)

Modified: pypy/branch/jitypes2/pypy/module/_lsprof/test/test_cprofile.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/_lsprof/test/test_cprofile.py	(original)
+++ pypy/branch/jitypes2/pypy/module/_lsprof/test/test_cprofile.py	Thu Dec  9 09:13:06 2010
@@ -2,9 +2,10 @@
 from pypy.conftest import gettestobjspace, option
 
 class AppTestCProfile(object):
+    keywords = {}
 
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('_lsprof',))
+        space = gettestobjspace(usemodules=('_lsprof',), **cls.keywords)
         cls.w_expected_output = space.wrap(expected_output)
         cls.space = space
         cls.w_file = space.wrap(__file__)
@@ -148,6 +149,12 @@
         finally:
             sys.path.pop(0)
 
+
+class AppTestWithDifferentBytecodes(AppTestCProfile):
+    keywords = {'objspace.opcodes.CALL_LIKELY_BUILTIN': True,
+                'objspace.opcodes.CALL_METHOD': True}
+
+
 expected_output = {}
 expected_output['print_stats'] = """\
          126 function calls (106 primitive calls) in 1.000 CPU seconds
@@ -165,11 +172,11 @@
         2    0.000    0.000    0.140    0.070 profilee.py:84(helper2_indirect)
         8    0.312    0.039    0.400    0.050 profilee.py:88(helper2)
         8    0.064    0.008    0.080    0.010 profilee.py:98(subhelper)
-        4    0.000    0.000    0.000    0.000 {.*append.*}
+        4    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
         1    0.000    0.000    0.000    0.000 {.*disable.*}
-       12    0.000    0.000    0.012    0.001 {hasattr.*}
-        8    0.000    0.000    0.000    0.000 {range.*}
-        4    0.000    0.000    0.000    0.000 {sys.exc_info.*}
+       12    0.000    0.000    0.012    0.001 {hasattr}
+        8    0.000    0.000    0.000    0.000 {range}
+        4    0.000    0.000    0.000    0.000 {sys.exc_info}
 
 
 """

Modified: pypy/branch/jitypes2/pypy/module/_stackless/interp_coroutine.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/_stackless/interp_coroutine.py	(original)
+++ pypy/branch/jitypes2/pypy/module/_stackless/interp_coroutine.py	Thu Dec  9 09:13:06 2010
@@ -304,16 +304,19 @@
 
 def w_descr__framestack(space, self):
     assert isinstance(self, AppCoroutine)
-    index = self.subctx.framestackdepth
-    if not index:
-        return space.newtuple([])
-    items = [None] * index
+    counter = 0
     f = self.subctx.topframe
-    while index > 0:
-        index -= 1
-        items[index] = space.wrap(f)
+    while f is not None:
+        counter += 1
         f = f.f_backref()
-    assert f is None
+    items = [None] * counter
+    f = self.subctx.topframe
+    while f is not None:
+        counter -= 1
+        assert counter >= 0
+        items[counter] = space.wrap(f)
+        f = f.f_backref()
+    assert counter == 0
     return space.newtuple(items)
 
 def makeStaticMethod(module, classname, funcname):

Modified: pypy/branch/jitypes2/pypy/module/array/test/test_array.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/array/test/test_array.py	(original)
+++ pypy/branch/jitypes2/pypy/module/array/test/test_array.py	Thu Dec  9 09:13:06 2010
@@ -64,6 +64,7 @@
             raises(TypeError, self.array, tc, None)
 
     def test_value_range(self):
+        import sys
         values = (-129, 128, -128, 127, 0, 255, -1, 256,
                   -32768, 32767, -32769, 32768, 65535, 65536,
                   -2147483647, -2147483648, 2147483647, 4294967295, 4294967296,
@@ -88,7 +89,12 @@
                 a.append(v)
             for i, v in enumerate(ok * 2):
                 assert a[i] == v
-                assert type(a[i]) is pt
+                assert type(a[i]) is pt or (
+                    # A special case: we return ints in Array('I') on 64-bits,
+                    # whereas CPython returns longs.  The difference is
+                    # probably acceptable.
+                    tc == 'I' and
+                    sys.maxint > 2147483647 and type(a[i]) is int)
             for v in ok:
                 a[1] = v
                 assert a[0] == ok[0]

Modified: pypy/branch/jitypes2/pypy/module/cpyext/__init__.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/__init__.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/__init__.py	Thu Dec  9 09:13:06 2010
@@ -69,6 +69,7 @@
 import pypy.module.cpyext.weakrefobject
 import pypy.module.cpyext.funcobject
 import pypy.module.cpyext.classobject
+import pypy.module.cpyext.pypyintf
 
 # now that all rffi_platform.Struct types are registered, configure them
 api.configure_types()

Modified: pypy/branch/jitypes2/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/api.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/api.py	Thu Dec  9 09:13:06 2010
@@ -369,7 +369,7 @@
         }.items():
         GLOBALS['Py%s_Type#' % (cpyname, )] = ('PyTypeObject*', pypyexpr)
 
-    for cpyname in 'Method List Int Long Dict Class'.split():
+    for cpyname in 'Method List Int Long Dict Tuple Class'.split():
         FORWARD_DECLS.append('typedef struct { PyObject_HEAD } '
                              'Py%sObject' % (cpyname, ))
 build_exported_objects()

Modified: pypy/branch/jitypes2/pypy/module/cpyext/include/Python.h
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/include/Python.h	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/include/Python.h	Thu Dec  9 09:13:06 2010
@@ -8,6 +8,8 @@
 # include <stddef.h>
 # include <limits.h>
 # include <math.h>
+# include <errno.h>
+# include <unistd.h>
 # define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
 # define PyAPI_FUNC(RTYPE) RTYPE
 # define PyAPI_DATA(RTYPE) extern RTYPE
@@ -103,6 +105,7 @@
 #include "sliceobject.h"
 #include "datetime.h"
 #include "pystate.h"
+#include "fileobject.h"
 
 // XXX This shouldn't be included here
 #include "structmember.h"
@@ -120,4 +123,8 @@
 #define PyDoc_STR(str) ""
 #endif
 
+/* PyPy does not implement --with-fpectl */
+#define PyFPE_START_PROTECT(err_string, leave_stmt)
+#define PyFPE_END_PROTECT(v)
+
 #endif

Modified: pypy/branch/jitypes2/pypy/module/cpyext/include/tupleobject.h
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/include/tupleobject.h	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/include/tupleobject.h	Thu Dec  9 09:13:06 2010
@@ -10,19 +10,9 @@
 /* defined in varargswrapper.c */
 PyObject * PyTuple_Pack(Py_ssize_t, ...);
 
-typedef struct {
-    PyObject_HEAD
-    PyObject **items;
-    Py_ssize_t size;
-} PyTupleObject;
+#define PyTuple_SET_ITEM PyTuple_SetItem
+#define PyTuple_GET_ITEM PyTuple_GetItem
 
-#define PyTuple_GET_ITEM        PyTuple_GetItem
-
-/* Macro, trading safety for speed */
-#define PyTuple_GET_SIZE(op)    (((PyTupleObject *)(op))->size)
-
-/* Macro, *only* to be used to fill in brand new tuples */
-#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->items[i] = v)
 
 #ifdef __cplusplus
 }

Modified: pypy/branch/jitypes2/pypy/module/cpyext/intobject.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/intobject.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/intobject.py	Thu Dec  9 09:13:06 2010
@@ -1,5 +1,6 @@
 
 from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.api import (cpython_api, PyObject, CANNOT_FAIL,
                                     build_type_checkers, Py_ssize_t)
 
@@ -19,6 +20,9 @@
     already one, and then return its value. If there is an error, -1 is
     returned, and the caller should check PyErr_Occurred() to find out whether
     there was an error, or whether the value just happened to be -1."""
+    if w_obj is None:
+        raise OperationError(space.w_TypeError,
+                             space.wrap("an integer is required, got NULL"))
     return space.int_w(space.int(w_obj))
 
 @cpython_api([PyObject], lltype.Unsigned, error=-1)
@@ -26,6 +30,9 @@
     """Return a C unsigned long representation of the contents of pylong.
     If pylong is greater than ULONG_MAX, an OverflowError is
     raised."""
+    if w_obj is None:
+        raise OperationError(space.w_TypeError,
+                             space.wrap("an integer is required, got NULL"))
     return space.uint_w(space.int(w_obj))
 
 @cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL)
@@ -39,6 +46,9 @@
     PyLongObject, if it is not already one, and then return its value as
     Py_ssize_t.
     """
+    if w_obj is None:
+        raise OperationError(space.w_TypeError,
+                             space.wrap("an integer is required, got NULL"))
     return space.int_w(w_obj) # XXX this is wrong on win64
 
 @cpython_api([Py_ssize_t], PyObject)
@@ -48,4 +58,3 @@
     returned.
     """
     return space.wrap(ival) # XXX this is wrong on win64
-

Modified: pypy/branch/jitypes2/pypy/module/cpyext/object.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/object.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/object.py	Thu Dec  9 09:13:06 2010
@@ -2,12 +2,13 @@
 from pypy.module.cpyext.api import (
     cpython_api, generic_cpy_call, CANNOT_FAIL, Py_ssize_t, Py_ssize_tP,
     PyVarObject, Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
-    Py_GE, CONST_STRING, FILEP, fwrite)
+    Py_GE, CONST_STRING, FILEP, fwrite, build_type_checkers)
 from pypy.module.cpyext.pyobject import (
     PyObject, PyObjectP, create_ref, from_ref, Py_IncRef, Py_DecRef,
     track_reference, get_typedescr, RefcountState)
 from pypy.module.cpyext.typeobject import PyTypeObjectPtr
 from pypy.module.cpyext.pyerrors import PyErr_NoMemory, PyErr_BadInternalCall
+from pypy.module._file.interp_file import W_File
 from pypy.objspace.std.objectobject import W_ObjectObject
 from pypy.objspace.std.typeobject import W_TypeObject
 from pypy.interpreter.error import OperationError
@@ -428,6 +429,34 @@
         rffi.free_nonmovingbuffer(data, buf)
     return 0
 
+PyFile_Check, PyFile_CheckExact = build_type_checkers("File", W_File)
+
+ at cpython_api([PyObject, rffi.INT_real], PyObject)
+def PyFile_GetLine(space, w_obj, n):
+    """
+    Equivalent to p.readline([n]), this function reads one line from the
+    object p.  p may be a file object or any object with a readline()
+    method.  If n is 0, exactly one line is read, regardless of the length of
+    the line.  If n is greater than 0, no more than n bytes will be read
+    from the file; a partial line can be returned.  In both cases, an empty string
+    is returned if the end of the file is reached immediately.  If n is less than
+    0, however, one line is read regardless of length, but EOFError is
+    raised if the end of the file is reached immediately."""
+    try:
+        w_readline = space.getattr(w_obj, space.wrap('readline'))
+    except OperationError:
+        raise OperationError(
+            space.w_TypeError, space.wrap(
+            "argument must be a file, or have a readline() method."))
+
+    n = rffi.cast(lltype.Signed, n)
+    if space.is_true(space.gt(space.wrap(n), space.wrap(0))):
+        return space.call_function(w_readline, space.wrap(n))
+    elif space.is_true(space.lt(space.wrap(n), space.wrap(0))):
+        return space.call_function(w_readline)
+    else:
+        # XXX Raise EOFError as specified
+        return space.call_function(w_readline)
 @cpython_api([CONST_STRING, CONST_STRING], PyObject)
 def PyFile_FromString(space, filename, mode):
     """
@@ -437,4 +466,3 @@
     w_filename = space.wrap(rffi.charp2str(filename))
     w_mode = space.wrap(rffi.charp2str(mode))
     return space.call_method(space.builtin, 'file', w_filename, w_mode)
-

Modified: pypy/branch/jitypes2/pypy/module/cpyext/pyerrors.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/pyerrors.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/pyerrors.py	Thu Dec  9 09:13:06 2010
@@ -5,7 +5,7 @@
 from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, CONST_STRING
 from pypy.module.exceptions.interp_exceptions import W_RuntimeWarning
 from pypy.module.cpyext.pyobject import (
-    PyObject, PyObjectP, make_ref, Py_DecRef, borrow_from)
+    PyObject, PyObjectP, make_ref, from_ref, Py_DecRef, borrow_from)
 from pypy.module.cpyext.state import State
 from pypy.module.cpyext.import_ import PyImport_Import
 from pypy.rlib.rposix import get_errno
@@ -80,6 +80,21 @@
     Py_DecRef(space, w_value)
     Py_DecRef(space, w_traceback)
 
+ at cpython_api([PyObjectP, PyObjectP, PyObjectP], lltype.Void)
+def PyErr_NormalizeException(space, exc_p, val_p, tb_p):
+    """Under certain circumstances, the values returned by PyErr_Fetch() below
+    can be "unnormalized", meaning that *exc is a class object but *val is
+    not an instance of the  same class.  This function can be used to instantiate
+    the class in that case.  If the values are already normalized, nothing happens.
+    The delayed normalization is implemented to improve performance."""
+    operr = OperationError(from_ref(space, exc_p[0]),
+                           from_ref(space, val_p[0]))
+    operr.normalize_exception(space)
+    Py_DecRef(space, exc_p[0])
+    Py_DecRef(space, val_p[0])
+    exc_p[0] = make_ref(space, operr.w_type)
+    val_p[0] = make_ref(space, operr.get_w_value(space))
+
 @cpython_api([], lltype.Void)
 def PyErr_BadArgument(space):
     """This is a shorthand for PyErr_SetString(PyExc_TypeError, message), where
@@ -114,10 +129,29 @@
     function around a system call can write return PyErr_SetFromErrno(type);
     when the system call returns an error.
     Return value: always NULL."""
+    PyErr_SetFromErrnoWithFilename(space, w_type,
+                                   lltype.nullptr(rffi.CCHARP.TO))
+
+ at cpython_api([PyObject, rffi.CCHARP], PyObject)
+def PyErr_SetFromErrnoWithFilename(space, w_type, llfilename):
+    """Similar to PyErr_SetFromErrno(), with the additional behavior that if
+    filename is not NULL, it is passed to the constructor of type as a third
+    parameter.  In the case of exceptions such as IOError and OSError,
+    this is used to define the filename attribute of the exception instance.
+    Return value: always NULL."""
     # XXX Doesn't actually do anything with PyErr_CheckSignals.
     errno = get_errno()
     msg = os.strerror(errno)
-    w_error = space.call_function(w_type, space.wrap(errno), space.wrap(msg))
+    if llfilename:
+        w_filename = rffi.charp2str(llfilename)
+        w_error = space.call_function(w_type,
+                                      space.wrap(errno),
+                                      space.wrap(msg),
+                                      space.wrap(w_filename))
+    else:
+        w_error = space.call_function(w_type,
+                                      space.wrap(errno),
+                                      space.wrap(msg))
     raise OperationError(w_type, w_error)
 
 @cpython_api([], rffi.INT_real, error=-1)

Modified: pypy/branch/jitypes2/pypy/module/cpyext/pythonrun.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/pythonrun.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/pythonrun.py	Thu Dec  9 09:13:06 2010
@@ -1,6 +1,16 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.state import State
 
 @cpython_api([], rffi.INT_real, error=CANNOT_FAIL)
 def Py_IsInitialized(space):
     return 1
+
+ at cpython_api([], rffi.CCHARP, error=CANNOT_FAIL)
+def Py_GetProgramName(space):
+    """
+    Return the program name set with Py_SetProgramName(), or the default.
+    The returned string points into static storage; the caller should not modify its
+    value."""
+    return space.fromcache(State).get_programname()
+

Modified: pypy/branch/jitypes2/pypy/module/cpyext/slotdefs.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/slotdefs.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/slotdefs.py	Thu Dec  9 09:13:06 2010
@@ -28,14 +28,14 @@
 
 def check_num_args(space, ob, n):
     from pypy.module.cpyext.tupleobject import PyTuple_CheckExact, \
-            _PyTuple_Size_Fast
+            PyTuple_GET_SIZE
     if not PyTuple_CheckExact(space, ob):
         raise OperationError(space.w_SystemError,
             space.wrap("PyArg_UnpackTuple() argument list is not a tuple"))
-    if n == _PyTuple_Size_Fast(space, ob):
+    if n == PyTuple_GET_SIZE(space, ob):
         return
     raise operationerrfmt(space.w_TypeError,
-        "expected %d arguments, got %d", n, _PyTuple_Size_Fast(space, ob))
+        "expected %d arguments, got %d", n, PyTuple_GET_SIZE(space, ob))
 
 def wrap_init(space, w_self, w_args, func, w_kwargs):
     func_init = rffi.cast(initproc, func)

Modified: pypy/branch/jitypes2/pypy/module/cpyext/src/getargs.c
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/src/getargs.c	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/src/getargs.c	Thu Dec  9 09:13:06 2010
@@ -453,6 +453,7 @@
 			strncpy(msgbuf, "is not retrievable", bufsize);
 			return msgbuf;
 		}
+                PyPy_Borrow(arg, item);
 		msg = convertitem(item, &format, p_va, flags, levels+1, 
 				  msgbuf, bufsize, freelist);
 		/* PySequence_GetItem calls tp->sq_item, which INCREFs */

Modified: pypy/branch/jitypes2/pypy/module/cpyext/state.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/state.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/state.py	Thu Dec  9 09:13:06 2010
@@ -8,6 +8,7 @@
     def __init__(self, space):
         self.space = space
         self.reset()
+        self.programname = lltype.nullptr(rffi.CCHARP.TO)
 
     def reset(self):
         from pypy.module.cpyext.modsupport import PyMethodDef
@@ -41,3 +42,16 @@
         if always:
             raise OperationError(self.space.w_SystemError, self.space.wrap(
                 "Function returned an error result without setting an exception"))
+
+    def get_programname(self):
+        if not self.programname:
+            space = self.space
+            argv = space.sys.get('argv')
+            if space.int_w(space.len(argv)):
+                argv0 = space.getitem(argv, space.wrap(0))
+                progname = space.str_w(argv0)
+            else:
+                progname = "pypy"
+            self.programname = rffi.str2charp(progname)
+            lltype.render_immortal(self.programname)
+        return self.programname

Modified: pypy/branch/jitypes2/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/stubs.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/stubs.py	Thu Dec  9 09:13:06 2010
@@ -668,24 +668,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObjectP, PyObjectP, PyObjectP], lltype.Void)
-def PyErr_NormalizeException(space, exc, val, tb):
-    """Under certain circumstances, the values returned by PyErr_Fetch() below
-    can be "unnormalized", meaning that *exc is a class object but *val is
-    not an instance of the  same class.  This function can be used to instantiate
-    the class in that case.  If the values are already normalized, nothing happens.
-    The delayed normalization is implemented to improve performance."""
-    raise NotImplementedError
-
- at cpython_api([PyObject, rffi.CCHARP], PyObject)
-def PyErr_SetFromErrnoWithFilename(space, type, filename):
-    """Similar to PyErr_SetFromErrno(), with the additional behavior that if
-    filename is not NULL, it is passed to the constructor of type as a third
-    parameter.  In the case of exceptions such as IOError and OSError,
-    this is used to define the filename attribute of the exception instance.
-    Return value: always NULL."""
-    raise NotImplementedError
-
 @cpython_api([rffi.INT_real], PyObject)
 def PyErr_SetFromWindowsErr(space, ierr):
     """This is a convenience function to raise WindowsError. If called with
@@ -809,21 +791,6 @@
     successful invocation of Py_EnterRecursiveCall()."""
     raise NotImplementedError
 
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyFile_Check(space, p):
-    """Return true if its argument is a PyFileObject or a subtype of
-    PyFileObject.
-    
-    Allowed subtypes to be accepted."""
-    raise NotImplementedError
-
- at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyFile_CheckExact(space, p):
-    """Return true if its argument is a PyFileObject, but not a subtype of
-    PyFileObject.
-    """
-    raise NotImplementedError
-
 @cpython_api([FILE, rffi.CCHARP, rffi.CCHARP, rffi.INT_real], PyObject)
 def PyFile_FromFile(space, fp, name, mode, close):
     """Create a new PyFileObject from the already-open standard C file
@@ -857,22 +824,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject, rffi.INT_real], PyObject)
-def PyFile_GetLine(space, p, n):
-    """
-    
-    
-    
-    Equivalent to p.readline([n]), this function reads one line from the
-    object p.  p may be a file object or any object with a readline()
-    method.  If n is 0, exactly one line is read, regardless of the length of
-    the line.  If n is greater than 0, no more than n bytes will be read
-    from the file; a partial line can be returned.  In both cases, an empty string
-    is returned if the end of the file is reached immediately.  If n is less than
-    0, however, one line is read regardless of length, but EOFError is
-    raised if the end of the file is reached immediately."""
-    raise NotImplementedError
-
 @cpython_api([PyObject], PyObject)
 def PyFile_Name(space, p):
     """Return the name of the file specified by p as a string object."""
@@ -1431,17 +1382,6 @@
     raise NotImplementedError
 
 @cpython_api([], rffi.CCHARP, error=CANNOT_FAIL)
-def Py_GetProgramName(space, ):
-    """
-    
-    
-    
-    Return the program name set with Py_SetProgramName(), or the default.
-    The returned string points into static storage; the caller should not modify its
-    value."""
-    raise NotImplementedError
-
- at cpython_api([], rffi.CCHARP, error=CANNOT_FAIL)
 def Py_GetPrefix(space, ):
     """Return the prefix for installed platform-independent files. This is derived
     through a number of complicated rules from the program name set with

Modified: pypy/branch/jitypes2/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/test/test_cpyext.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/test/test_cpyext.py	Thu Dec  9 09:13:06 2010
@@ -545,17 +545,16 @@
             PyObject *true = Py_True;
             PyObject *tup = NULL;
             int refcnt = true->ob_refcnt;
-            int refcnt_middle, refcnt_after;
+            int refcnt_after;
 
             tup = PyTuple_New(1);
             Py_INCREF(true);
             if (PyTuple_SetItem(tup, 0, true) < 0)
                 return NULL;
-            refcnt_middle = true->ob_refcnt;
-            Py_DECREF(tup);
             refcnt_after = true->ob_refcnt;
-            fprintf(stderr, "REFCNT2 %i %i %i\\n", refcnt, refcnt_middle, refcnt_after);
-            return PyBool_FromLong(refcnt_after == refcnt && refcnt_middle == refcnt+1);
+            Py_DECREF(tup);
+            fprintf(stderr, "REFCNT2 %i %i\\n", refcnt, refcnt_after);
+            return PyBool_FromLong(refcnt_after == refcnt);
         }
 
         static PyMethodDef methods[] = {
@@ -683,3 +682,19 @@
         assert mod.get_names() == ('cell', 'module', 'property',
                                    'staticmethod',
                                    'builtin_function_or_method')
+
+    def test_get_programname(self):
+        mod = self.import_extension('foo', [
+            ('get_programname', 'METH_NOARGS',
+             '''
+             char* name1 = Py_GetProgramName();
+             char* name2 = Py_GetProgramName();
+             if (name1 != name2)
+                 Py_RETURN_FALSE;
+             return PyString_FromString(name1);
+             '''
+             ),
+            ])
+        p = mod.get_programname()
+        print p
+        assert 'py' in p

Modified: pypy/branch/jitypes2/pypy/module/cpyext/test/test_intobject.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/test/test_intobject.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/test/test_intobject.py	Thu Dec  9 09:13:06 2010
@@ -19,6 +19,10 @@
         assert api.PyErr_Occurred() is space.w_TypeError
         api.PyErr_Clear()
 
+        assert api.PyInt_AsLong(None) == -1
+        assert api.PyErr_Occurred() is space.w_TypeError
+        api.PyErr_Clear()
+
         assert api.PyInt_AsUnsignedLong(space.wrap(sys.maxint)) == sys.maxint
         assert api.PyInt_AsUnsignedLong(space.wrap(-5)) == sys.maxint * 2 + 1
         assert api.PyErr_Occurred() is space.w_ValueError

Modified: pypy/branch/jitypes2/pypy/module/cpyext/test/test_object.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/test/test_object.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/test/test_object.py	Thu Dec  9 09:13:06 2010
@@ -4,7 +4,7 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import Py_LT, Py_LE, Py_NE, Py_EQ,\
-    Py_GE, Py_GT
+    Py_GE, Py_GT, fopen, fclose, fwrite
 from pypy.tool.udir import udir
 
 class TestObject(BaseApiTest):
@@ -188,10 +188,45 @@
         rffi.free_charp(filename)
         rffi.free_charp(mode)
 
+        assert api.PyFile_Check(w_file)
+        assert api.PyFile_CheckExact(w_file)
+        assert not api.PyFile_Check(space.wrap("text"))
+
         space.call_method(w_file, "write", space.wrap("text"))
         space.call_method(w_file, "close")
         assert (udir / "_test_file").read() == "text"
 
+    def test_file_getline(self, space, api):
+        filename = rffi.str2charp(str(udir / "_test_file"))
+
+        mode = rffi.str2charp("w")
+        w_file = api.PyFile_FromString(filename, mode)
+        space.call_method(w_file, "write",
+                          space.wrap("line1\nline2\nline3\nline4"))
+        space.call_method(w_file, "close")
+
+        rffi.free_charp(mode)
+        mode = rffi.str2charp("r")
+        w_file = api.PyFile_FromString(filename, mode)
+        rffi.free_charp(filename)
+        rffi.free_charp(mode)
+
+        w_line = api.PyFile_GetLine(w_file, 0)
+        assert space.str_w(w_line) == "line1\n"
+
+        w_line = api.PyFile_GetLine(w_file, 4)
+        assert space.str_w(w_line) == "line"
+
+        w_line = api.PyFile_GetLine(w_file, 0)
+        assert space.str_w(w_line) == "2\n"
+
+        # XXX We ought to raise an EOFError here, but don't
+        w_line = api.PyFile_GetLine(w_file, -1)
+        # assert api.PyErr_Occurred() is space.w_EOFError
+        assert space.str_w(w_line) == "line3\n"
+
+        space.call_method(w_file, "close")
+
 class AppTestObject(AppTestCpythonExtensionBase):
     def setup_class(cls):
         AppTestCpythonExtensionBase.setup_class.im_func(cls)

Modified: pypy/branch/jitypes2/pypy/module/cpyext/test/test_pyerrors.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/test/test_pyerrors.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/test/test_pyerrors.py	Thu Dec  9 09:13:06 2010
@@ -129,6 +129,41 @@
             ])
         assert module.check_error()
 
+
+    def test_normalize(self):
+        module = self.import_extension('foo', [
+            ("check_error", "METH_NOARGS",
+             '''
+             PyObject *type, *val, *tb;
+             PyErr_SetString(PyExc_TypeError, "message");
+
+             PyErr_Fetch(&type, &val, &tb);
+             if (type != PyExc_TypeError)
+                 Py_RETURN_FALSE;
+             if (!PyString_Check(val))
+                 Py_RETURN_FALSE;
+             /* Normalize */
+             PyErr_NormalizeException(&type, &val, &tb);
+             if (type != PyExc_TypeError)
+                 Py_RETURN_FALSE;
+             if (val->ob_type != PyExc_TypeError)
+                 Py_RETURN_FALSE;
+
+             /* Normalize again */
+             PyErr_NormalizeException(&type, &val, &tb);
+             if (type != PyExc_TypeError)
+                 Py_RETURN_FALSE;
+             if (val->ob_type != PyExc_TypeError)
+                 Py_RETURN_FALSE;
+
+             PyErr_Restore(type, val, tb);
+             PyErr_Clear();
+             Py_RETURN_TRUE;
+             '''
+             ),
+            ])
+        assert module.check_error()
+
     def test_SetFromErrno(self):
         import sys
         if sys.platform != 'win32':
@@ -149,3 +184,26 @@
         except OSError, e:
             assert e.errno == errno.EBADF
             assert e.strerror == os.strerror(errno.EBADF)
+            assert e.filename == None
+
+    def test_SetFromErrnoWithFilename(self):
+        import sys
+        if sys.platform != 'win32':
+            skip("callbacks through ll2ctypes modify errno")
+        import errno, os
+
+        module = self.import_extension('foo', [
+                ("set_from_errno", "METH_NOARGS",
+                 '''
+                 errno = EBADF;
+                 PyErr_SetFromErrnoWithFilename(PyExc_OSError, "blyf");
+                 return NULL;
+                 '''),
+                ],
+                prologue="#include <errno.h>")
+        try:
+            module.set_from_errno()
+        except OSError, e:
+            assert e.filename == "blyf"
+            assert e.errno == errno.EBADF
+            assert e.strerror == os.strerror(errno.EBADF)

Modified: pypy/branch/jitypes2/pypy/module/cpyext/test/test_tupleobject.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/test/test_tupleobject.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/test/test_tupleobject.py	Thu Dec  9 09:13:06 2010
@@ -7,34 +7,24 @@
 class TestTupleObject(BaseApiTest):
     def test_tupleobject(self, space, api):
         assert not api.PyTuple_Check(space.w_None)
-        #assert api.PyTuple_SetItem(space.w_None, 0, space.w_None) == -1     XXX
+        assert api.PyTuple_SetItem(space.w_None, 0, space.w_None) == -1
         atuple = space.newtuple([0, 1, 'yay'])
         assert api.PyTuple_Size(atuple) == 3
-        #raises(TypeError, api.PyTuple_Size(space.newlist([])))     XXX
+        assert api.PyTuple_GET_SIZE(atuple) == 3
+        raises(TypeError, api.PyTuple_Size(space.newlist([])))
         api.PyErr_Clear()
     
     def test_tuple_resize(self, space, api):
-        ref_tup = api.PyTuple_New(3)
+        py_tuple = api.PyTuple_New(3)
         ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
-        ar[0] = rffi.cast(PyObject, ref_tup)
+        ar[0] = rffi.cast(PyObject, make_ref(space, py_tuple))
         api._PyTuple_Resize(ar, 2)
-        assert ar[0] == rffi.cast(PyObject, ref_tup)
-        # ^^^ our _PyTuple_Resize does not actually need to change the ptr so far
-        assert api.PyTuple_Size(ar[0]) == 2
+        py_tuple = from_ref(space, ar[0])
+        assert len(py_tuple.wrappeditems) == 2
         
         api._PyTuple_Resize(ar, 10)
-        assert api.PyTuple_Size(ar[0]) == 10
+        py_tuple = from_ref(space, ar[0])
+        assert len(py_tuple.wrappeditems) == 10
         
         api.Py_DecRef(ar[0])
         lltype.free(ar, flavor='raw')
-
-    def test_tuple_setup(self, space, api):
-        ref_tup = api.PyTuple_New(2)
-        ref0 = make_ref(space, space.wrap(123))
-        api.PyTuple_SetItem(ref_tup, 0, ref0)
-        ref1 = make_ref(space, space.wrap(456))
-        api.PyTuple_SetItem(ref_tup, 1, ref1)
-
-        w_tup = from_ref(space, ref_tup)
-        assert space.is_true(space.eq(w_tup, space.wrap((123, 456))))
-        api.Py_DecRef(ref_tup)

Modified: pypy/branch/jitypes2/pypy/module/cpyext/tupleobject.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/cpyext/tupleobject.py	(original)
+++ pypy/branch/jitypes2/pypy/module/cpyext/tupleobject.py	Thu Dec  9 09:13:06 2010
@@ -1,144 +1,55 @@
 from pypy.interpreter.error import OperationError
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL,
-                                    build_type_checkers, PyObjectFields,
-                                    cpython_struct, bootstrap_function)
+                                    build_type_checkers)
 from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, Py_DecRef,
-    borrow_from, make_ref, from_ref, make_typedescr, get_typedescr, Reference,
-    track_reference)
+    borrow_from, make_ref, from_ref)
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
+from pypy.objspace.std.tupleobject import W_TupleObject
 
-##
-## Implementation of PyTupleObject
-## ===============================
-##
-## We have the same problem as PyStringObject: a PyTupleObject can be
-## initially used in a read-write way with PyTuple_New(), PyTuple_SetItem()
-## and _PyTuple_Resize().
-##
-## The 'size' and 'items' fields of a PyTupleObject are always valid.
-## Apart from that detail, see the big comment in stringobject.py for
-## more information.
-##
-
-ARRAY_OF_PYOBJ = rffi.CArrayPtr(PyObject)
-PyTupleObjectStruct = lltype.ForwardReference()
-PyTupleObject = lltype.Ptr(PyTupleObjectStruct)
-PyTupleObjectFields = PyObjectFields + \
-    (("items", ARRAY_OF_PYOBJ), ("size", Py_ssize_t))
-cpython_struct("PyTupleObject", PyTupleObjectFields, PyTupleObjectStruct)
-
- at bootstrap_function
-def init_tupleobject(space):
-    "Type description of PyTupleObject"
-    make_typedescr(space.w_tuple.instancetypedef,
-                   basestruct=PyTupleObject.TO,
-                   attach=tuple_attach,
-                   dealloc=tuple_dealloc,
-                   realize=tuple_realize)
 
 PyTuple_Check, PyTuple_CheckExact = build_type_checkers("Tuple")
 
-def new_empty_tuple(space, length):
-    """
-    Allocate a PyTupleObject and its array, but without a corresponding
-    interpreter object.  The array items may be mutated, until
-    tuple_realize() is called.
-    """
-    typedescr = get_typedescr(space.w_tuple.instancetypedef)
-    py_obj = typedescr.allocate(space, space.w_tuple)
-    py_tup = rffi.cast(PyTupleObject, py_obj)
-
-    py_tup.c_items = lltype.malloc(ARRAY_OF_PYOBJ.TO, length,
-                                   flavor='raw', zero=True)
-    py_tup.c_size = length
-    return py_tup
-
-def tuple_attach(space, py_obj, w_obj):
-    """
-    Fills a newly allocated PyTupleObject with the given tuple object.
-    """
-    items_w = space.fixedview(w_obj)
-    py_tup = rffi.cast(PyTupleObject, py_obj)
-    py_tup.c_items = lltype.nullptr(ARRAY_OF_PYOBJ.TO)
-    py_tup.c_size = len(items_w)
-
-def tuple_realize(space, py_obj):
-    """
-    Creates the tuple in the interpreter. The PyTupleObject items array
-    must not be modified after this call.
-    """
-    py_tup = rffi.cast(PyTupleObject, py_obj)
-    # If your CPython extension creates a self-referential tuple
-    # with PyTuple_SetItem(), you loose.
-    c_items = py_tup.c_items
-    items_w = [from_ref(space, c_items[i]) for i in range(py_tup.c_size)]
-    w_obj = space.newtuple(items_w)
-    track_reference(space, py_obj, w_obj)
-    return w_obj
-
- at cpython_api([PyObject], lltype.Void, external=False)
-def tuple_dealloc(space, py_obj):
-    """Frees allocated PyTupleObject resources.
-    """
-    py_tup = rffi.cast(PyTupleObject, py_obj)
-    if py_tup.c_items:
-        for i in range(py_tup.c_size):
-            Py_DecRef(space, py_tup.c_items[i])
-        lltype.free(py_tup.c_items, flavor="raw")
-    from pypy.module.cpyext.object import PyObject_dealloc
-    PyObject_dealloc(space, py_obj)
-
-#_______________________________________________________________________
-
 @cpython_api([Py_ssize_t], PyObject)
 def PyTuple_New(space, size):
-    return rffi.cast(PyObject, new_empty_tuple(space, size))
+    return space.newtuple([space.w_None] * size)
 
 @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
-def PyTuple_SetItem(space, ref, pos, ref_item):
-    # XXX steals a reference at the level of PyObjects.  Don't try to
-    # XXX call this function with an interpreter object as ref_item!
-
-    # XXX do PyTuple_Check, without forcing ref as an interpreter object
-    # XXX -- then if it fails it should also steal a reference, test it!!!
-    ref_tup = rffi.cast(PyTupleObject, ref)
-    if not ref_tup.c_items:
-        msg = "PyTuple_SetItem() called on an already-escaped tuple object"
-        raise OperationError(space.w_SystemError, space.wrap(msg))
-    ref_old = ref_tup.c_items[pos]
-    ref_tup.c_items[pos] = ref_item      # SetItem steals a reference!
-    Py_DecRef(space, ref_old)
+def PyTuple_SetItem(space, w_t, pos, w_obj):
+    if not PyTuple_Check(space, w_t):
+        # XXX this should also steal a reference, test it!!!
+        PyErr_BadInternalCall(space)
+    assert isinstance(w_t, W_TupleObject)
+    w_t.wrappeditems[pos] = w_obj
+    Py_DecRef(space, w_obj) # SetItem steals a reference!
     return 0
 
 @cpython_api([PyObject, Py_ssize_t], PyObject)
-def PyTuple_GetItem(space, ref, pos):
-    # XXX do PyTuple_Check, without forcing ref as an interpreter object
-    ref_tup = rffi.cast(PyTupleObject, ref)
-    if ref_tup.c_items:
-        return Reference(ref_tup.c_items[pos])     # borrowed reference
-    else:
-        w_t = from_ref(space, ref)
-        w_obj = space.getitem(w_t, space.wrap(pos))
-        return borrow_from(w_t, w_obj)
-
- at cpython_api([PyObject], Py_ssize_t, error=-1)
-def _PyTuple_Size_Fast(space, ref):
-    # custom version: it's not a macro, so it can be called from other .py
-    # files; but it doesn't include PyTuple_Check()
-    ref_tup = rffi.cast(PyTupleObject, ref)
-    return ref_tup.c_size
+def PyTuple_GetItem(space, w_t, pos):
+    if not PyTuple_Check(space, w_t):
+        PyErr_BadInternalCall(space)
+    assert isinstance(w_t, W_TupleObject)
+    w_obj = w_t.wrappeditems[pos]
+    return borrow_from(w_t, w_obj)
+
+ at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+def PyTuple_GET_SIZE(space, w_t):
+    """Return the size of the tuple p, which must be non-NULL and point to a tuple;
+    no error checking is performed. """
+    assert isinstance(w_t, W_TupleObject)
+    return len(w_t.wrappeditems)
 
 @cpython_api([PyObject], Py_ssize_t, error=-1)
 def PyTuple_Size(space, ref):
     """Take a pointer to a tuple object, and return the size of that tuple."""
-    # XXX do PyTuple_Check, without forcing ref as an interpreter object
-    ref_tup = rffi.cast(PyTupleObject, ref)
-    return ref_tup.c_size
+    if not PyTuple_Check(space, ref):
+        raise OperationError(space.w_TypeError,
+                             space.wrap("expected tuple object"))
+    return PyTuple_GET_SIZE(space, ref)
 
 
 @cpython_api([PyObjectP, Py_ssize_t], rffi.INT_real, error=-1)
-def _PyTuple_Resize(space, refp, newsize):
+def _PyTuple_Resize(space, ref, newsize):
     """Can be used to resize a tuple.  newsize will be the new length of the tuple.
     Because tuples are supposed to be immutable, this should only be used if there
     is only one reference to the object.  Do not use this if the tuple may already
@@ -149,22 +60,18 @@
     this function. If the object referenced by *p is replaced, the original
     *p is destroyed.  On failure, returns -1 and sets *p to NULL, and
     raises MemoryError or SystemError."""
-    # XXX do PyTuple_Check, without forcing ref as an interpreter object
-    # XXX -- then if it fails it should reset refp[0] to null
-    ref_tup = rffi.cast(PyTupleObject, refp[0])
-    c_newitems = lltype.malloc(ARRAY_OF_PYOBJ.TO, newsize,
-                               flavor='raw', zero=True)
-    c_olditems = ref_tup.c_items
-    if not c_olditems:
-        msg = "_PyTuple_Resize() called on an already-escaped tuple object"
-        raise OperationError(space.w_SystemError, space.wrap(msg))
-    oldsize = ref_tup.c_size
-    for i in range(min(oldsize, newsize)):
-        c_newitems[i] = c_olditems[i]
-    # decref items deleted by shrinkage
-    for i in range(newsize, oldsize):
-        Py_DecRef(space, c_olditems[i])
-    ref_tup.c_items = c_newitems
-    ref_tup.c_size = newsize
-    lltype.free(c_olditems, flavor='raw')
+    py_tuple = from_ref(space, ref[0])
+    if not PyTuple_Check(space, py_tuple):
+        PyErr_BadInternalCall(space)
+    assert isinstance(py_tuple, W_TupleObject)
+    py_newtuple = PyTuple_New(space, newsize)
+    
+    to_cp = newsize
+    oldsize = len(py_tuple.wrappeditems)
+    if oldsize < newsize:
+        to_cp = oldsize
+    for i in range(to_cp):
+        py_newtuple.wrappeditems[i] = py_tuple.wrappeditems[i]
+    Py_DecRef(space, ref[0])
+    ref[0] = make_ref(space, py_newtuple)
     return 0

Modified: pypy/branch/jitypes2/pypy/module/exceptions/interp_exceptions.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/exceptions/interp_exceptions.py	(original)
+++ pypy/branch/jitypes2/pypy/module/exceptions/interp_exceptions.py	Thu Dec  9 09:13:06 2010
@@ -452,6 +452,7 @@
         self.w_text     = space.w_None
         self.w_msg      = space.wrap('')
         self.w_print_file_and_line = space.w_None # what's that?
+        self.w_lastlineno = space.w_None          # this is a pypy extension
         W_BaseException.__init__(self, space)
 
     def descr_init(self, space, args_w):
@@ -459,11 +460,12 @@
         if len(args_w) > 0:
             self.w_msg = args_w[0]
         if len(args_w) == 2:
-            values_w = space.fixedview(args_w[1], 4)
-            self.w_filename = values_w[0]
-            self.w_lineno   = values_w[1]
-            self.w_offset   = values_w[2]
-            self.w_text     = values_w[3]
+            values_w = space.fixedview(args_w[1])
+            if len(values_w) > 0: self.w_filename   = values_w[0]
+            if len(values_w) > 1: self.w_lineno     = values_w[1]
+            if len(values_w) > 2: self.w_offset     = values_w[2]
+            if len(values_w) > 3: self.w_text       = values_w[3]
+            if len(values_w) > 4: self.w_lastlineno = values_w[4]
         W_BaseException.descr_init(self, space, args_w)
     descr_init.unwrap_spec = ['self', ObjSpace, 'args_w']
 
@@ -472,18 +474,24 @@
             if type(self.msg) is not str:
                 return str(self.msg)
 
+            lineno = None
             buffer = self.msg
             have_filename = type(self.filename) is str
-            have_lineno = type(self.lineno) is int
+            if type(self.lineno) is int:
+                if (type(self.lastlineno) is int and
+                       self.lastlineno > self.lineno):
+                    lineno = 'lines %d-%d' % (self.lineno, self.lastlineno)
+                else:
+                    lineno = 'line %d' % (self.lineno,)
             if have_filename:
                 import os
                 fname = os.path.basename(self.filename or "???")
-                if have_lineno:
-                    buffer = "%s (%s, line %ld)" % (self.msg, fname, self.lineno)
+                if lineno:
+                    buffer = "%s (%s, %s)" % (self.msg, fname, lineno)
                 else:
                     buffer ="%s (%s)" % (self.msg, fname)
-            elif have_lineno:
-                buffer = "%s (line %ld)" % (self.msg, self.lineno)
+            elif lineno:
+                buffer = "%s (%s)" % (self.msg, lineno)
             return buffer
         """)
 
@@ -504,6 +512,7 @@
     text     = readwrite_attrproperty_w('w_text', W_SyntaxError),
     print_file_and_line = readwrite_attrproperty_w('w_print_file_and_line',
                                                    W_SyntaxError),
+    lastlineno = readwrite_attrproperty_w('w_lastlineno', W_SyntaxError),
 )
 
 W_FutureWarning = _new_exception('FutureWarning', W_Warning,

Modified: pypy/branch/jitypes2/pypy/module/imp/importing.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/imp/importing.py	(original)
+++ pypy/branch/jitypes2/pypy/module/imp/importing.py	Thu Dec  9 09:13:06 2010
@@ -529,7 +529,7 @@
             space.sys.setmodule(w_module)
             raise
     finally:
-        space.reloading_modules.clear()
+        del space.reloading_modules[modulename]
 
 
 # __________________________________________________________________

Modified: pypy/branch/jitypes2/pypy/module/pypyjit/test/test_pypy_c.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/pypyjit/test/test_pypy_c.py	(original)
+++ pypy/branch/jitypes2/pypy/module/pypyjit/test/test_pypy_c.py	Thu Dec  9 09:13:06 2010
@@ -909,11 +909,14 @@
     def test_array_sum(self):
         for tc, maxops in zip('bhilBHILfd', (38,) * 6 + (40, 40, 41, 38)):
             res = 19352859
-            if tc in 'IL':
+            if tc == 'L':
                 res = long(res)
             elif tc in 'fd':
                 res = float(res)
-            
+            elif tc == 'I' and sys.maxint == 2147483647:
+                res = long(res)
+                # note: in CPython we always get longs here, even on 64-bits
+
             self.run_source('''
             from array import array
 
@@ -961,11 +964,14 @@
             print '='*65
             print '='*20, 'running test for tc=%r' % (tc,), '='*20
             res = 73574560
-            if tc in 'IL':
+            if tc == 'L':
                 res = long(res)
             elif tc in 'fd':
                 res = float(res)
-            
+            elif tc == 'I' and sys.maxint == 2147483647:
+                res = long(res)
+                # note: in CPython we always get longs here, even on 64-bits
+
             self.run_source('''
             from array import array
 

Modified: pypy/branch/jitypes2/pypy/module/sys/vm.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/sys/vm.py	(original)
+++ pypy/branch/jitypes2/pypy/module/sys/vm.py	Thu Dec  9 09:13:06 2010
@@ -41,27 +41,21 @@
         f = ec.getnextframe_nohidden(f)
     return space.wrap(f)
 
-# directly from the C code in ceval.c, might be moved somewhere else.
-
 def setrecursionlimit(space, w_new_limit):
-    """Set the maximum depth of the Python interpreter stack to n.  This
-limit prevents infinite recursion from causing an overflow of the C
-stack and crashing Python.  The highest possible limit is platform
-dependent."""
+    """DEPRECATED on PyPy. Will issue warning and not work
+    """
     new_limit = space.int_w(w_new_limit)
     if new_limit <= 0:
         raise OperationError(space.w_ValueError,
                              space.wrap("recursion limit must be positive"))
     # global recursion_limit
     # we need to do it without writing globals.
+    space.warn('setrecursionlimit deprecated', space.w_DeprecationWarning)
     space.sys.recursionlimit = new_limit
 
 def getrecursionlimit(space):
-    """Return the current value of the recursion limit, the maximum depth
-    of the Python interpreter stack.  This limit prevents infinite
-    recursion from causing an overflow of the C stack and crashing Python.
+    """DEPRECATED on PyPy. Will issue warning and not work
     """
-
     return space.wrap(space.sys.recursionlimit)
 
 def setcheckinterval(space, interval):

Modified: pypy/branch/jitypes2/pypy/objspace/std/complexobject.py
==============================================================================
--- pypy/branch/jitypes2/pypy/objspace/std/complexobject.py	(original)
+++ pypy/branch/jitypes2/pypy/objspace/std/complexobject.py	Thu Dec  9 09:13:06 2010
@@ -23,90 +23,92 @@
         """ representation for debugging purposes """
         return "<W_ComplexObject(%f,%f)>" % (w_self.realval, w_self.imagval)
 
-registerimplementation(W_ComplexObject)
-
-c_1 = (1.0, 0.0)
+    def sub(self, other):
+        return W_ComplexObject(self.realval - other.realval,
+                               self.imagval - other.imagval)
+
+    def mul(self, other):
+        r = self.realval * other.realval - self.imagval * other.imagval
+        i = self.realval * other.imagval + self.imagval * other.realval
+        return W_ComplexObject(r, i)
+
+    def div(self, other):
+        r1, i1 = self.realval, self.imagval
+        r2, i2 = other.realval, other.imagval
+        if r2 < 0:
+            abs_r2 = - r2
+        else:
+            abs_r2 = r2
+        if i2 < 0:
+            abs_i2 = - i2
+        else:
+            abs_i2 = i2
+        if abs_r2 >= abs_i2:
+            if abs_r2 == 0.0:
+                raise ZeroDivisionError
+            else:
+                ratio = i2 / r2
+                denom = r2 + i2 * ratio
+                rr = (r1 + i1 * ratio) / denom
+                ir = (i1 - r1 * ratio) / denom
+        else:
+            ratio = r2 / i2
+            denom = r2 * ratio + i2
+            assert i2 != 0.0
+            rr = (r1 * ratio + i1) / denom
+            ir = (i1 * ratio - r1) / denom
+        return W_ComplexObject(rr,ir)
+
+    def divmod(self, other):
+        w_div = self.div(other)
+        div = math.floor(w_div.realval)
+        w_mod = self.sub(
+            W_ComplexObject(other.realval * div, other.imagval * div))
+        return (W_ComplexObject(div, 0), w_mod)
+
+    def pow(self, other):
+        r1, i1 = self.realval, self.imagval
+        r2, i2 = other.realval, other.imagval
+        if r2 == 0.0 and i2 == 0.0:
+            rr, ir = 1, 0
+        elif r1 == 0.0 and i1 == 0.0:
+            if i2 != 0.0 or r2 < 0.0:
+                raise ZeroDivisionError
+            rr, ir = (0.0, 0.0)
+        else:
+            vabs = math.hypot(r1,i1)
+            len = math.pow(vabs,r2)
+            at = math.atan2(i1,r1)
+            phase = at * r2
+            if i2 != 0.0:
+                len /= math.exp(at * i2)
+                phase += i2 * math.log(vabs)
+            rr = len * math.cos(phase)
+            ir = len * math.sin(phase)
+        return W_ComplexObject(rr, ir)
+
+    def pow_int(self, n):
+        if n > 100 or n < -100:
+            return self.pow(W_ComplexObject(1.0 * n, 0.0))
+        elif n > 0:
+            return self.pow_positive_int(n)
+        else:
+            return w_one.div(self.pow_positive_int(-n))
 
-def _sum(c1, c2):
-    return (c1[0]+c2[0],c1[1]+c2[1])
+    def pow_positive_int(self, n):
+        mask = 1
+        w_result = w_one
+        while mask > 0 and n >= mask:
+            if n & mask:
+                w_result = w_result.mul(self)
+            mask <<= 1
+            self = self.mul(self)
 
-def _diff(c1, c2):
-    return (c1[0]-c2[0],c1[1]-c2[1])
+        return w_result
 
-def _prod(c1, c2):
-    r = c1[0]*c2[0] - c1[1]*c2[1]
-    i = c1[0]*c2[1] + c1[1]*c2[0]
-    return (r,i)
-
-def _quot(c1,c2):
-    r1, i1 = c1
-    r2, i2 = c2
-    if r2 < 0:
-        abs_r2 = - r2
-    else:
-        abs_r2 = r2
-    if i2 < 0:
-        abs_i2 = - i2
-    else:
-        abs_i2 = i2
-    if abs_r2 >= abs_i2:
-        if abs_r2 == 0.0:
-            raise ZeroDivisionError
-        else:
-            ratio = i2 / r2
-            denom = r2 + i2 * ratio
-            rr = (r1 + i1 * ratio) / denom
-            ir = (i1 - r1 * ratio) / denom
-    else:
-        ratio = r2 / i2
-        denom = r2 * ratio + i2
-        assert i2 != 0.0
-        rr = (r1 * ratio + i1) / denom
-        ir = (i1 * ratio - r1) / denom
-    return (rr,ir)
-
-def _pow(c1,c2):
-    r1, i1 = c1
-    r2, i2 = c2
-    if r2 == 0.0 and i2 == 0.0:
-        rr, ir = c_1
-    elif r1 == 0.0 and i1 == 0.0:
-        if i2 != 0.0 or r2 < 0.0:
-            raise ZeroDivisionError
-        rr, ir = (0.0, 0.0)
-    else:
-        vabs = math.hypot(r1,i1)
-        len = math.pow(vabs,r2)
-        at = math.atan2(i1,r1)
-        phase = at * r2
-        if i2 != 0.0:
-            len /= math.exp(at * i2)
-            phase += i2 * math.log(vabs)
-        rr = len * math.cos(phase)
-        ir = len * math.sin(phase)
-    return (rr, ir)
-
-def _powu(c,n):
-    mask = 1;
-    rr, ir = c_1
-    rp = c[0]
-    ip = c[1]
-    while mask > 0 and n >= mask:
-        if n & mask:
-            rr, ir = _prod((rr, ir), (rp, ip))
-        mask <<= 1
-        rp, ip = _prod((rp, ip), (rp, ip))
-
-    return (rr, ir)
-
-def _powi(c,n):
-    if n > 100 or n < -100:
-        return _pow(c,(1.0 * n, 0.0))
-    elif n > 0:
-        return _powu(c, n)
-    else:
-        return _quot(c_1, _powu(c, -n))
+registerimplementation(W_ComplexObject)
 
+w_one = W_ComplexObject(1, 0)
 
 
 def delegate_Bool2Complex(space, w_bool):
@@ -126,38 +128,25 @@
     return W_ComplexObject(w_float.floatval, 0.0)
 
 def hash__Complex(space, w_value):
-    #this is straight out of CPython complex implementation
-
     hashreal = _hash_float(space, w_value.realval)
-    if hashreal == -1:
-        return space.newint(-1)
     hashimg = _hash_float(space, w_value.imagval)
-    if hashimg == -1:
-        return space.newint(-1)
     combined = hashreal + 1000003 * hashimg
-    if (combined == -1):
-        combined = -2
     return space.newint(combined)
 
-def _w2t(space, w_complex):
-    "convert an interplevel complex object to a tuple representation"
-    return w_complex.realval, w_complex.imagval
-
-def _t2w(space, c):
-    return W_ComplexObject(c[0], c[1])
-
 def add__Complex_Complex(space, w_complex1, w_complex2):
-    return _t2w(space, _sum(_w2t(space, w_complex1), _w2t(space, w_complex2)))
+    return W_ComplexObject(w_complex1.realval + w_complex2.realval,
+                           w_complex1.imagval + w_complex2.imagval)
 
 def sub__Complex_Complex(space, w_complex1, w_complex2):
-    return _t2w(space, _diff(_w2t(space, w_complex1), _w2t(space, w_complex2)))
+    return W_ComplexObject(w_complex1.realval - w_complex2.realval,
+                           w_complex1.imagval - w_complex2.imagval)
 
 def mul__Complex_Complex(space, w_complex1, w_complex2):
-    return _t2w(space, _prod(_w2t(space, w_complex1), _w2t(space, w_complex2)))
+    return w_complex1.mul(w_complex2)
 
 def div__Complex_Complex(space, w_complex1, w_complex2):
     try:
-        return _t2w(space, _quot(_w2t(space, w_complex1), _w2t(space, w_complex2)))
+        return w_complex1.div(w_complex2)
     except ZeroDivisionError, e:
         raise OperationError(space.w_ZeroDivisionError, space.wrap(str(e)))
 
@@ -165,49 +154,38 @@
 
 def mod__Complex_Complex(space, w_complex1, w_complex2):
     try:
-        div = _quot(_w2t(space, w_complex1), _w2t(space, w_complex2))
+        return w_complex1.divmod(w_complex2)[1]
     except ZeroDivisionError, e:
-        raise OperationError(space.w_ZeroDivisionError, space.wrap("complex remainder"))
-    div = (math.floor(div[0]), 0.0)
-    mod = _diff(_w2t(space, w_complex1), _prod(_w2t(space, w_complex2), div))
-
-    return _t2w(space, mod)
+        raise OperationError(space.w_ZeroDivisionError, space.wrap(str(e)))
 
 def divmod__Complex_Complex(space, w_complex1, w_complex2):
     try:
-        div = _quot(_w2t(space, w_complex1), _w2t(space, w_complex2))
+        div, mod = w_complex1.divmod(w_complex2)
     except ZeroDivisionError, e:
-        raise OperationError(space.w_ZeroDivisionError, space.wrap("complex divmod()"))
-    div = (math.floor(div[0]), 0.0)
-    mod = _diff(_w2t(space, w_complex1), _prod(_w2t(space, w_complex2), div))
-    w_div = _t2w(space, div)
-    w_mod = _t2w(space, mod)
-    return space.newtuple([w_div, w_mod])
+        raise OperationError(space.w_ZeroDivisionError, space.wrap(str(e)))
+    return space.newtuple([div, mod])
 
 def floordiv__Complex_Complex(space, w_complex1, w_complex2):
+    # don't care about the slight slowdown you get from using divmod
     try:
-        div = _quot(_w2t(space, w_complex1), _w2t(space, w_complex2))
+        return w_complex1.divmod(w_complex2)[0]
     except ZeroDivisionError, e:
-        raise OperationError(space.w_ZeroDivisionError, space.wrap("complex floordiv()"))
-    div = (math.floor(div[0]), 0.0)
-    return _t2w(space, div)
+        raise OperationError(space.w_ZeroDivisionError, space.wrap(str(e)))
 
-def pow__Complex_Complex_ANY(space, w_complex1, w_complex2, thirdArg):
+def pow__Complex_Complex_ANY(space, w_complex, w_exponent, thirdArg):
     if not space.is_w(thirdArg, space.w_None):
         raise OperationError(space.w_ValueError, space.wrap('complex modulo'))
+    int_exponent = int(w_exponent.realval)
     try:
-        v = _w2t(space, w_complex1)
-        exponent = _w2t(space, w_complex2)
-        int_exponent = int(exponent[0])
-        if exponent[1] == 0.0 and exponent[0] == int_exponent:
-            p = _powi(v, int_exponent)
+        if w_exponent.imagval == 0.0 and w_exponent.realval == int_exponent:
+            w_p = w_complex.pow_int(int_exponent)
         else:
-            p = _pow(v, exponent)
+            w_p = w_complex.pow(w_exponent)
     except ZeroDivisionError:
         raise OperationError(space.w_ZeroDivisionError, space.wrap("0.0 to a negative or complex power"))
     except OverflowError:
         raise OperationError(space.w_OverflowError, space.wrap("complex exponentiation"))
-    return _t2w(space, p)
+    return w_p
 
 def neg__Complex(space, w_complex):
     return W_ComplexObject(-w_complex.realval, -w_complex.imagval)

Modified: pypy/branch/jitypes2/pypy/objspace/std/complextype.py
==============================================================================
--- pypy/branch/jitypes2/pypy/objspace/std/complextype.py	(original)
+++ pypy/branch/jitypes2/pypy/objspace/std/complextype.py	Thu Dec  9 09:13:06 2010
@@ -1,7 +1,7 @@
 from pypy.interpreter import gateway
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.strutil import interp_string_to_float, ParseStringError
+from pypy.objspace.std.strutil import string_to_float, ParseStringError
 from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef
 from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod
@@ -131,8 +131,8 @@
         except ValueError:
             raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED))
         try:
-            realval = interp_string_to_float(space, realstr)
-            imagval = interp_string_to_float(space, imagstr)
+            realval = string_to_float(realstr)
+            imagval = string_to_float(imagstr)
         except ParseStringError:
             raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED))
         else:

Modified: pypy/branch/jitypes2/pypy/objspace/std/floattype.py
==============================================================================
--- pypy/branch/jitypes2/pypy/objspace/std/floattype.py	(original)
+++ pypy/branch/jitypes2/pypy/objspace/std/floattype.py	Thu Dec  9 09:13:06 2010
@@ -2,7 +2,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std.stdtypedef import StdTypeDef
 from pypy.objspace.std.strutil import ParseStringError
-from pypy.objspace.std.strutil import interp_string_to_float
+from pypy.objspace.std.strutil import string_to_float
 
 def descr__new__(space, w_floattype, w_x=0.0):
     from pypy.objspace.std.floatobject import W_FloatObject
@@ -10,7 +10,7 @@
     if space.is_true(space.isinstance(w_value, space.w_str)):
         strvalue = space.str_w(w_value)
         try:
-            value = interp_string_to_float(space, strvalue)
+            value = string_to_float(strvalue)
         except ParseStringError, e:
             raise OperationError(space.w_ValueError,
                                  space.wrap(e.msg))
@@ -21,7 +21,7 @@
             from unicodeobject import unicode_to_decimal_w
         strvalue = unicode_to_decimal_w(space, w_value)
         try:
-            value = interp_string_to_float(space, strvalue)
+            value = string_to_float(strvalue)
         except ParseStringError, e:
             raise OperationError(space.w_ValueError,
                                  space.wrap(e.msg))

Modified: pypy/branch/jitypes2/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/branch/jitypes2/pypy/objspace/std/longobject.py	(original)
+++ pypy/branch/jitypes2/pypy/objspace/std/longobject.py	Thu Dec  9 09:13:06 2010
@@ -45,19 +45,6 @@
     fromrarith_int._annspecialcase_ = "specialize:argtype(0)"
     fromrarith_int = staticmethod(fromrarith_int)
 
-    def fromdecimalstr(s):
-        return W_LongObject(rbigint.fromdecimalstr(s))
-    fromdecimalstr = staticmethod(fromdecimalstr)
-
-    def _count_bits(self):
-        return self.num._count_bits()
-
-    def is_odd(self):
-        return self.num.is_odd()
-
-    def get_sign(self):
-        return self.num.sign
-
 registerimplementation(W_LongObject)
 
 # bool-to-long

Modified: pypy/branch/jitypes2/pypy/objspace/std/strutil.py
==============================================================================
--- pypy/branch/jitypes2/pypy/objspace/std/strutil.py	(original)
+++ pypy/branch/jitypes2/pypy/objspace/std/strutil.py	Thu Dec  9 09:13:06 2010
@@ -150,7 +150,7 @@
 del calc_mantissa_bits
 MANTISSA_DIGITS = len(str( (1L << MANTISSA_BITS)-1 )) + 1
 
-def interp_string_to_float(space, s):
+def string_to_float(s):
     """
     Conversion of string to float.
     This version tries to only raise on invalid literals.
@@ -162,10 +162,9 @@
     s = strip_spaces(s)
 
     if not s:
-        raise OperationError(space.w_ValueError, space.wrap(
-            "empty string for float()"))
+        raise ParseStringError("empty string for float()")
+
 
-    
     low = s.lower()
     if low == "-inf":
         return -INFINITY
@@ -204,68 +203,56 @@
     if len(digits) == 0:
         digits = '0'
 
-    # a few abbreviations
-    from pypy.objspace.std import longobject
-    mklong = longobject.W_LongObject.fromint
-    d2long = longobject.W_LongObject.fromdecimalstr
-    adlong = longobject.add__Long_Long
-    longup = longobject.pow__Long_Long_None
-    multip = longobject.mul__Long_Long
-    divide = longobject.div__Long_Long
-    lshift = longobject.lshift__Long_Long
-    rshift = longobject.rshift__Long_Long
-
     # 4) compute the exponent and truncate to +-400
     if not exponent:
         exponent = '0'
-    w_le = d2long(exponent)
-    w_le = adlong(space, w_le, mklong(space, dexp))
+    long_exponent = rbigint.fromdecimalstr(exponent)
+    long_exponent = long_exponent.add(rbigint.fromint(dexp))
     try:
-        e = w_le.toint()
+        e = long_exponent.toint()
     except OverflowError:
         # XXX poking at internals
-        e = w_le.num.sign * 400
-    if e >= 400:
-        e = 400
-    elif e <= -400:
-        e = -400
+        e = long_exponent.sign * 400
+    else:
+        if e >= 400:
+            e = 400
+        elif e <= -400:
+            e = -400
 
     # 5) compute the value using long math and proper rounding.
-    w_lr = d2long(digits)
-    w_10 = mklong(space, 10)
-    w_1 = mklong(space, 1)
+    b_digits = rbigint.fromdecimalstr(digits)
+    b_10 = rbigint.fromint(10)
+    b_1 = rbigint.fromint(1)
     if e >= 0:
         bits = 0
-        w_pten = longup(space, w_10, mklong(space, e), space.w_None)
-        w_m = multip(space, w_lr, w_pten)
+        b_power_of_ten = b_10.pow(rbigint.fromint(e))
+        b_mantissa = b_digits.mul(b_power_of_ten)
     else:
         # compute a sufficiently large scale
         prec = MANTISSA_DIGITS * 2 + 22 # 128, maybe
         bits = - (int(math.ceil(-e / math.log10(2.0) - 1e-10)) + prec)
-        w_scale = lshift(space, w_1, mklong(space, -bits))
-        w_pten = longup(space, w_10, mklong(space, -e), None)
-        w_tmp = multip(space, w_lr, w_scale)
-        w_m = divide(space, w_tmp, w_pten)
+        b_scale = b_1.lshift(-bits)
+        b_power_of_ten = b_10.pow(rbigint.fromint(-e))
+        b_mantissa = b_digits.mul(b_scale).div(b_power_of_ten)
 
     # we now have a fairly large mantissa.
     # Shift it and round the last bit.
 
     # first estimate the bits and do a big shift
-    mbits = w_m._count_bits()
+    mbits = b_mantissa._count_bits()
     needed = MANTISSA_BITS
     if mbits > needed:
         if mbits > needed+1:
             shifted = mbits - (needed+1)
-            w_m = rshift(space, w_m, mklong(space, shifted))
+            b_mantissa = b_mantissa.rshift(shifted)
             bits += shifted
         # do the rounding
         bits += 1
-        round = w_m.is_odd()
-        w_m = rshift(space, w_m, w_1)
-        w_m = adlong(space, w_m, mklong(space, round))
+        round = b_mantissa.is_odd()
+        b_mantissa = b_mantissa.rshift(1).add(rbigint.fromint(round))
 
     try:
-        r = math.ldexp(w_m.tofloat(), bits)
+        r = math.ldexp(b_mantissa.tofloat(), bits)
         # XXX I guess we do not check for overflow in ldexp as we agreed to!
         if r == 2*r and r != 0.0:
             raise OverflowError

Modified: pypy/branch/jitypes2/pypy/objspace/std/test/test_complexobject.py
==============================================================================
--- pypy/branch/jitypes2/pypy/objspace/std/test/test_complexobject.py	(original)
+++ pypy/branch/jitypes2/pypy/objspace/std/test/test_complexobject.py	Thu Dec  9 09:13:06 2010
@@ -1,5 +1,6 @@
 import py
-from pypy.objspace.std import complexobject as cobj
+from pypy.objspace.std.complexobject import W_ComplexObject, \
+    pow__Complex_Complex_ANY
 from pypy.objspace.std import complextype as cobjtype
 from pypy.objspace.std.multimethod import FailedToImplement
 from pypy.objspace.std.stringobject import W_StringObject
@@ -11,7 +12,7 @@
 
     def _test_instantiation(self):
         def _t_complex(r=0.0,i=0.0):
-            c = cobj.W_ComplexObject(r, i)
+            c = W_ComplexObject(r, i)
             assert c.real == float(r) and c.imag == float(i)
         pairs = (
             (1, 1),
@@ -38,21 +39,31 @@
         test_cparse('.e+5', '.e+5', '0.0')
 
     def test_pow(self):
-        assert cobj._pow((0.0,2.0),(0.0,0.0)) == (1.0,0.0)
-        assert cobj._pow((0.0,0.0),(2.0,0.0)) == (0.0,0.0)
-        rr, ir = cobj._pow((0.0,1.0),(2.0,0.0))
+        def _pow((r1, i1), (r2, i2)):
+            w_res = W_ComplexObject(r1, i1).pow(W_ComplexObject(r2, i2))
+            return w_res.realval, w_res.imagval
+        assert _pow((0.0,2.0),(0.0,0.0)) == (1.0,0.0)
+        assert _pow((0.0,0.0),(2.0,0.0)) == (0.0,0.0)
+        rr, ir = _pow((0.0,1.0),(2.0,0.0))
         assert abs(-1.0 - rr) < EPS
         assert abs(0.0 - ir) < EPS
 
-        assert cobj._powu((0.0,2.0),0) == (1.0,0.0)
-        assert cobj._powu((0.0,0.0),2) == (0.0,0.0)
-        assert cobj._powu((0.0,1.0),2) == (-1.0,0.0)
-        assert cobj._powi((0.0,2.0),0) == (1.0,0.0)
-        assert cobj._powi((0.0,0.0),2) == (0.0,0.0)
-        assert cobj._powi((0.0,1.0),2) == (-1.0,0.0)
-        c = cobj.W_ComplexObject(0.0,1.0)
-        p = cobj.W_ComplexObject(2.0,0.0)
-        r = cobj.pow__Complex_Complex_ANY(self.space,c,p,self.space.wrap(None))
+        def _powu((r1, i1), n):
+            w_res = W_ComplexObject(r1, i1).pow_positive_int(n)
+            return w_res.realval, w_res.imagval
+        assert _powu((0.0,2.0),0) == (1.0,0.0)
+        assert _powu((0.0,0.0),2) == (0.0,0.0)
+        assert _powu((0.0,1.0),2) == (-1.0,0.0)
+
+        def _powi((r1, i1), n):
+            w_res = W_ComplexObject(r1, i1).pow_int(n)
+            return w_res.realval, w_res.imagval
+        assert _powi((0.0,2.0),0) == (1.0,0.0)
+        assert _powi((0.0,0.0),2) == (0.0,0.0)
+        assert _powi((0.0,1.0),2) == (-1.0,0.0)
+        c = W_ComplexObject(0.0,1.0)
+        p = W_ComplexObject(2.0,0.0)
+        r = pow__Complex_Complex_ANY(self.space,c,p,self.space.wrap(None))
         assert r.realval == -1.0
         assert r.imagval == 0.0
 

Modified: pypy/branch/jitypes2/pypy/objspace/std/test/test_strutil.py
==============================================================================
--- pypy/branch/jitypes2/pypy/objspace/std/test/test_strutil.py	(original)
+++ pypy/branch/jitypes2/pypy/objspace/std/test/test_strutil.py	Thu Dec  9 09:13:06 2010
@@ -131,8 +131,6 @@
         assert string_to_bigint('1891234174197319').tolong() == 1891234174197319
 
     def test_string_to_float(self):
-        def string_to_float(x):
-            return interp_string_to_float(self.space, x)
         assert string_to_float('0') == 0.0
         assert string_to_float('1') == 1.0
         assert string_to_float('-1.5') == -1.5
@@ -180,3 +178,4 @@
                     print repr(s)
                     if s.strip(): # empty s raises OperationError directly
                         py.test.raises(ParseStringError, string_to_float, s)
+        py.test.raises(ParseStringError, string_to_float, "")

Modified: pypy/branch/jitypes2/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/jitypes2/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/branch/jitypes2/pypy/rpython/lltypesystem/ll2ctypes.py	Thu Dec  9 09:13:06 2010
@@ -409,6 +409,7 @@
     subcls = get_common_subclass(mixin_cls, instance.__class__)
     instance.__class__ = subcls
     instance._storage = ctypes_storage
+    assert ctypes_storage   # null pointer?
 
 class _parentable_mixin(object):
     """Mixin added to _parentable containers when they become ctypes-based.

Modified: pypy/branch/jitypes2/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/jitypes2/pypy/rpython/memory/gc/base.py	(original)
+++ pypy/branch/jitypes2/pypy/rpython/memory/gc/base.py	Thu Dec  9 09:13:06 2010
@@ -36,6 +36,13 @@
         self.finalizer_lock_count = 0
         self.run_finalizers = self.AddressDeque()
 
+    def post_setup(self):
+        # More stuff that needs to be initialized when the GC is already
+        # fully working.  (Only called by gctransform/framework for now.)
+        from pypy.rpython.memory.gc import env
+        if env.read_from_env('PYPY_GC_DEBUG') > 0:
+            self.DEBUG = True
+
     def _teardown(self):
         pass
 
@@ -48,7 +55,8 @@
     # The following flag enables costly consistency checks after each
     # collection.  It is automatically set to True by test_gc.py.  The
     # checking logic is translatable, so the flag can be set to True
-    # here before translation.
+    # here before translation.  At run-time, if PYPY_GC_DEBUG is set,
+    # then it is also set to True.
     DEBUG = False
 
     def set_query_functions(self, is_varsize, has_gcptr_in_varsize,

Modified: pypy/branch/jitypes2/pypy/rpython/memory/gc/minimark.py
==============================================================================
--- pypy/branch/jitypes2/pypy/rpython/memory/gc/minimark.py	(original)
+++ pypy/branch/jitypes2/pypy/rpython/memory/gc/minimark.py	Thu Dec  9 09:13:06 2010
@@ -32,6 +32,9 @@
                         limit.  Useful to avoid spending all the time in
                         the GC in very small programs.  Defaults to 8
                         times the nursery.
+
+ PYPY_GC_DEBUG          Enable extra checks around collections that are
+                        too slow for normal use.
 """
 # XXX Should find a way to bound the major collection threshold by the
 # XXX total addressable size.  Maybe by keeping some minimarkpage arenas
@@ -841,7 +844,7 @@
         def remember_young_pointer(addr_struct, newvalue):
             # 'addr_struct' is the address of the object in which we write.
             # 'newvalue' is the address that we are going to write in there.
-            if DEBUG:
+            if DEBUG:   # note: PYPY_GC_DEBUG=1 does not enable this
                 ll_assert(not self.is_in_nursery(addr_struct),
                           "nursery object with GCFLAG_NO_YOUNG_PTRS")
             #
@@ -878,7 +881,7 @@
             # 'addr_array' is the address of the object in which we write,
             # which must have an array part;  'index' is the index of the
             # item that is (or contains) the pointer that we write.
-            if DEBUG:
+            if DEBUG:   # note: PYPY_GC_DEBUG=1 does not enable this
                 ll_assert(not self.is_in_nursery(addr_array),
                           "nursery array with GCFLAG_NO_YOUNG_PTRS")
             objhdr = self.header(addr_array)

Modified: pypy/branch/jitypes2/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/jitypes2/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/jitypes2/pypy/rpython/memory/gctransform/framework.py	Thu Dec  9 09:13:06 2010
@@ -189,6 +189,7 @@
             # run-time initialization code
             root_walker.setup_root_walker()
             gcdata.gc.setup()
+            gcdata.gc.post_setup()
 
         def frameworkgc__teardown():
             # run-time teardown code for tests!

Modified: pypy/branch/jitypes2/pypy/rpython/tool/rffi_platform.py
==============================================================================
--- pypy/branch/jitypes2/pypy/rpython/tool/rffi_platform.py	(original)
+++ pypy/branch/jitypes2/pypy/rpython/tool/rffi_platform.py	Thu Dec  9 09:13:06 2010
@@ -639,7 +639,6 @@
 C_HEADER = """
 #include <stdio.h>
 #include <stddef.h>   /* for offsetof() */
-#include <stdint.h>   /* FreeBSD: for uint64_t */
 
 void dump(char* key, int value) {
     printf("%s: %d\\n", key, value);

Modified: pypy/branch/jitypes2/pypy/tool/error.py
==============================================================================
--- pypy/branch/jitypes2/pypy/tool/error.py	(original)
+++ pypy/branch/jitypes2/pypy/tool/error.py	Thu Dec  9 09:13:06 2010
@@ -120,7 +120,7 @@
         msg.append("      (%s getting at the binding!)" % (
             e.__class__.__name__,))
         return
-    for desc in descs.keys():
+    for desc in list(descs):
         func = desc.pyobj
         if func is None:
             r = repr(desc)

Modified: pypy/branch/jitypes2/pypy/tool/release/package.py
==============================================================================
--- pypy/branch/jitypes2/pypy/tool/release/package.py	(original)
+++ pypy/branch/jitypes2/pypy/tool/release/package.py	Thu Dec  9 09:13:06 2010
@@ -78,7 +78,7 @@
     old_dir = os.getcwd()
     try:
         os.chdir(str(builddir))
-        os.system("strip " + str(archive_pypy_c))    # ignore errors
+        os.system("strip -x " + str(archive_pypy_c))    # ignore errors
         if USE_TARFILE_MODULE:
             import tarfile
             tf = tarfile.open(str(builddir.join(name + '.tar.bz2')), 'w:bz2')

Modified: pypy/branch/jitypes2/pypy/translator/goal/app_main.py
==============================================================================
--- pypy/branch/jitypes2/pypy/translator/goal/app_main.py	(original)
+++ pypy/branch/jitypes2/pypy/translator/goal/app_main.py	Thu Dec  9 09:13:06 2010
@@ -312,8 +312,9 @@
                      cmd=None,
                      **ignored):
     # with PyPy in top of CPython we can only have around 100 
-    # but we need more in the translated PyPy for the compiler package 
-    sys.setrecursionlimit(5000)
+    # but we need more in the translated PyPy for the compiler package
+    if '__pypy__' not in sys.builtin_module_names:
+        sys.setrecursionlimit(5000)
 
     if unbuffered:
         set_unbuffered_io()

Modified: pypy/branch/jitypes2/pypy/translator/platform/darwin.py
==============================================================================
--- pypy/branch/jitypes2/pypy/translator/platform/darwin.py	(original)
+++ pypy/branch/jitypes2/pypy/translator/platform/darwin.py	Thu Dec  9 09:13:06 2010
@@ -11,8 +11,10 @@
     shared_only = ()
 
     so_ext = 'so'
-    
-    default_cc = 'gcc'
+
+    # NOTE: GCC 4.2 will fail at runtime due to subtle issues, possibly
+    # related to GC roots. Using LLVM-GCC or Clang will break the build.
+    default_cc = 'gcc-4.0'
 
     def __init__(self, cc=None):
         if cc is None:
@@ -87,4 +89,3 @@
     link_flags = ('-arch', 'x86_64', '-mmacosx-version-min=10.4')
     cflags = ('-arch', 'x86_64', '-O3', '-fomit-frame-pointer',
               '-mmacosx-version-min=10.4')
-    default_cc = 'gcc-4.0'



More information about the Pypy-commit mailing list