Author: Manuel Jacob Branch: refactor-str-types Changeset: r66184:ee8c9667c732 Date: 2013-08-17 17:05 +0200 http://bitbucket.org/pypy/pypy/changeset/ee8c9667c732/
Log: hg merge default diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -83,7 +83,7 @@ the selection of scientific software) will also work for a build with the builtin backend. -.. _`download`: http://cern.ch/wlav/reflex-2013-04-23.tar.bz2 +.. _`download`: http://cern.ch/wlav/reflex-2013-08-14.tar.bz2 .. _`ROOT`: http://root.cern.ch/ Besides Reflex, you probably need a version of `gccxml`_ installed, which is @@ -98,8 +98,8 @@ To install the standalone version of Reflex, after download:: - $ tar jxf reflex-2013-04-23.tar.bz2 - $ cd reflex-2013-04-23 + $ tar jxf reflex-2013-08-14.tar.bz2 + $ cd reflex-2013-08-14 $ ./build/autogen $ ./configure <usual set of options such as --prefix> $ make && make install diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -119,13 +119,12 @@ except: try: stderr = sys.stderr - except AttributeError: - pass # too bad - else: print >> stderr, 'Error calling sys.excepthook:' originalexcepthook(*sys.exc_info()) print >> stderr print >> stderr, 'Original exception was:' + except: + pass # too bad # we only get here if sys.excepthook didn't do its job originalexcepthook(etype, evalue, etraceback) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -28,16 +28,17 @@ import __pypy__, thread, signal, time, sys def subthread(): + print('subthread started') try: with __pypy__.thread.signals_enabled: thread.interrupt_main() for i in range(10): - print 'x' + print('x') time.sleep(0.1) except BaseException, e: interrupted.append(e) finally: - print 'subthread stops, interrupted=%r' % (interrupted,) + print('subthread stops, interrupted=%r' % (interrupted,)) done.append(None) # This is normally called by app_main.py @@ -53,13 +54,13 @@ try: done = [] interrupted = [] - print '--- start ---' + print('--- start ---') thread.start_new_thread(subthread, ()) for j in range(10): if len(done): break - print '.' + print('.') time.sleep(0.1) - print 'main thread loop done' + print('main thread loop done') assert len(done) == 1 assert len(interrupted) == 1 assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ @@ -80,7 +81,7 @@ def threadfunction(): pid = fork() if pid == 0: - print 'in child' + print('in child') # signal() only works from the 'main' thread signal.signal(signal.SIGUSR1, signal.SIG_IGN) os._exit(42) diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -437,14 +437,14 @@ return self.getrepr(self.space, info) def getdisplayname(self): + space = self.space w_name = self.w_name if w_name is None: return '?' - elif self.space.is_true(self.space.isinstance(w_name, - self.space.w_str)): - return "'%s'" % self.space.str_w(w_name) + elif space.isinstance_w(w_name, space.w_str): + return "'%s'" % space.str_w(w_name) else: - return self.space.str_w(self.space.repr(w_name)) + return space.str_w(space.repr(w_name)) def file_writelines(self, w_lines): """writelines(sequence_of_strings) -> None. Write the strings to the file. diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -11,7 +11,7 @@ from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.objectmodel import keepalive_until_here from rpython.rtyper.lltypesystem import lltype, rffi - +from pypy.objspace.std.floatobject import W_FloatObject @unwrap_spec(typecode=str) def w_array(space, w_cls, typecode, __args__): @@ -532,7 +532,7 @@ class TypeCode(object): - def __init__(self, itemtype, unwrap, canoverflow=False, signed=False): + def __init__(self, itemtype, unwrap, canoverflow=False, signed=False, method='__int__'): self.itemtype = itemtype self.bytes = rffi.sizeof(itemtype) self.arraytype = lltype.Array(itemtype, hints={'nolength': True}) @@ -540,6 +540,7 @@ self.signed = signed self.canoverflow = canoverflow self.w_class = None + self.method = method if self.canoverflow: assert self.bytes <= rffi.sizeof(rffi.ULONG) @@ -554,8 +555,8 @@ return True types = { - 'c': TypeCode(lltype.Char, 'str_w'), - 'u': TypeCode(lltype.UniChar, 'unicode_w'), + 'c': TypeCode(lltype.Char, 'str_w', method=''), + 'u': TypeCode(lltype.UniChar, 'unicode_w', method=''), 'b': TypeCode(rffi.SIGNEDCHAR, 'int_w', True, True), 'B': TypeCode(rffi.UCHAR, 'int_w', True), 'h': TypeCode(rffi.SHORT, 'int_w', True, True), @@ -567,8 +568,8 @@ # rbigint.touint() which # corresponds to the # C-type unsigned long - 'f': TypeCode(lltype.SingleFloat, 'float_w'), - 'd': TypeCode(lltype.Float, 'float_w'), + 'f': TypeCode(lltype.SingleFloat, 'float_w', method='__float__'), + 'd': TypeCode(lltype.Float, 'float_w', method='__float__'), } for k, v in types.items(): v.typecode = k @@ -613,7 +614,19 @@ def item_w(self, w_item): space = self.space unwrap = getattr(space, mytype.unwrap) - item = unwrap(w_item) + try: + item = unwrap(w_item) + except OperationError, e: + if isinstance(w_item, W_FloatObject): # Odd special case from cpython + raise + if mytype.method != '' and e.match(space, space.w_TypeError): + try: + item = unwrap(space.call_method(w_item, mytype.method)) + except OperationError: + msg = 'array item must be ' + mytype.unwrap[:-2] + raise OperationError(space.w_TypeError, space.wrap(msg)) + else: + raise if mytype.unwrap == 'bigint_w': try: item = item.touint() diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -874,6 +874,77 @@ assert l assert l[0] is None or len(l[0]) == 0 + def test_assign_object_with_special_methods(self): + from array import array + + class Num(object): + def __float__(self): + return 5.25 + + def __int__(self): + return 7 + + class NotNum(object): + pass + + class Silly(object): + def __float__(self): + return None + + def __int__(self): + return None + + class OldNum: + def __float__(self): + return 6.25 + + def __int__(self): + return 8 + + class OldNotNum: + pass + + class OldSilly: + def __float__(self): + return None + + def __int__(self): + return None + + for tc in 'bBhHiIlL': + a = array(tc, [0]) + raises(TypeError, a.__setitem__, 0, 1.0) + a[0] = 1 + a[0] = Num() + assert a[0] == 7 + raises(TypeError, a.__setitem__, NotNum()) + a[0] = OldNum() + assert a[0] == 8 + raises(TypeError, a.__setitem__, OldNotNum()) + raises(TypeError, a.__setitem__, Silly()) + raises(TypeError, a.__setitem__, OldSilly()) + + for tc in 'fd': + a = array(tc, [0]) + a[0] = 1.0 + a[0] = 1 + a[0] = Num() + assert a[0] == 5.25 + raises(TypeError, a.__setitem__, NotNum()) + a[0] = OldNum() + assert a[0] == 6.25 + raises(TypeError, a.__setitem__, OldNotNum()) + raises(TypeError, a.__setitem__, Silly()) + raises(TypeError, a.__setitem__, OldSilly()) + + a = array('c', 'hi') + a[0] = 'b' + assert a[0] == 'b' + + a = array('u', u'hi') + a[0] = u'b' + assert a[0] == u'b' + class TestCPythonsOwnArray(BaseArrayTests): diff --git a/pypy/module/cppyy/genreflex-methptrgetter.patch b/pypy/module/cppyy/genreflex-methptrgetter.patch --- a/pypy/module/cppyy/genreflex-methptrgetter.patch +++ b/pypy/module/cppyy/genreflex-methptrgetter.patch @@ -10,7 +10,7 @@ # The next is to avoid a known problem with gccxml that it generates a # references to id equal '_0' which is not defined anywhere self.xref['_0'] = {'elem':'Unknown', 'attrs':{'id':'_0','name':''}, 'subelems':[]} -@@ -1306,6 +1307,8 @@ +@@ -1328,6 +1329,8 @@ bases = self.getBases( attrs['id'] ) if inner and attrs.has_key('demangled') and self.isUnnamedType(attrs['demangled']) : cls = attrs['demangled'] @@ -19,7 +19,7 @@ clt = '' else: cls = self.genTypeName(attrs['id'],const=True,colon=True) -@@ -1343,7 +1346,7 @@ +@@ -1365,7 +1368,7 @@ # Inner class/struct/union/enum. for m in memList : member = self.xref[m] @@ -28,7 +28,7 @@ and member['attrs'].get('access') in ('private','protected') \ and not self.isUnnamedType(member['attrs'].get('demangled')): cmem = self.genTypeName(member['attrs']['id'],const=True,colon=True) -@@ -1981,8 +1984,15 @@ +@@ -2003,8 +2006,15 @@ else : params = '0' s = ' .AddFunctionMember(%s, Reflex::Literal("%s"), %s%s, 0, %s, %s)' % (self.genTypeID(id), name, type, id, params, mod) s += self.genCommentProperty(attrs) @@ -44,7 +44,7 @@ def genMCODef(self, type, name, attrs, args): id = attrs['id'] cl = self.genTypeName(attrs['context'],colon=True) -@@ -2049,8 +2059,44 @@ +@@ -2071,8 +2081,44 @@ if returns == 'void' : body += ' }\n' else : body += ' }\n' body += '}\n' @@ -105,17 +105,16 @@ -h, --help Print this help\n """ -@@ -127,7 +131,8 @@ - opts, args = getopt.getopt(options, 'ho:s:c:I:U:D:PC', \ +@@ -128,7 +132,7 @@ ['help','debug=', 'output=','selection_file=','pool','dataonly','interpreteronly','deep','gccxmlpath=', 'capabilities=','rootmap=','rootmap-lib=','comments','iocomments','no_membertypedefs', -- 'fail_on_warnings', 'quiet', 'gccxmlopt=', 'reflex', 'split=','no_templatetypedefs','gccxmlpost=']) -+ 'fail_on_warnings', 'quiet', 'gccxmlopt=', 'reflex', 'split=','no_templatetypedefs','gccxmlpost=', -+ 'with-methptrgetter']) + 'fail_on_warnings', 'quiet', 'gccxmlopt=', 'reflex', 'split=','no_templatetypedefs','gccxmlpost=', +- 'library=']) ++ 'library=', 'with-methptrgetter']) except getopt.GetoptError, e: print "--->> genreflex: ERROR:",e self.usage(2) -@@ -186,6 +191,8 @@ +@@ -187,6 +191,8 @@ self.rootmap = a if o in ('--rootmap-lib',): self.rootmaplib = a diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -140,6 +140,7 @@ ("deg2rad", "radians"), ("rad2deg", "degrees"), ("reciprocal", "reciprocal"), + ("rint", "rint"), ("sign", "sign"), ("signbit", "signbit"), ("sin", "sin"), @@ -175,6 +176,8 @@ ('logaddexp2', 'logaddexp2'), ('real', 'real'), ('imag', 'imag'), + ('ones_like', 'ones_like'), + ('zeros_like', 'zeros_like'), ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -620,6 +620,7 @@ ("positive", "pos", 1), ("negative", "neg", 1), ("absolute", "abs", 1, {"complex_to_float": True}), + ("rint", "rint", 1), ("sign", "sign", 1, {"promote_bools": True}), ("signbit", "signbit", 1, {"bool_result": True, "allow_complex": False}), @@ -675,6 +676,8 @@ "allow_complex": False}), ("logaddexp2", "logaddexp2", 2, {"promote_to_float": True, "allow_complex": False}), + ("ones_like", "ones_like", 1), + ("zeros_like", "zeros_like", 1), ]: self.add_ufunc(space, *ufunc_def) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -685,3 +685,8 @@ msg=error_message) sys.stderr.write('.') sys.stderr.write('\n') + + def test_complexbox_to_pycomplex(self): + from numpypy import complex128 + x = complex128(3.4j) + assert complex(x) == 3.4j diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -255,6 +255,22 @@ for i in range(3): assert c[i] == a[i] * b[i] + def test_rint(self): + from numpypy import array, complex, rint, isnan + + nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') + + reference = array([ninf, -2., -1., -0., 0., 0., 0., 1., 2., inf]) + a = array([ninf, -1.5, -1., -0.5, -0., 0., 0.5, 1., 1.5, inf]) + b = rint(a) + for i in range(len(a)): + assert b[i] == reference[i] + assert isnan(rint(nan)) + assert isnan(rint(nnan)) + + assert rint(complex(inf, 1.5)) == complex(inf, 2.) + assert rint(complex(0.5, inf)) == complex(0., inf) + def test_sign(self): from numpypy import array, sign, dtype @@ -939,4 +955,18 @@ assert logaddexp2(float('inf'), float('-inf')) == float('inf') assert logaddexp2(float('inf'), float('inf')) == float('inf') + def test_ones_like(self): + from numpypy import array, ones_like + assert ones_like(False) == array(True) + assert ones_like(2) == array(1) + assert ones_like(2.) == array(1.) + assert ones_like(complex(2)) == array(complex(1)) + + def test_zeros_like(self): + from numpypy import array, zeros_like + + assert zeros_like(True) == array(False) + assert zeros_like(2) == array(0) + assert zeros_like(2.) == array(0.) + assert zeros_like(complex(2)) == array(complex(0)) diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -307,6 +307,22 @@ def min(self, v1, v2): return min(v1, v2) + @simple_unary_op + def rint(self, v): + if isfinite(v): + return rfloat.round_double(v, 0, half_even=True) + else: + return v + + @simple_unary_op + def ones_like(self, v): + return 1 + + @simple_unary_op + def zeros_like(self, v): + return 0 + + class NonNativePrimitive(Primitive): _mixin_ = True @@ -1392,11 +1408,14 @@ def round(self, v, decimals=0): ans = list(self.for_computation(self.unbox(v))) if isfinite(ans[0]): - ans[0] = rfloat.round_double(ans[0], decimals, half_even=True) + ans[0] = rfloat.round_double(ans[0], decimals, half_even=True) if isfinite(ans[1]): - ans[1] = rfloat.round_double(ans[1], decimals, half_even=True) + ans[1] = rfloat.round_double(ans[1], decimals, half_even=True) return self.box_complex(ans[0], ans[1]) + def rint(self, v): + return self.round(v) + # No floor, ceil, trunc in numpy for complex #@simple_unary_op #def floor(self, v): @@ -1599,6 +1618,15 @@ except ValueError: return rfloat.NAN, rfloat.NAN + @complex_unary_op + def ones_like(self, v): + return 1, 0 + + @complex_unary_op + def zeros_like(self, v): + return 0, 0 + + class Complex64(ComplexFloating, BaseType): _attrs_ = () diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -723,11 +723,16 @@ for hook in get_fork_hooks(where): hook(space) -def fork(space): +def _run_forking_function(space, kind): run_fork_hooks('before', space) - try: - pid = os.fork() + if kind == "F": + pid = os.fork() + master_fd = -1 + elif kind == "P": + pid, master_fd = os.forkpty() + else: + raise AssertionError except OSError, e: try: run_fork_hooks('parent', space) @@ -735,12 +740,14 @@ # Don't clobber the OSError if the fork failed pass raise wrap_oserror(space, e) - if pid == 0: run_fork_hooks('child', space) else: run_fork_hooks('parent', space) + return pid, master_fd +def fork(space): + pid, irrelevant = _run_forking_function(space, "F") return space.wrap(pid) def openpty(space): @@ -752,10 +759,7 @@ return space.newtuple([space.wrap(master_fd), space.wrap(slave_fd)]) def forkpty(space): - try: - pid, master_fd = os.forkpty() - except OSError, e: - raise wrap_oserror(space, e) + pid, master_fd = _run_forking_function(space, "P") return space.newtuple([space.wrap(pid), space.wrap(master_fd)]) diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py --- a/pypy/objspace/std/complextype.py +++ b/pypy/objspace/std/complextype.py @@ -201,7 +201,7 @@ if w_z is not None: # __complex__() must return a complex or (float,int,long) object # (XXX should not use isinstance here) - if not strict_typing and (space.isinstance_w(w_z, space.w_int) or + if not strict_typing and (space.isinstance_w(w_z, space.w_int) or space.isinstance_w(w_z, space.w_long) or space.isinstance_w(w_z, space.w_float)): return (space.float_w(w_z), 0.0) @@ -214,8 +214,10 @@ # # no '__complex__' method, so we assume it is a float, # unless it is an instance of some subclass of complex. - if isinstance(w_complex, W_ComplexObject): - return (w_complex.realval, w_complex.imagval) + if space.isinstance_w(w_complex, space.gettypefor(W_ComplexObject)): + real = space.float(space.getattr(w_complex, space.wrap("real"))) + imag = space.float(space.getattr(w_complex, space.wrap("imag"))) + return (space.float_w(real), space.float_w(imag)) # # Check that it is not a string (on which space.float() would succeed). if (space.isinstance_w(w_complex, space.w_str) or diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py --- a/pypy/objspace/std/intobject.py +++ b/pypy/objspace/std/intobject.py @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.objspace.std import newformat -from pypy.objspace.std.inttype import wrapint, W_AbstractIntObject +from pypy.objspace.std.inttype import W_AbstractIntObject from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.noneobject import W_NoneObject @@ -55,7 +55,7 @@ if space.is_w(space.type(self), space.w_int): return self a = self.intval - return wrapint(space, a) + return space.newint(a) registerimplementation(W_IntObject) @@ -104,7 +104,7 @@ except OverflowError: raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer addition")) - return wrapint(space, z) + return space.newint(z) def sub__Int_Int(space, w_int1, w_int2): x = w_int1.intval @@ -114,7 +114,7 @@ except OverflowError: raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer substraction")) - return wrapint(space, z) + return space.newint(z) def mul__Int_Int(space, w_int1, w_int2): x = w_int1.intval @@ -124,7 +124,7 @@ except OverflowError: raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer multiplication")) - return wrapint(space, z) + return space.newint(z) def floordiv__Int_Int(space, w_int1, w_int2): x = w_int1.intval @@ -137,7 +137,7 @@ except OverflowError: raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer division")) - return wrapint(space, z) + return space.newint(z) div__Int_Int = floordiv__Int_Int def truediv__Int_Int(space, w_int1, w_int2): @@ -158,7 +158,7 @@ except OverflowError: raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer modulo")) - return wrapint(space, z) + return space.newint(z) def divmod__Int_Int(space, w_int1, w_int2): x = w_int1.intval @@ -231,7 +231,7 @@ except OverflowError: raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer negation")) - return wrapint(space, x) + return space.newint(x) get_negint = neg__Int @@ -247,7 +247,7 @@ def invert__Int(space, w_int1): x = w_int1.intval a = ~x - return wrapint(space, a) + return space.newint(a) def lshift__Int_Int(space, w_int1, w_int2): a = w_int1.intval @@ -258,7 +258,7 @@ except OverflowError: raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer left shift")) - return wrapint(space, c) + return space.newint(c) if b < 0: raise OperationError(space.w_ValueError, space.wrap("negative shift count")) @@ -284,25 +284,25 @@ a = 0 else: a = a >> b - return wrapint(space, a) + return space.newint(a) def and__Int_Int(space, w_int1, w_int2): a = w_int1.intval b = w_int2.intval res = a & b - return wrapint(space, res) + return space.newint(res) def xor__Int_Int(space, w_int1, w_int2): a = w_int1.intval b = w_int2.intval res = a ^ b - return wrapint(space, res) + return space.newint(res) def or__Int_Int(space, w_int1, w_int2): a = w_int1.intval b = w_int2.intval res = a | b - return wrapint(space, res) + return space.newint(res) def pos__Int(self, space): return self.int(space) @@ -323,7 +323,7 @@ return space.wrap(hex(w_int1.intval)) def getnewargs__Int(space, w_int1): - return space.newtuple([wrapint(space, w_int1.intval)]) + return space.newtuple([space.newint(w_int1.intval)]) register_all(vars()) diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py --- a/pypy/objspace/std/listobject.py +++ b/pypy/objspace/std/listobject.py @@ -20,7 +20,6 @@ from pypy.objspace.std.bytesobject import W_BytesObject from pypy.objspace.std.floatobject import W_FloatObject from pypy.objspace.std.intobject import W_IntObject -from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.iterobject import (W_FastListIterObject, W_ReverseSeqIterObject) from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice @@ -427,7 +426,7 @@ def descr_len(self, space): result = self.length() - return wrapint(space, result) + return space.newint(result) def descr_iter(self, space): return W_FastListIterObject(self) diff --git a/pypy/objspace/std/stringmethods.py b/pypy/objspace/std/stringmethods.py --- a/pypy/objspace/std/stringmethods.py +++ b/pypy/objspace/std/stringmethods.py @@ -1,7 +1,6 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.objspace.std import slicetype -from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from rpython.rlib import jit from rpython.rlib.objectmodel import specialize @@ -205,7 +204,7 @@ @specialize.argtype(0) def descr_count(self, space, w_sub, w_start=None, w_end=None): value, start, end = self._convert_idx_params(space, w_start, w_end) - return wrapint(space, value.count(self._op_val(space, w_sub), start, end)) + return space.newint(value.count(self._op_val(space, w_sub), start, end)) @specialize.argtype(0) def descr_decode(self, space, w_encoding=None, w_errors=None): diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -7,7 +7,6 @@ from pypy.interpreter.gateway import ( WrappedDefault, interp2app, interpindirect2app, unwrap_spec) from pypy.objspace.std import slicetype -from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.util import negate @@ -56,7 +55,7 @@ def descr_len(self, space): result = self.length() - return wrapint(space, result) + return space.newint(result) def descr_iter(self, space): from pypy.objspace.std import iterobject diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -382,7 +382,7 @@ from rpython.jit.backend.tool.viewcode import World world = World() for entry in extract_category(log, 'jit-backend-dump'): - world.parse(entry.splitlines(True), truncate_addr=False) + world.parse(entry.splitlines(True)) dumps = {} for r in world.ranges: if r.addr in addrs and addrs[r.addr]: diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -26,10 +26,11 @@ - Add COND_CALLs to the write barrier before SETFIELD_GC and SETARRAYITEM_GC operations. - recent_mallocs contains a dictionary of variable -> None. If a variable - is in the dictionary, next setfields can be called without a write barrier, - because the variable got allocated after the last potentially collecting - resop + 'write_barrier_applied' contains a dictionary of variable -> None. + If a variable is in the dictionary, next setfields can be called without + a write barrier. The idea is that an object that was freshly allocated + or already write_barrier'd don't need another write_barrier if there + was no potentially collecting resop inbetween. """ _previous_size = -1 @@ -42,7 +43,7 @@ self.cpu = cpu self.newops = [] self.known_lengths = {} - self.recent_mallocs = {} + self.write_barrier_applied = {} def rewrite(self, operations): # we can only remember one malloc since the next malloc can possibly @@ -221,18 +222,18 @@ def emitting_an_operation_that_can_collect(self): # must be called whenever we emit an operation that can collect: # forgets the previous MALLOC_NURSERY, if any; and empty the - # set 'recent_mallocs', so that future SETFIELDs will generate + # set 'write_barrier_applied', so that future SETFIELDs will generate # a write barrier as usual. self._op_malloc_nursery = None - self.recent_mallocs.clear() + self.write_barrier_applied.clear() def _gen_call_malloc_gc(self, args, v_result, descr): """Generate a CALL_MALLOC_GC with the given args.""" self.emitting_an_operation_that_can_collect() op = ResOperation(rop.CALL_MALLOC_GC, args, v_result, descr) self.newops.append(op) - # mark 'v_result' as freshly malloced - self.recent_mallocs[v_result] = None + # mark 'v_result' as freshly malloced, so not needing a write barrier + self.write_barrier_applied[v_result] = None def gen_malloc_fixedsize(self, size, typeid, v_result): """Generate a CALL_MALLOC_GC(malloc_fixedsize_fn, ...). @@ -315,7 +316,7 @@ [ConstInt(kind), ConstInt(itemsize), v_length], v_result, descr=arraydescr) self.newops.append(op) - self.recent_mallocs[v_result] = None + self.write_barrier_applied[v_result] = None return True def gen_malloc_nursery_varsize_frame(self, sizebox, v_result): @@ -327,7 +328,7 @@ v_result) self.newops.append(op) - self.recent_mallocs[v_result] = None + self.write_barrier_applied[v_result] = None def gen_malloc_nursery(self, size, v_result): """Try to generate or update a CALL_MALLOC_NURSERY. @@ -360,7 +361,7 @@ self.newops.append(op) self._previous_size = size self._v_last_malloced_nursery = v_result - self.recent_mallocs[v_result] = None + self.write_barrier_applied[v_result] = None return True def gen_initialize_tid(self, v_newgcobj, tid): @@ -382,45 +383,42 @@ def handle_write_barrier_setfield(self, op): val = op.getarg(0) - # no need for a write barrier in the case of previous malloc - if val not in self.recent_mallocs: + if val not in self.write_barrier_applied: v = op.getarg(1) if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and bool(v.value)): # store a non-NULL - self.gen_write_barrier(op.getarg(0), v) - op = op.copy_and_change(rop.SETFIELD_RAW) + self.gen_write_barrier(val) + #op = op.copy_and_change(rop.SETFIELD_RAW) self.newops.append(op) def handle_write_barrier_setinteriorfield(self, op): val = op.getarg(0) - # no need for a write barrier in the case of previous malloc - if val not in self.recent_mallocs: + if val not in self.write_barrier_applied: v = op.getarg(2) if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and bool(v.value)): # store a non-NULL - self.gen_write_barrier(op.getarg(0), v) - op = op.copy_and_change(rop.SETINTERIORFIELD_RAW) + self.gen_write_barrier(val) + #op = op.copy_and_change(rop.SETINTERIORFIELD_RAW) self.newops.append(op) def handle_write_barrier_setarrayitem(self, op): val = op.getarg(0) - # no need for a write barrier in the case of previous malloc - if val not in self.recent_mallocs: + if val not in self.write_barrier_applied: v = op.getarg(2) if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and bool(v.value)): # store a non-NULL - self.gen_write_barrier_array(op.getarg(0), - op.getarg(1), v) - op = op.copy_and_change(rop.SETARRAYITEM_RAW) + self.gen_write_barrier_array(val, op.getarg(1)) + #op = op.copy_and_change(rop.SETARRAYITEM_RAW) self.newops.append(op) - def gen_write_barrier(self, v_base, v_value): + def gen_write_barrier(self, v_base): write_barrier_descr = self.gc_ll_descr.write_barrier_descr - args = [v_base, v_value] + args = [v_base] self.newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None, descr=write_barrier_descr)) + self.write_barrier_applied[v_base] = None - def gen_write_barrier_array(self, v_base, v_index, v_value): + def gen_write_barrier_array(self, v_base, v_index): write_barrier_descr = self.gc_ll_descr.write_barrier_descr if write_barrier_descr.has_write_barrier_from_array(self.cpu): # If we know statically the length of 'v', and it is not too @@ -430,13 +428,15 @@ length = self.known_lengths.get(v_base, LARGE) if length >= LARGE: # unknown or too big: produce a write_barrier_from_array - args = [v_base, v_index, v_value] + args = [v_base, v_index] self.newops.append( ResOperation(rop.COND_CALL_GC_WB_ARRAY, args, None, descr=write_barrier_descr)) + # a WB_ARRAY is not enough to prevent any future write + # barriers, so don't add to 'write_barrier_applied'! return # fall-back case: produce a write_barrier - self.gen_write_barrier(v_base, v_value) + self.gen_write_barrier(v_base) def round_up_for_allocation(self, size): if not self.gc_ll_descr.round_up: diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -202,13 +202,11 @@ rewriter = gc.GcRewriterAssembler(gc_ll_descr, None) newops = rewriter.newops v_base = BoxPtr() - v_value = BoxPtr() - rewriter.gen_write_barrier(v_base, v_value) + rewriter.gen_write_barrier(v_base) assert llop1.record == [] assert len(newops) == 1 assert newops[0].getopnum() == rop.COND_CALL_GC_WB assert newops[0].getarg(0) == v_base - assert newops[0].getarg(1) == v_value assert newops[0].result is None wbdescr = newops[0].getdescr() assert is_valid_int(wbdescr.jit_wb_if_flag) diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -561,8 +561,8 @@ jump() """, """ [p1, p2] - cond_call_gc_wb(p1, p2, descr=wbdescr) - setfield_raw(p1, p2, descr=tzdescr) + cond_call_gc_wb(p1, descr=wbdescr) + setfield_gc(p1, p2, descr=tzdescr) jump() """) @@ -575,8 +575,8 @@ jump() """, """ [p1, i2, p3] - cond_call_gc_wb(p1, p3, descr=wbdescr) - setarrayitem_raw(p1, i2, p3, descr=cdescr) + cond_call_gc_wb(p1, descr=wbdescr) + setarrayitem_gc(p1, i2, p3, descr=cdescr) jump() """) @@ -595,8 +595,8 @@ setfield_gc(p1, 8111, descr=tiddescr) setfield_gc(p1, 129, descr=clendescr) call(123456) - cond_call_gc_wb(p1, p3, descr=wbdescr) - setarrayitem_raw(p1, i2, p3, descr=cdescr) + cond_call_gc_wb(p1, descr=wbdescr) + setarrayitem_gc(p1, i2, p3, descr=cdescr) jump() """) @@ -616,8 +616,8 @@ setfield_gc(p1, 8111, descr=tiddescr) setfield_gc(p1, 130, descr=clendescr) call(123456) - cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr) - setarrayitem_raw(p1, i2, p3, descr=cdescr) + cond_call_gc_wb_array(p1, i2, descr=wbdescr) + setarrayitem_gc(p1, i2, p3, descr=cdescr) jump() """) @@ -628,8 +628,8 @@ jump() """, """ [p1, i2, p3] - cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr) - setarrayitem_raw(p1, i2, p3, descr=cdescr) + cond_call_gc_wb_array(p1, i2, descr=wbdescr) + setarrayitem_gc(p1, i2, p3, descr=cdescr) jump() """) @@ -647,8 +647,8 @@ setfield_gc(p1, 8111, descr=tiddescr) setfield_gc(p1, 5, descr=clendescr) label(p1, i2, p3) - cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr) - setarrayitem_raw(p1, i2, p3, descr=cdescr) + cond_call_gc_wb_array(p1, i2, descr=wbdescr) + setarrayitem_gc(p1, i2, p3, descr=cdescr) jump() """) @@ -666,8 +666,8 @@ jump(p1, p2) """, """ [p1, p2] - cond_call_gc_wb(p1, p2, descr=wbdescr) - setinteriorfield_raw(p1, 0, p2, descr=interiorzdescr) + cond_call_gc_wb(p1, descr=wbdescr) + setinteriorfield_gc(p1, 0, p2, descr=interiorzdescr) jump(p1, p2) """, interiorzdescr=interiorzdescr) @@ -733,8 +733,8 @@ p1 = call_malloc_nursery_varsize(1, 1, i0, \ descr=strdescr) setfield_gc(p1, i0, descr=strlendescr) - cond_call_gc_wb(p0, p1, descr=wbdescr) - setfield_raw(p0, p1, descr=tzdescr) + cond_call_gc_wb(p0, descr=wbdescr) + setfield_gc(p0, p1, descr=tzdescr) jump() """) @@ -750,11 +750,25 @@ p0 = call_malloc_nursery(%(tdescr.size)d) setfield_gc(p0, 5678, descr=tiddescr) label(p0, p1) - cond_call_gc_wb(p0, p1, descr=wbdescr) - setfield_raw(p0, p1, descr=tzdescr) + cond_call_gc_wb(p0, descr=wbdescr) + setfield_gc(p0, p1, descr=tzdescr) jump() """) + def test_multiple_writes(self): + self.check_rewrite(""" + [p0, p1, p2] + setfield_gc(p0, p1, descr=tzdescr) + setfield_gc(p0, p2, descr=tzdescr) + jump(p1, p2, p0) + """, """ + [p0, p1, p2] + cond_call_gc_wb(p0, descr=wbdescr) + setfield_gc(p0, p1, descr=tzdescr) + setfield_gc(p0, p2, descr=tzdescr) + jump(p1, p2, p0) + """) + def test_rewrite_call_assembler(self): self.check_rewrite(""" [i0, f0] diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -2140,11 +2140,9 @@ s = lltype.malloc(S) s.tid = value sgcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) - t = lltype.malloc(S) - tgcref = lltype.cast_opaque_ptr(llmemory.GCREF, t) del record[:] self.execute_operation(rop.COND_CALL_GC_WB, - [BoxPtr(sgcref), ConstPtr(tgcref)], + [BoxPtr(sgcref)], 'void', descr=WriteBarrierDescr()) if cond: assert record == [rffi.cast(lltype.Signed, sgcref)] @@ -2179,7 +2177,7 @@ sgcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) del record[:] self.execute_operation(rop.COND_CALL_GC_WB_ARRAY, - [BoxPtr(sgcref), ConstInt(123), BoxPtr(sgcref)], + [BoxPtr(sgcref), ConstInt(123)], 'void', descr=WriteBarrierDescr()) if cond: assert record == [rffi.cast(lltype.Signed, sgcref)] @@ -2244,7 +2242,7 @@ del record[:] box_index = BoxIndexCls((9<<7) + 17) self.execute_operation(rop.COND_CALL_GC_WB_ARRAY, - [BoxPtr(sgcref), box_index, BoxPtr(sgcref)], + [BoxPtr(sgcref), box_index], 'void', descr=WriteBarrierDescr()) if cond in [0, 1]: assert record == [rffi.cast(lltype.Signed, s.data)] diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py --- a/rpython/jit/backend/tool/viewcode.py +++ b/rpython/jit/backend/tool/viewcode.py @@ -51,18 +51,18 @@ raise ObjdumpNotFound('(g)objdump was not found in PATH') def machine_code_dump(data, originaddr, backend_name, label_list=None): - objdump_backend_option = { + objdump_machine_option = { 'x86': 'i386', 'x86-without-sse2': 'i386', 'x86_32': 'i386', - 'x86_64': 'x86-64', - 'x86-64': 'x86-64', + 'x86_64': 'i386:x86-64', + 'x86-64': 'i386:x86-64', 'i386': 'i386', 'arm': 'arm', 'arm_32': 'arm', } cmd = find_objdump() - objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' + objdump = ('%(command)s -b binary -m %(machine)s ' '--disassembler-options=intel-mnemonics ' '--adjust-vma=%(origin)d -D %(file)s') # @@ -73,8 +73,7 @@ 'command': cmd, 'file': tmpfile, 'origin': originaddr, - 'backend': objdump_backend_option[backend_name], - 'machine': 'i386' if not backend_name.startswith('arm') else 'arm', + 'machine': objdump_machine_option[backend_name], }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert not p.returncode, ('Encountered an error running objdump: %s' % @@ -240,7 +239,7 @@ self.backend_name = None self.executable_name = None - def parse(self, f, textonly=True, truncate_addr=True): + def parse(self, f, textonly=True): for line in f: if line.startswith('BACKEND '): self.backend_name = line.split(' ')[1].strip() @@ -251,9 +250,7 @@ if len(pieces) == 3: continue # empty line baseaddr = long(pieces[1][1:], 16) - if truncate_addr: - baseaddr &= 0xFFFFFFFFL - elif baseaddr < 0: + if baseaddr < 0: baseaddr += (2 * sys.maxint + 2) offset = int(pieces[2][1:]) addr = baseaddr + offset @@ -273,9 +270,7 @@ assert pieces[1].startswith('@') assert pieces[2].startswith('+') baseaddr = long(pieces[1][1:], 16) - if truncate_addr: - baseaddr &= 0xFFFFFFFFL - elif baseaddr < 0: + if baseaddr < 0: baseaddr += (2 * sys.maxint + 2) offset = int(pieces[2][1:]) addr = baseaddr + offset diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -502,8 +502,8 @@ 'SETFIELD_RAW/2d', 'STRSETITEM/3', 'UNICODESETITEM/3', - 'COND_CALL_GC_WB/2d', # [objptr, newvalue] (for the write barrier) - 'COND_CALL_GC_WB_ARRAY/3d', # [objptr, arrayindex, newvalue] (write barr.) + 'COND_CALL_GC_WB/1d', # [objptr] (for the write barrier) + 'COND_CALL_GC_WB_ARRAY/2d', # [objptr, arrayindex] (write barr. for array) 'DEBUG_MERGE_POINT/*', # debugging only 'JIT_DEBUG/*', # debugging only 'VIRTUAL_REF_FINISH/2', # removed before it's passed to the backend diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py --- a/rpython/rtyper/module/ll_os.py +++ b/rpython/rtyper/module/ll_os.py @@ -1574,6 +1574,7 @@ _nowrapper = True) def fork_llimpl(): + # NB. keep forkpty() up-to-date, too opaqueaddr = rthread.gc_thread_before_fork() childpid = rffi.cast(lltype.Signed, os_fork()) rthread.gc_thread_after_fork(childpid, opaqueaddr) @@ -1609,6 +1610,7 @@ @registering_if(os, 'forkpty') def register_os_forkpty(self): + from rpython.rlib import rthread os_forkpty = self.llexternal( 'forkpty', [rffi.INTP, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP], @@ -1616,7 +1618,11 @@ compilation_info=ExternalCompilationInfo(libraries=['util'])) def forkpty_llimpl(): master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') - childpid = os_forkpty(master_p, None, None, None) + master_p[0] = rffi.cast(rffi.INT, -1) + opaqueaddr = rthread.gc_thread_before_fork() + childpid = rffi.cast(lltype.Signed, + os_forkpty(master_p, None, None, None)) + rthread.gc_thread_after_fork(childpid, opaqueaddr) master_fd = master_p[0] lltype.free(master_p, flavor='raw') if childpid == -1: _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit