[pypy-svn] r79852 - in pypy/branch/fast-forward: . lib-python/modified-2.5.2/distutils pypy pypy/doc/config pypy/interpreter pypy/jit/codewriter pypy/jit/codewriter/test pypy/jit/metainterp pypy/jit/metainterp/optimizeopt pypy/jit/metainterp/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/pypyjit/test pypy/module/sys pypy/rlib pypy/rlib/test pypy/rpython/lltypesystem pypy/tool/release pypy/translator/goal pypy/translator/platform
afa at codespeak.net
afa at codespeak.net
Mon Dec 6 17:27:37 CET 2010
Author: afa
Date: Mon Dec 6 17:27:34 2010
New Revision: 79852
Added:
pypy/branch/fast-forward/pypy/module/cpyext/include/fileobject.h
- copied unchanged from r79849, pypy/trunk/pypy/module/cpyext/include/fileobject.h
Modified:
pypy/branch/fast-forward/ (props changed)
pypy/branch/fast-forward/lib-python/modified-2.5.2/distutils/unixccompiler.py
pypy/branch/fast-forward/pypy/ (props changed)
pypy/branch/fast-forward/pypy/doc/config/objspace.usemodules.array.txt (props changed)
pypy/branch/fast-forward/pypy/interpreter/executioncontext.py
pypy/branch/fast-forward/pypy/jit/codewriter/regalloc.py
pypy/branch/fast-forward/pypy/jit/codewriter/test/test_regalloc.py
pypy/branch/fast-forward/pypy/jit/metainterp/optimizefindnode.py
pypy/branch/fast-forward/pypy/jit/metainterp/optimizeopt/optimizer.py (props changed)
pypy/branch/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py
pypy/branch/fast-forward/pypy/module/_stackless/interp_coroutine.py
pypy/branch/fast-forward/pypy/module/array/benchmark/Makefile (props changed)
pypy/branch/fast-forward/pypy/module/array/benchmark/intimg.c (props changed)
pypy/branch/fast-forward/pypy/module/array/benchmark/intimgtst.c (props changed)
pypy/branch/fast-forward/pypy/module/array/benchmark/intimgtst.py (props changed)
pypy/branch/fast-forward/pypy/module/array/benchmark/loop.c (props changed)
pypy/branch/fast-forward/pypy/module/array/benchmark/sum.c (props changed)
pypy/branch/fast-forward/pypy/module/array/benchmark/sumtst.c (props changed)
pypy/branch/fast-forward/pypy/module/array/benchmark/sumtst.py (props changed)
pypy/branch/fast-forward/pypy/module/array/test/test_array.py
pypy/branch/fast-forward/pypy/module/array/test/test_array_old.py (props changed)
pypy/branch/fast-forward/pypy/module/cpyext/include/Python.h
pypy/branch/fast-forward/pypy/module/cpyext/intobject.py
pypy/branch/fast-forward/pypy/module/cpyext/object.py
pypy/branch/fast-forward/pypy/module/cpyext/pyerrors.py
pypy/branch/fast-forward/pypy/module/cpyext/pythonrun.py
pypy/branch/fast-forward/pypy/module/cpyext/src/getargs.c
pypy/branch/fast-forward/pypy/module/cpyext/state.py
pypy/branch/fast-forward/pypy/module/cpyext/stubs.py
pypy/branch/fast-forward/pypy/module/cpyext/test/test_cpyext.py
pypy/branch/fast-forward/pypy/module/cpyext/test/test_intobject.py
pypy/branch/fast-forward/pypy/module/cpyext/test/test_object.py
pypy/branch/fast-forward/pypy/module/cpyext/test/test_pyerrors.py
pypy/branch/fast-forward/pypy/module/pypyjit/test/test_pypy_c.py
pypy/branch/fast-forward/pypy/module/sys/vm.py
pypy/branch/fast-forward/pypy/rlib/rerased.py (props changed)
pypy/branch/fast-forward/pypy/rlib/test/test_rerased.py (props changed)
pypy/branch/fast-forward/pypy/rpython/lltypesystem/ll2ctypes.py
pypy/branch/fast-forward/pypy/tool/release/package.py
pypy/branch/fast-forward/pypy/translator/goal/app_main.py
pypy/branch/fast-forward/pypy/translator/platform/darwin.py
Log:
Merge from trunk: -r79790:79849
Modified: pypy/branch/fast-forward/lib-python/modified-2.5.2/distutils/unixccompiler.py
==============================================================================
--- pypy/branch/fast-forward/lib-python/modified-2.5.2/distutils/unixccompiler.py (original)
+++ pypy/branch/fast-forward/lib-python/modified-2.5.2/distutils/unixccompiler.py Mon Dec 6 17:27:34 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/fast-forward/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/executioncontext.py (original)
+++ pypy/branch/fast-forward/pypy/interpreter/executioncontext.py Mon Dec 6 17:27:34 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,17 +112,14 @@
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!
Modified: pypy/branch/fast-forward/pypy/jit/codewriter/regalloc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/regalloc.py (original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/regalloc.py Mon Dec 6 17:27:34 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/fast-forward/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/codewriter/test/test_regalloc.py (original)
+++ pypy/branch/fast-forward/pypy/jit/codewriter/test/test_regalloc.py Mon Dec 6 17:27:34 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/fast-forward/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/optimizefindnode.py (original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/optimizefindnode.py Mon Dec 6 17:27:34 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/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/branch/fast-forward/pypy/jit/metainterp/test/test_optimizeopt.py Mon Dec 6 17:27:34 2010
@@ -1954,6 +1954,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/fast-forward/pypy/module/_stackless/interp_coroutine.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_stackless/interp_coroutine.py (original)
+++ pypy/branch/fast-forward/pypy/module/_stackless/interp_coroutine.py Mon Dec 6 17:27:34 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/fast-forward/pypy/module/array/test/test_array.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/array/test/test_array.py (original)
+++ pypy/branch/fast-forward/pypy/module/array/test/test_array.py Mon Dec 6 17:27:34 2010
@@ -65,6 +65,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,
@@ -89,7 +90,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/fast-forward/pypy/module/cpyext/include/Python.h
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/include/Python.h (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/include/Python.h Mon Dec 6 17:27:34 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
@@ -115,6 +117,7 @@
#include "sliceobject.h"
#include "datetime.h"
#include "pystate.h"
+#include "fileobject.h"
// XXX This shouldn't be included here
#include "structmember.h"
@@ -132,4 +135,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/fast-forward/pypy/module/cpyext/intobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/intobject.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/intobject.py Mon Dec 6 17:27:34 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, build_type_checkers, PyObject,
CONST_STRING, CANNOT_FAIL, Py_ssize_t)
@@ -20,6 +21,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)
@@ -27,6 +31,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], rffi.ULONG, error=-1)
@@ -54,6 +61,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)
@@ -85,4 +95,3 @@
if pend:
pend[0] = rffi.ptradd(str, len(s))
return space.call_function(space.w_int, w_str, w_base)
-
Modified: pypy/branch/fast-forward/pypy/module/cpyext/object.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/object.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/object.py Mon Dec 6 17:27:34 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/fast-forward/pypy/module/cpyext/pyerrors.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/pyerrors.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/pyerrors.py Mon Dec 6 17:27:34 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/fast-forward/pypy/module/cpyext/pythonrun.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/pythonrun.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/pythonrun.py Mon Dec 6 17:27:34 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/fast-forward/pypy/module/cpyext/src/getargs.c
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/src/getargs.c (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/src/getargs.c Mon Dec 6 17:27:34 2010
@@ -445,18 +445,22 @@
for (i = 0; i < n; i++) {
char *msg;
PyObject *item;
- item = PySequence_GetItem(arg, i);
+ /* CPython uses PySequence_GetItem() and Py_XDECREF() here,
+ exposing a crash (see http://bugs.python.org/issue6083).
+ It always crashes with PyPy, so we apply the fix being
+ discussed: we only allow a tuple. */
+ item = PyTuple_GetItem(arg, i);
if (item == NULL) {
PyErr_Clear();
levels[0] = i+1;
levels[1] = 0;
- strncpy(msgbuf, "is not retrievable", bufsize);
+ strncpy(msgbuf, "is not retrievable (subargument "
+ "must be a real tuple with PyPy)",
+ bufsize);
return msgbuf;
}
msg = convertitem(item, &format, p_va, flags, levels+1,
msgbuf, bufsize, freelist);
- /* PySequence_GetItem calls tp->sq_item, which INCREFs */
- Py_XDECREF(item);
if (msg != NULL) {
levels[0] = i+1;
return msg;
Modified: pypy/branch/fast-forward/pypy/module/cpyext/state.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/state.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/state.py Mon Dec 6 17:27:34 2010
@@ -9,6 +9,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
@@ -82,3 +83,16 @@
for func in INIT_FUNCTIONS:
func(space)
self.check_and_raise_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/fast-forward/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/stubs.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/stubs.py Mon Dec 6 17:27:34 2010
@@ -597,24 +597,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
@@ -723,21 +705,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
@@ -771,22 +738,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."""
@@ -1310,17 +1261,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/fast-forward/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/test/test_cpyext.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/test/test_cpyext.py Mon Dec 6 17:27:34 2010
@@ -691,3 +691,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/fast-forward/pypy/module/cpyext/test/test_intobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/test/test_intobject.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/test/test_intobject.py Mon Dec 6 17:27:34 2010
@@ -20,6 +20,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/fast-forward/pypy/module/cpyext/test/test_object.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/test/test_object.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/test/test_object.py Mon Dec 6 17:27:34 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/fast-forward/pypy/module/cpyext/test/test_pyerrors.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/test/test_pyerrors.py (original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/test/test_pyerrors.py Mon Dec 6 17:27:34 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/fast-forward/pypy/module/pypyjit/test/test_pypy_c.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/pypyjit/test/test_pypy_c.py (original)
+++ pypy/branch/fast-forward/pypy/module/pypyjit/test/test_pypy_c.py Mon Dec 6 17:27:34 2010
@@ -885,11 +885,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
@@ -937,11 +940,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/fast-forward/pypy/module/sys/vm.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/sys/vm.py (original)
+++ pypy/branch/fast-forward/pypy/module/sys/vm.py Mon Dec 6 17:27:34 2010
@@ -42,27 +42,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/fast-forward/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rpython/lltypesystem/ll2ctypes.py (original)
+++ pypy/branch/fast-forward/pypy/rpython/lltypesystem/ll2ctypes.py Mon Dec 6 17:27:34 2010
@@ -413,6 +413,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/fast-forward/pypy/tool/release/package.py
==============================================================================
--- pypy/branch/fast-forward/pypy/tool/release/package.py (original)
+++ pypy/branch/fast-forward/pypy/tool/release/package.py Mon Dec 6 17:27:34 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/fast-forward/pypy/translator/goal/app_main.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/goal/app_main.py (original)
+++ pypy/branch/fast-forward/pypy/translator/goal/app_main.py Mon Dec 6 17:27:34 2010
@@ -383,8 +383,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/fast-forward/pypy/translator/platform/darwin.py
==============================================================================
--- pypy/branch/fast-forward/pypy/translator/platform/darwin.py (original)
+++ pypy/branch/fast-forward/pypy/translator/platform/darwin.py Mon Dec 6 17:27:34 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