[pypy-commit] pypy cpyext-macros-cast2: abandon branch
Author: Matti PicusBranch: cpyext-macros-cast2 Changeset: r84393:71ed4229465d Date: 2016-05-12 07:41 +0300 http://bitbucket.org/pypy/pypy/changeset/71ed4229465d/ Log:abandon branch ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: fix _finalize_ signature
Author: Matti PicusBranch: Changeset: r84394:e3a98baf1c1e Date: 2016-05-12 07:51 +0300 http://bitbucket.org/pypy/pypy/changeset/e3a98baf1c1e/ Log:fix _finalize_ signature diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -16,10 +16,11 @@ class W_HKEY(W_Root): def __init__(self, space, hkey): self.hkey = hkey +self.space = space self.register_finalizer(space) -def _finalize_(self, space): -self.Close(space) +def _finalize_(self): +self.Close(self.space) def as_int(self): return rffi.cast(rffi.SIZE_T, self.hkey) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-macros-cast: hg merge default
Author: Devin JeanpierreBranch: cpyext-macros-cast Changeset: r84392:7c4d5229e521 Date: 2016-05-11 16:10 -0700 http://bitbucket.org/pypy/pypy/changeset/7c4d5229e521/ Log:hg merge default diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -89,3 +89,7 @@ Use the new rgc.FinalizerQueue mechanism to clean up the handling of ``__del__`` methods. Fixes notably issue #2287. (All RPython subclasses of W_Root need to use FinalizerQueue now.) + +.. branch: ufunc-outer + +Implement ufunc.outer on numpypy diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -466,6 +466,13 @@ list = self.fired_actions if list is not None: self.fired_actions = None +# NB. in case there are several actions, we reset each +# 'action._fired' to false only when we're about to call +# 'action.perform()'. This means that if +# 'action.fire()' happens to be called any time before +# the corresponding perform(), the fire() has no +# effect---which is the effect we want, because +# perform() will be called anyway. for action in list: action._fired = False action.perform(ec, frame) diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -14,10 +14,11 @@ space.wrap(message)])) class W_HKEY(W_Root): -def __init__(self, hkey): +def __init__(self, space, hkey): self.hkey = hkey +self.register_finalizer(space) -def descr_del(self, space): +def _finalize_(self, space): self.Close(space) def as_int(self): @@ -64,7 +65,7 @@ @unwrap_spec(key=int) def new_HKEY(space, w_subtype, key): hkey = rffi.cast(rwinreg.HKEY, key) -return space.wrap(W_HKEY(hkey)) +return space.wrap(W_HKEY(space, hkey)) descr_HKEY_new = interp2app(new_HKEY) W_HKEY.typedef = TypeDef( @@ -91,7 +92,6 @@ __int__ - Converting a handle to an integer returns the Win32 handle. __cmp__ - Handle objects are compared using the handle value.""", __new__ = descr_HKEY_new, -__del__ = interp2app(W_HKEY.descr_del), __repr__ = interp2app(W_HKEY.descr_repr), __int__ = interp2app(W_HKEY.descr_int), __nonzero__ = interp2app(W_HKEY.descr_nonzero), @@ -480,7 +480,7 @@ ret = rwinreg.RegCreateKey(hkey, subkey, rethkey) if ret != 0: raiseWindowsError(space, ret, 'CreateKey') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(subkey=str, res=int, sam=rffi.r_uint) def CreateKeyEx(space, w_hkey, subkey, res=0, sam=rwinreg.KEY_WRITE): @@ -502,7 +502,7 @@ lltype.nullptr(rwin32.LPDWORD.TO)) if ret != 0: raiseWindowsError(space, ret, 'CreateKeyEx') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(subkey=str) def DeleteKey(space, w_hkey, subkey): @@ -549,7 +549,7 @@ ret = rwinreg.RegOpenKeyEx(hkey, subkey, res, sam, rethkey) if ret != 0: raiseWindowsError(space, ret, 'RegOpenKeyEx') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(index=int) def EnumValue(space, w_hkey, index): @@ -688,7 +688,7 @@ ret = rwinreg.RegConnectRegistry(machine, hkey, rethkey) if ret != 0: raiseWindowsError(space, ret, 'RegConnectRegistry') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(source=unicode) def ExpandEnvironmentStrings(space, source): diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -203,46 +203,46 @@ # id. Invariant: this variable always contain 0 when the PyPy GIL is # released. It should also contain 0 when regular RPython code # executes. In non-cpyext-related code, it will thus always be 0. -# +# # **make_generic_cpy_call():** RPython to C, with the GIL held. Before # the call, must assert that the global variable is 0 and set the # current thread identifier into the global variable. After the call, # assert that the global variable still contains the current thread id, # and reset it to 0. -# +# # **make_wrapper():** C to RPython; by default assume that the GIL is # held, but accepts gil="acquire", "release", "around", # "pygilstate_ensure", "pygilstate_release". -# +# # When a
[pypy-commit] pypy cpyext-macros-cast: Unwrapper: Don't require PyObject* for a void* param that isn't a w_foo.
Author: Devin JeanpierreBranch: cpyext-macros-cast Changeset: r84391:f1c7124eea15 Date: 2016-05-11 15:32 -0700 http://bitbucket.org/pypy/pypy/changeset/f1c7124eea15/ Log:Unwrapper: Don't require PyObject* for a void* param that isn't a w_foo. When it *is* a w_foo, we still require that they be either a real Python object or a PyObject*, of course, because there is no other meaning for a void* w_foo. diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -366,13 +366,22 @@ assert len(args) == len(api_function.argtypes) for i, (ARG, is_wrapped) in types_names_enum_ui: input_arg = args[i] -if (is_PyObject(ARG) or ARG == rffi.VOIDP) and not is_wrapped: +if is_PyObject(ARG) and not is_wrapped: # build a 'PyObject *' (not holding a reference) if not is_pyobj(input_arg): keepalives += (input_arg,) arg = rffi.cast(ARG, as_pyobj(space, input_arg)) else: arg = rffi.cast(ARG, input_arg) +elif ARG == rffi.VOIDP and not is_wrapped: +# unlike is_PyObject case above, we allow any kind of +# argument -- just, if it's an object, we assume the +# caller meant for it to become a PyObject*. +if input_arg is None or isinstance(input_arg, W_Root): +keepalives += (input_arg,) +arg = rffi.cast(ARG, as_pyobj(space, input_arg)) +else: +arg = rffi.cast(ARG, input_arg) elif (is_PyObject(ARG) or ARG == rffi.VOIDP) and is_wrapped: # build a W_Root, possibly from a 'PyObject *' if is_pyobj(input_arg): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-macros-cast: Revert name changes in tests.
Author: Devin JeanpierreBranch: cpyext-macros-cast Changeset: r84389:56ebebbb88b9 Date: 2016-05-11 10:34 -0700 http://bitbucket.org/pypy/pypy/changeset/56ebebbb88b9/ Log:Revert name changes in tests. diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py --- a/pypy/module/cpyext/test/test_datetime.py +++ b/pypy/module/cpyext/test/test_datetime.py @@ -10,9 +10,9 @@ assert api.PyDate_Check(w_date) assert api.PyDate_CheckExact(w_date) -assert api._PyDateTime_GET_YEAR(w_date) == 2010 -assert api._PyDateTime_GET_MONTH(w_date) == 6 -assert api._PyDateTime_GET_DAY(w_date) == 3 +assert api.PyDateTime_GET_YEAR(w_date) == 2010 +assert api.PyDateTime_GET_MONTH(w_date) == 6 +assert api.PyDateTime_GET_DAY(w_date) == 3 def test_time(self, space, api): w_time = api.PyTime_FromTime(23, 15, 40, 123456) @@ -21,10 +21,10 @@ assert api.PyTime_Check(w_time) assert api.PyTime_CheckExact(w_time) -assert api._PyDateTime_TIME_GET_HOUR(w_time) == 23 -assert api._PyDateTime_TIME_GET_MINUTE(w_time) == 15 -assert api._PyDateTime_TIME_GET_SECOND(w_time) == 40 -assert api._PyDateTime_TIME_GET_MICROSECOND(w_time) == 123456 +assert api.PyDateTime_TIME_GET_HOUR(w_time) == 23 +assert api.PyDateTime_TIME_GET_MINUTE(w_time) == 15 +assert api.PyDateTime_TIME_GET_SECOND(w_time) == 40 +assert api.PyDateTime_TIME_GET_MICROSECOND(w_time) == 123456 def test_datetime(self, space, api): w_date = api.PyDateTime_FromDateAndTime( @@ -36,13 +36,13 @@ assert api.PyDate_Check(w_date) assert not api.PyDate_CheckExact(w_date) -assert api._PyDateTime_GET_YEAR(w_date) == 2010 -assert api._PyDateTime_GET_MONTH(w_date) == 6 -assert api._PyDateTime_GET_DAY(w_date) == 3 -assert api._PyDateTime_DATE_GET_HOUR(w_date) == 23 -assert api._PyDateTime_DATE_GET_MINUTE(w_date) == 15 -assert api._PyDateTime_DATE_GET_SECOND(w_date) == 40 -assert api._PyDateTime_DATE_GET_MICROSECOND(w_date) == 123456 +assert api.PyDateTime_GET_YEAR(w_date) == 2010 +assert api.PyDateTime_GET_MONTH(w_date) == 6 +assert api.PyDateTime_GET_DAY(w_date) == 3 +assert api.PyDateTime_DATE_GET_HOUR(w_date) == 23 +assert api.PyDateTime_DATE_GET_MINUTE(w_date) == 15 +assert api.PyDateTime_DATE_GET_SECOND(w_date) == 40 +assert api.PyDateTime_DATE_GET_MICROSECOND(w_date) == 123456 def test_delta(self, space, api): w_delta = space.appexec( @@ -57,9 +57,9 @@ assert api.PyDelta_Check(w_delta) assert api.PyDelta_CheckExact(w_delta) -assert api._PyDateTime_DELTA_GET_DAYS(w_delta) == 10 -assert api._PyDateTime_DELTA_GET_SECONDS(w_delta) == 20 -assert api._PyDateTime_DELTA_GET_MICROSECONDS(w_delta) == 30 +assert api.PyDateTime_DELTA_GET_DAYS(w_delta) == 10 +assert api.PyDateTime_DELTA_GET_SECONDS(w_delta) == 20 +assert api.PyDateTime_DELTA_GET_MICROSECONDS(w_delta) == 30 def test_fromtimestamp(self, space, api): w_args = space.wrap((0,)) diff --git a/pypy/module/cpyext/test/test_floatobject.py b/pypy/module/cpyext/test/test_floatobject.py --- a/pypy/module/cpyext/test/test_floatobject.py +++ b/pypy/module/cpyext/test/test_floatobject.py @@ -6,7 +6,7 @@ def test_floatobject(self, space, api): assert space.unwrap(api.PyFloat_FromDouble(3.14)) == 3.14 assert api.PyFloat_AsDouble(space.wrap(23.45)) == 23.45 -assert api._PyFloat_AS_DOUBLE(space.wrap(23.45)) == 23.45 +assert api.PyFloat_AS_DOUBLE(space.wrap(23.45)) == 23.45 assert api.PyFloat_AsDouble(space.w_None) == -1 api.PyErr_Clear() diff --git a/pypy/module/cpyext/test/test_intobject.py b/pypy/module/cpyext/test/test_intobject.py --- a/pypy/module/cpyext/test/test_intobject.py +++ b/pypy/module/cpyext/test/test_intobject.py @@ -9,7 +9,7 @@ assert not api.PyInt_Check(space.wrap((1, 2, 3))) for i in [3, -5, -1, -sys.maxint, sys.maxint - 1]: x = api.PyInt_AsLong(space.wrap(i)) -y = api._PyInt_AS_LONG(space.wrap(i)) +y = api.PyInt_AS_LONG(space.wrap(i)) assert x == i assert y == i w_x = api.PyInt_FromLong(x + 1) diff --git a/pypy/module/cpyext/test/test_listobject.py b/pypy/module/cpyext/test/test_listobject.py --- a/pypy/module/cpyext/test/test_listobject.py +++ b/pypy/module/cpyext/test/test_listobject.py @@ -22,9 +22,9 @@ def test_get_size(self, space, api): l = api.PyList_New(0) -assert api._PyList_GET_SIZE(l) == 0 +assert api.PyList_GET_SIZE(l) == 0 api.PyList_Append(l, space.wrap(3)) -assert api._PyList_GET_SIZE(l) == 1 +assert api.PyList_GET_SIZE(l) == 1
[pypy-commit] pypy cpyext-macros-cast: Accept PyObject*s through void* for the macro implementations that cast.
Author: Devin JeanpierreBranch: cpyext-macros-cast Changeset: r84390:f53e46cf5a82 Date: 2016-05-11 14:07 -0700 http://bitbucket.org/pypy/pypy/changeset/f53e46cf5a82/ Log:Accept PyObject*s through void* for the macro implementations that cast. This entails a change to the cpython_api wrapper/unwrapper so that it understands that void* is a valid place to get a python object from, and a valid place to store a python object to (as a PyObject*). diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -366,14 +366,14 @@ assert len(args) == len(api_function.argtypes) for i, (ARG, is_wrapped) in types_names_enum_ui: input_arg = args[i] -if is_PyObject(ARG) and not is_wrapped: +if (is_PyObject(ARG) or ARG == rffi.VOIDP) and not is_wrapped: # build a 'PyObject *' (not holding a reference) if not is_pyobj(input_arg): keepalives += (input_arg,) arg = rffi.cast(ARG, as_pyobj(space, input_arg)) else: arg = rffi.cast(ARG, input_arg) -elif is_PyObject(ARG) and is_wrapped: +elif (is_PyObject(ARG) or ARG == rffi.VOIDP) and is_wrapped: # build a W_Root, possibly from a 'PyObject *' if is_pyobj(input_arg): arg = from_ref(space, input_arg) @@ -859,6 +859,10 @@ if is_PyObject(typ) and is_wrapped: assert is_pyobj(arg) arg_conv = from_ref(space, rffi.cast(PyObject, arg)) +elif typ == rffi.VOIDP and is_wrapped: +# Many macros accept a void* so that one can pass a +# PyObject* or a PySomeSubtype*. +arg_conv = from_ref(space, rffi.cast(PyObject, arg)) else: arg_conv = arg boxed_args += (arg_conv, ) diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py --- a/pypy/module/cpyext/cdatetime.py +++ b/pypy/module/cpyext/cdatetime.py @@ -178,67 +178,67 @@ # Accessors -@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL) def PyDateTime_GET_YEAR(space, w_obj): """Return the year, as a positive int. """ return space.int_w(space.getattr(w_obj, space.wrap("year"))) -@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL) def PyDateTime_GET_MONTH(space, w_obj): """Return the month, as an int from 1 through 12. """ return space.int_w(space.getattr(w_obj, space.wrap("month"))) -@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL) def PyDateTime_GET_DAY(space, w_obj): """Return the day, as an int from 1 through 31. """ return space.int_w(space.getattr(w_obj, space.wrap("day"))) -@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL) def PyDateTime_DATE_GET_HOUR(space, w_obj): """Return the hour, as an int from 0 through 23. """ return space.int_w(space.getattr(w_obj, space.wrap("hour"))) -@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL) def PyDateTime_DATE_GET_MINUTE(space, w_obj): """Return the minute, as an int from 0 through 59. """ return space.int_w(space.getattr(w_obj, space.wrap("minute"))) -@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL) def PyDateTime_DATE_GET_SECOND(space, w_obj): """Return the second, as an int from 0 through 59. """ return space.int_w(space.getattr(w_obj, space.wrap("second"))) -@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL) def PyDateTime_DATE_GET_MICROSECOND(space, w_obj): """Return the microsecond, as an int from 0 through 99. """ return space.int_w(space.getattr(w_obj, space.wrap("microsecond"))) -@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL) def PyDateTime_TIME_GET_HOUR(space, w_obj): """Return the hour, as an int from 0 through 23. """ return space.int_w(space.getattr(w_obj, space.wrap("hour"))) -@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL) +@cpython_api([rffi.VOIDP], rffi.INT_real,
[pypy-commit] pypy cpyext-macros-cast: Back out non-test changes, since I'm going to rewrite how I make the tests pass.
Author: Devin JeanpierreBranch: cpyext-macros-cast Changeset: r84388:b3124c608c44 Date: 2016-05-11 09:47 -0700 http://bitbucket.org/pypy/pypy/changeset/b3124c608c44/ Log:Back out non-test changes, since I'm going to rewrite how I make the tests pass. hg backout cf292fe --no-commit hg status -n | grep test/ | xargs hg revert diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py --- a/pypy/module/cpyext/cdatetime.py +++ b/pypy/module/cpyext/cdatetime.py @@ -179,67 +179,67 @@ # Accessors @cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_GET_YEAR(space, w_obj): +def PyDateTime_GET_YEAR(space, w_obj): """Return the year, as a positive int. """ return space.int_w(space.getattr(w_obj, space.wrap("year"))) @cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_GET_MONTH(space, w_obj): +def PyDateTime_GET_MONTH(space, w_obj): """Return the month, as an int from 1 through 12. """ return space.int_w(space.getattr(w_obj, space.wrap("month"))) @cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_GET_DAY(space, w_obj): +def PyDateTime_GET_DAY(space, w_obj): """Return the day, as an int from 1 through 31. """ return space.int_w(space.getattr(w_obj, space.wrap("day"))) @cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_DATE_GET_HOUR(space, w_obj): +def PyDateTime_DATE_GET_HOUR(space, w_obj): """Return the hour, as an int from 0 through 23. """ return space.int_w(space.getattr(w_obj, space.wrap("hour"))) @cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_DATE_GET_MINUTE(space, w_obj): +def PyDateTime_DATE_GET_MINUTE(space, w_obj): """Return the minute, as an int from 0 through 59. """ return space.int_w(space.getattr(w_obj, space.wrap("minute"))) @cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_DATE_GET_SECOND(space, w_obj): +def PyDateTime_DATE_GET_SECOND(space, w_obj): """Return the second, as an int from 0 through 59. """ return space.int_w(space.getattr(w_obj, space.wrap("second"))) @cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_DATE_GET_MICROSECOND(space, w_obj): +def PyDateTime_DATE_GET_MICROSECOND(space, w_obj): """Return the microsecond, as an int from 0 through 99. """ return space.int_w(space.getattr(w_obj, space.wrap("microsecond"))) @cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_TIME_GET_HOUR(space, w_obj): +def PyDateTime_TIME_GET_HOUR(space, w_obj): """Return the hour, as an int from 0 through 23. """ return space.int_w(space.getattr(w_obj, space.wrap("hour"))) @cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_TIME_GET_MINUTE(space, w_obj): +def PyDateTime_TIME_GET_MINUTE(space, w_obj): """Return the minute, as an int from 0 through 59. """ return space.int_w(space.getattr(w_obj, space.wrap("minute"))) @cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_TIME_GET_SECOND(space, w_obj): +def PyDateTime_TIME_GET_SECOND(space, w_obj): """Return the second, as an int from 0 through 59. """ return space.int_w(space.getattr(w_obj, space.wrap("second"))) @cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_TIME_GET_MICROSECOND(space, w_obj): +def PyDateTime_TIME_GET_MICROSECOND(space, w_obj): """Return the microsecond, as an int from 0 through 99. """ return space.int_w(space.getattr(w_obj, space.wrap("microsecond"))) @@ -249,13 +249,13 @@ # for types defined in a python module like lib/datetime.py. @cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_DELTA_GET_DAYS(space, w_obj): +def PyDateTime_DELTA_GET_DAYS(space, w_obj): return space.int_w(space.getattr(w_obj, space.wrap("days"))) @cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_DELTA_GET_SECONDS(space, w_obj): +def PyDateTime_DELTA_GET_SECONDS(space, w_obj): return space.int_w(space.getattr(w_obj, space.wrap("seconds"))) @cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL) -def _PyDateTime_DELTA_GET_MICROSECONDS(space, w_obj): +def PyDateTime_DELTA_GET_MICROSECONDS(space, w_obj): return space.int_w(space.getattr(w_obj, space.wrap("microseconds"))) diff --git a/pypy/module/cpyext/floatobject.py b/pypy/module/cpyext/floatobject.py --- a/pypy/module/cpyext/floatobject.py +++ b/pypy/module/cpyext/floatobject.py @@ -49,7 +49,7 @@ return space.float_w(space.float(w_obj)) @cpython_api([PyObject], lltype.Float, error=CANNOT_FAIL) -def _PyFloat_AS_DOUBLE(space, w_float): +def PyFloat_AS_DOUBLE(space, w_float):
[pypy-commit] pypy shadowstack-perf-2: expand_pop_roots
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84387:5b47be0086d7 Date: 2016-05-11 20:49 +0200 http://bitbucket.org/pypy/pypy/changeset/5b47be0086d7/ Log:expand_pop_roots diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -113,6 +113,11 @@ return SpaceOperation('gc_save_root', [c_index, var], varoftype(lltype.Void)) +def _gc_restore_root(index, var): +c_index = Constant(index, lltype.Signed) +return SpaceOperation('gc_restore_root', [c_index, var], + varoftype(lltype.Void)) + c_NULL = Constant(lltype.nullptr(llmemory.GCREF.TO), llmemory.GCREF) def make_bitmask(filled): @@ -128,6 +133,7 @@ bitmask <<= (i - last_index) last_index = i bitmask |= 1 +assert bitmask & 1 return (last_index, Constant(bitmask, lltype.Signed)) @@ -141,14 +147,23 @@ assert not filled[index] filled[index] = True yield _gc_save_root(index, v) -bitmask_index, bitmask_v = make_bitmask(filled) +bitmask_index, bitmask_c = make_bitmask(filled) if bitmask_index is not None: -yield _gc_save_root(bitmask_index, bitmask_v) +yield _gc_save_root(bitmask_index, bitmask_c) + +def expand_one_pop_roots(regalloc, args): +if regalloc is None: +assert len(args) == 0 +else: +for v in args: +index = regalloc.getcolor(v) +yield _gc_restore_root(index, v) def expand_push_roots(graph, regalloc): """Expand gc_push_roots into a series of gc_save_root, including -writing a bitmask tag to mark some entries as not-in-use +writing a bitmask tag to mark some entries as not-in-use. +(If regalloc is None, it will still remove empty gc_push_roots.) """ for block in graph.iterblocks(): any_change = False @@ -200,18 +215,22 @@ x.x.x.x -def expand_push_pop_roots(graph): -x +def expand_pop_roots(graph): +"""gc_pop_roots => series of gc_restore_root; this is done after +move_pushes_earlier() because that one doesn't work correctly if +a completely-empty gc_pop_roots is removed. +""" for block in graph.iterblocks(): +any_change = False +newops = [] for op in block.operations: -if op.opname == 'gc_push_roots': -for v in op.args: -interesting_vars.add(v) -pending_pred.append((block, v)) -elif op.opname == 'gc_pop_roots': -for v in op.args: -assert v in interesting_vars # must be pushed just above -pending_succ.append((block, v)) +if op.opname == 'gc_pop_roots': +newops += expand_one_pop_roots(regalloc, op) +any_change = True +else: +newops.append(op) +if any_change: +block.operations = newops def postprocess_graph(gct, graph): @@ -219,4 +238,7 @@ added in this complete graph, and replace them with real operations. """ regalloc = allocate_registers(graph) +expand_push_roots(graph, regalloc) +move_pushes_earlier(graph, regalloc) +expand_pop_roots(graph, regalloc) diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -29,8 +29,7 @@ def push_roots(self, hop, keep_current_args=False): livevars = self.get_livevars_for_roots(hop, keep_current_args) self.num_pushs += len(livevars) -if livevars: -hop.genop("gc_push_roots", livevars) +hop.genop("gc_push_roots", livevars) return livevars def pop_roots(self, hop, livevars): diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py --- a/rpython/memory/gctransform/test/test_shadowcolor.py +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -268,27 +268,44 @@ class FakeRegAlloc: -def __init__(self, **colors): +def __init__(self, expected_op, **colors): +self.expected_op = expected_op self.numcolors = len(colors) self.getcolor = colors.__getitem__ -def check_expand_one_push_roots(regalloc, args): -got = list(expand_one_push_roots(regalloc, args)) -result = [] -for spaceop in got: -assert spaceop.opname == 'gc_save_root' -result.append((spaceop.args[0].value, spaceop.args[1])) -return result +def check(self, got): +got = list(got) +result = [] +for spaceop in got: +assert spaceop.opname == self.expected_op +
[pypy-commit] pypy default: Clean up code and debugging artifacts
Author: Ronan LamyBranch: Changeset: r84386:63ca6c7d90a0 Date: 2016-05-11 19:41 +0100 http://bitbucket.org/pypy/pypy/changeset/63ca6c7d90a0/ Log:Clean up code and debugging artifacts diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -292,11 +292,7 @@ def get_wrapper(self, space): wrapper = getattr(self, '_wrapper', None) if wrapper is None: -wrapper = self._make_wrapper(space) -self._wrapper = wrapper -wrapper.relax_sig_check = True -if self.c_name is not None: -wrapper.c_name = cpyext_namespace.uniquename(self.c_name) +wrapper = self._wrapper = self._make_wrapper(space) return wrapper # Make the wrapper for the cases (1) and (2) @@ -306,11 +302,8 @@ # big wrapper() function for every callable. Instead we create # only one per "signature". -callable = self.callable -gil = self.gil -argnames = self.argnames argtypesw = zip(self.argtypes, -[_name.startswith("w_") for _name in argnames]) +[_name.startswith("w_") for _name in self.argnames]) error_value = getattr(self, "error_value", CANNOT_FAIL) if (isinstance(self.restype, lltype.Ptr) and error_value is not CANNOT_FAIL): @@ -329,19 +322,15 @@ self.restype, result_kind, error_value, -gil) +self.gil) cache = space.fromcache(WrapperCache) -cache.stats[1] += 1 try: wrapper_gen = cache.wrapper_gens[signature] except KeyError: -#print signature -wrapper_gen = cache.wrapper_gens[signature] = WrapperGen(space, -signature) -cache.stats[0] += 1 -#print 'Wrapper cache [wrappers/total]:', cache.stats -wrapper = wrapper_gen.make_wrapper(callable) +wrapper_gen = WrapperGen(space, signature) +cache.wrapper_gens[signature] = wrapper_gen +wrapper = wrapper_gen.make_wrapper(self.callable) wrapper.relax_sig_check = True if self.c_name is not None: wrapper.c_name = cpyext_namespace.uniquename(self.c_name) @@ -731,7 +720,6 @@ def __init__(self, space): self.space = space self.wrapper_gens = {}# {signature: WrapperGen()} -self.stats = [0, 0] class WrapperGen(object): wrapper_second_level = None ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy shadowstack-perf-2: Test
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84385:09e14faba25a Date: 2016-05-11 20:36 +0200 http://bitbucket.org/pypy/pypy/changeset/09e14faba25a/ Log:Test diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -1,5 +1,6 @@ from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.flowspace.model import mkentrymap, Variable, Constant +from rpython.flowspace.model import mkentrymap +from rpython.flowspace.model import Variable, Constant, SpaceOperation from rpython.tool.algo.regalloc import perform_register_allocation from rpython.translator.unsimplify import varoftype @@ -130,6 +131,21 @@ return (last_index, Constant(bitmask, lltype.Signed)) +def expand_one_push_roots(regalloc, args): +if regalloc is None: +assert len(args) == 0 +else: +filled = [False] * regalloc.numcolors +for v in args: +index = regalloc.getcolor(v) +assert not filled[index] +filled[index] = True +yield _gc_save_root(index, v) +bitmask_index, bitmask_v = make_bitmask(filled) +if bitmask_index is not None: +yield _gc_save_root(bitmask_index, bitmask_v) + + def expand_push_roots(graph, regalloc): """Expand gc_push_roots into a series of gc_save_root, including writing a bitmask tag to mark some entries as not-in-use @@ -139,18 +155,7 @@ newops = [] for op in block.operations: if op.opname == 'gc_push_roots': -if regalloc is None: -assert len(op.args) == 0 -else: -filled = [False] * regalloc.numcolors -for v in op.args: -index = regalloc.getcolor(v) -assert not filled[index] -filled[index] = True -newops.append(_gc_save_root(index, v)) -bitmask_index, bitmask_v = make_bitmask(filled) -if bitmask_index is not None: -newops.append(_gc_save_root(bitmask_index, bitmask_v)) +newops += expand_one_push_roots(regalloc, op) any_change = True else: newops.append(op) diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py --- a/rpython/memory/gctransform/test/test_shadowcolor.py +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -265,3 +265,30 @@ bitmask >>= 1 index -= 1 assert boollist == [True] * len(boollist) + + +class FakeRegAlloc: +def __init__(self, **colors): +self.numcolors = len(colors) +self.getcolor = colors.__getitem__ + +def check_expand_one_push_roots(regalloc, args): +got = list(expand_one_push_roots(regalloc, args)) +result = [] +for spaceop in got: +assert spaceop.opname == 'gc_save_root' +result.append((spaceop.args[0].value, spaceop.args[1])) +return result + +def test_expand_one_push_roots(): +regalloc = FakeRegAlloc(a=0, b=1, c=2) +assert check_expand_one_push_roots(regalloc, ['a', 'b', 'c']) == [ +(0, 'a'), (1, 'b'), (2, 'c')] +assert check_expand_one_push_roots(regalloc, ['a', 'c']) == [ +(0, 'a'), (2, 'c'), (1, c_NULL)] +assert check_expand_one_push_roots(regalloc, ['b']) == [ +(1, 'b'), (2, Constant(0x5, lltype.Signed))] +assert check_expand_one_push_roots(regalloc, ['a']) == [ +(0, 'a'), (2, Constant(0x3, lltype.Signed))] +assert check_expand_one_push_roots(regalloc, []) == [ +(2, Constant(0x7, lltype.Signed))] ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy shadowstack-perf-2: in-progress, hypothesis testing of the bitmask encoding
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84384:56e5c4403abf Date: 2016-05-11 20:22 +0200 http://bitbucket.org/pypy/pypy/changeset/56e5c4403abf/ Log:in-progress, hypothesis testing of the bitmask encoding diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -1,5 +1,7 @@ -from rpython.flowspace.model import mkentrymap, Variable +from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.flowspace.model import mkentrymap, Variable, Constant from rpython.tool.algo.regalloc import perform_register_allocation +from rpython.translator.unsimplify import varoftype def is_trivial_rewrite(op): @@ -77,6 +79,8 @@ for v in op.args: assert v in interesting_vars # must be pushed just above pending_succ.append((block, v)) +if not interesting_vars: +return None # If there is a path from a gc_pop_roots(v) to a subsequent # gc_push_roots(w) where w contains the same value as v along that @@ -96,36 +100,115 @@ def allocate_registers(graph): interesting_vars = find_interesting_variables(graph) +if not interesting_vars: +return None regalloc = perform_register_allocation(graph, interesting_vars.__contains__) +regalloc.find_num_colors() return regalloc -def move_pushes_earlier(graph): +def _gc_save_root(index, var): +c_index = Constant(index, lltype.Signed) +return SpaceOperation('gc_save_root', [c_index, var], + varoftype(lltype.Void)) + +c_NULL = Constant(lltype.nullptr(llmemory.GCREF.TO), llmemory.GCREF) + +def make_bitmask(filled): +n = filled.count(False) +if n == 0: +return (None, None) +if n == 1: +return (filled.index(False), c_NULL) +bitmask = 0 +last_index = 0 +for i in range(len(filled)): +if not filled[i]: +bitmask <<= (i - last_index) +last_index = i +bitmask |= 1 +return (last_index, Constant(bitmask, lltype.Signed)) + + +def expand_push_roots(graph, regalloc): +"""Expand gc_push_roots into a series of gc_save_root, including +writing a bitmask tag to mark some entries as not-in-use +""" +for block in graph.iterblocks(): +any_change = False +newops = [] +for op in block.operations: +if op.opname == 'gc_push_roots': +if regalloc is None: +assert len(op.args) == 0 +else: +filled = [False] * regalloc.numcolors +for v in op.args: +index = regalloc.getcolor(v) +assert not filled[index] +filled[index] = True +newops.append(_gc_save_root(index, v)) +bitmask_index, bitmask_v = make_bitmask(filled) +if bitmask_index is not None: +newops.append(_gc_save_root(bitmask_index, bitmask_v)) +any_change = True +else: +newops.append(op) +if any_change: +block.operations = newops + + +def move_pushes_earlier(graph, regalloc): """gc_push_roots and gc_pop_roots are pushes/pops to the shadowstack, immediately enclosing the operation that needs them (typically a call). Here, we try to move individual pushes earlier, in fact as early as possible under the following conditions: we only move it across vars that are 'interesting_vars'; and we stop when we encounter the -operation that produces the value, or when we encounter a gc_pop_roots -that pops off the same stack location. In the latter case, if that -gc_pop_roots pops the same value out of the same stack location, then -success: we can remove the gc_push_root on that path. +operation that produces the value, or when we encounter a gc_pop_roots. +In the latter case, if that gc_pop_roots pops the same value out of the +same stack location, then success: we can remove the gc_push_root on +that path. If the process succeeds to remove the gc_push_root along at least one path, we generate it explicitly on the other paths, and we remove the original gc_push_root. If the process doesn't succeed in doing any such removal, we don't do anything. +""" +# Concrete example (assembler tested on x86-64 gcc 5.3 and clang 3.7): +# +# original move_pushes_earlier +# +# while (a > 10) { *foo = b; +# *foo = b; while (a > 10) { +# a = g(a); a = g(a); +# b = *foo; b = *foo; +#// *foo = b; +# } } +# return b;
[pypy-commit] pypy default: turn make_wrapper() into a method of ApiFunction
Author: Ronan LamyBranch: Changeset: r84383:51732368583f Date: 2016-05-11 19:21 +0100 http://bitbucket.org/pypy/pypy/changeset/51732368583f/ Log:turn make_wrapper() into a method of ApiFunction diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -203,46 +203,46 @@ # id. Invariant: this variable always contain 0 when the PyPy GIL is # released. It should also contain 0 when regular RPython code # executes. In non-cpyext-related code, it will thus always be 0. -# +# # **make_generic_cpy_call():** RPython to C, with the GIL held. Before # the call, must assert that the global variable is 0 and set the # current thread identifier into the global variable. After the call, # assert that the global variable still contains the current thread id, # and reset it to 0. -# +# # **make_wrapper():** C to RPython; by default assume that the GIL is # held, but accepts gil="acquire", "release", "around", # "pygilstate_ensure", "pygilstate_release". -# +# # When a wrapper() is called: -# +# # * "acquire": assert that the GIL is not currently held, i.e. the # global variable does not contain the current thread id (otherwise, # deadlock!). Acquire the PyPy GIL. After we acquired it, assert # that the global variable is 0 (it must be 0 according to the # invariant that it was 0 immediately before we acquired the GIL, # because the GIL was released at that point). -# +# # * gil=None: we hold the GIL already. Assert that the current thread # identifier is in the global variable, and replace it with 0. -# +# # * "pygilstate_ensure": if the global variable contains the current # thread id, replace it with 0 and set the extra arg to 0. Otherwise, # do the "acquire" and set the extra arg to 1. Then we'll call # pystate.py:PyGILState_Ensure() with this extra arg, which will do # the rest of the logic. -# +# # When a wrapper() returns, first assert that the global variable is # still 0, and then: -# +# # * "release": release the PyPy GIL. The global variable was 0 up to # and including at the point where we released the GIL, but afterwards # it is possible that the GIL is acquired by a different thread very # quickly. -# +# # * gil=None: we keep holding the GIL. Set the current thread # identifier into the global variable. -# +# # * "pygilstate_release": if the argument is PyGILState_UNLOCKED, # release the PyPy GIL; otherwise, set the current thread identifier # into the global variable. The rest of the logic of @@ -254,7 +254,7 @@ cpyext_namespace = NameManager('cpyext_') -class ApiFunction: +class ApiFunction(object): def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED, c_name=None, gil=None, result_borrowed=False, result_is_ll=False): self.argtypes = argtypes @@ -292,13 +292,61 @@ def get_wrapper(self, space): wrapper = getattr(self, '_wrapper', None) if wrapper is None: -wrapper = make_wrapper(space, self.callable, self.gil) +wrapper = self._make_wrapper(space) self._wrapper = wrapper wrapper.relax_sig_check = True if self.c_name is not None: wrapper.c_name = cpyext_namespace.uniquename(self.c_name) return wrapper +# Make the wrapper for the cases (1) and (2) +def _make_wrapper(self, space): +"NOT_RPYTHON" +# This logic is obscure, because we try to avoid creating one +# big wrapper() function for every callable. Instead we create +# only one per "signature". + +callable = self.callable +gil = self.gil +argnames = self.argnames +argtypesw = zip(self.argtypes, +[_name.startswith("w_") for _name in argnames]) +error_value = getattr(self, "error_value", CANNOT_FAIL) +if (isinstance(self.restype, lltype.Ptr) +and error_value is not CANNOT_FAIL): +assert lltype.typeOf(error_value) == self.restype +assert not error_value# only support error=NULL +error_value = 0# because NULL is not hashable + +if self.result_is_ll: +result_kind = "L" +elif self.result_borrowed: +result_kind = "B" # note: 'result_borrowed' is ignored if we also +else: # say 'result_is_ll=True' (in this case it's +result_kind = "." # up to you to handle refcounting anyway) + +signature = (tuple(argtypesw), +self.restype, +result_kind, +error_value, +gil) + +cache = space.fromcache(WrapperCache) +cache.stats[1] += 1 +try: +wrapper_gen = cache.wrapper_gens[signature] +except KeyError: +#print signature +
[pypy-commit] pypy guard-compatible: merge default
Author: Carl Friedrich BolzBranch: guard-compatible Changeset: r84382:608b83492e8d Date: 2016-05-11 18:17 +0200 http://bitbucket.org/pypy/pypy/changeset/608b83492e8d/ Log:merge default diff too long, truncating to 2000 out of 54659 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -20,3 +20,5 @@ 5f8302b8bf9f53056e40426f10c72151564e5b19 release-4.0.1 246c9cf22037b11dc0e8c29ce3f291d3b8c5935a release-5.0 bbd45126bc691f669c4ebdfbd74456cd274c6b92 release-5.0.1 +3260adbeba4a8b6659d1cc0d0b41f266769b74da release-5.1 +b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -111,23 +111,24 @@ Simon Burton Martin Matusiak Konstantin Lopuhin + Stefano Rivera Wenzhu Man John Witulski Laurence Tratt Ivan Sichmann Freitas Greg Price Dario Bertini - Stefano Rivera Mark Pearse Simon Cross + Edd Barrett Andreas Sthrk - Edd Barrett Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov + Spenser Bauman Jeremy Thurgood Pawe Piotr Przeradowski - Spenser Bauman + Tobias Pape Paul deGrandis Ilya Osadchiy marky1991 @@ -139,7 +140,7 @@ Georg Brandl Bert Freudenberg Stian Andreassen - Tobias Pape + Mark Young Wanja Saatkamp Gerald Klix Mike Blume @@ -170,9 +171,9 @@ Yichao Yu Rocco Moretti Gintautas Miliauskas + Devin Jeanpierre Michael Twomey Lucian Branescu Mihaila - Devin Jeanpierre Gabriel Lavoie Olivier Dormond Jared Grubb @@ -183,6 +184,7 @@ Victor Stinner Andrews Medina anatoly techtonik + Sergey Matyunin Stuart Williams Jasper Schulz Christian Hudon @@ -217,7 +219,6 @@ Arjun Naik Valentina Mukhamedzhanova Stefano Parmesan - Mark Young Alexis Daboville Jens-Uwe Mager Carl Meyer @@ -225,7 +226,9 @@ Pieter Zieschang Gabriel Lukas Vacek + Kunal Grover Andrew Dalke + Florin Papa Sylvain Thenault Jakub Stasiak Nathan Taylor @@ -240,7 +243,6 @@ Kristjan Valur Jonsson David Lievens Neil Blakey-Milner - Sergey Matyunin Lutz Paelike Lucio Torre Lars Wassermann @@ -252,9 +254,11 @@ Artur Lisiecki Sergey Kishchenko Ignas Mikalajunas + Alecsandru Patrascu Christoph Gerum Martin Blais Lene Wagner + Catalin Gabriel Manciu Tomo Cocoa Kim Jin Su Toni Mattis @@ -291,6 +295,7 @@ Akira Li Gustavo Niemeyer Stephan Busemann + florinpapa Rafa Gaczyski Matt Bogosian Christian Muirhead @@ -305,6 +310,7 @@ Boglarka Vezer Chris Pressey Buck Golemon + Diana Popa Konrad Delong Dinu Gherman Chris Lambacher diff --git a/dotviewer/graphserver.py b/dotviewer/graphserver.py --- a/dotviewer/graphserver.py +++ b/dotviewer/graphserver.py @@ -143,6 +143,11 @@ if __name__ == '__main__': if len(sys.argv) != 2: +if len(sys.argv) == 1: +# start locally +import sshgraphserver +sshgraphserver.ssh_graph_server(['LOCAL']) +sys.exit(0) print >> sys.stderr, __doc__ sys.exit(2) if sys.argv[1] == '--stdio': diff --git a/dotviewer/sshgraphserver.py b/dotviewer/sshgraphserver.py --- a/dotviewer/sshgraphserver.py +++ b/dotviewer/sshgraphserver.py @@ -4,11 +4,14 @@ Usage: sshgraphserver.py hostname [more args for ssh...] +sshgraphserver.py LOCAL This logs in to 'hostname' by passing the arguments on the command-line to ssh. No further configuration is required: it works for all programs using the dotviewer library as long as they run on 'hostname' under the same username as the one sshgraphserver logs as. + +If 'hostname' is the string 'LOCAL', then it starts locally without ssh. """ import graphserver, socket, subprocess, random @@ -18,12 +21,19 @@ s1 = socket.socket() s1.bind(('127.0.0.1', socket.INADDR_ANY)) localhost, localport = s1.getsockname() -remoteport = random.randrange(1, 2) -# ^^^ and just hope there is no conflict -args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % (remoteport, localport)] -args = args + sshargs + ['python -u -c "exec input()"'] -print ' '.join(args[:-1]) +if sshargs[0] != 'LOCAL': +remoteport = random.randrange(1, 2) +# ^^^ and just hope there is no conflict + +args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % ( +remoteport, localport)] +args = args + sshargs + ['python -u -c "exec input()"'] +else: +remoteport = localport +args = ['python', '-u', '-c', 'exec input()'] + +print ' '.join(args) p = subprocess.Popen(args, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE) diff --git a/lib-python/2.7/distutils/cmd.py b/lib-python/2.7/distutils/cmd.py --- a/lib-python/2.7/distutils/cmd.py +++ b/lib-python/2.7/distutils/cmd.py @@ -298,8 +298,16 @@
[pypy-commit] pypy shadowstack-perf-2: in-progress
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84381:94fec9f874f1 Date: 2016-05-11 18:18 +0200 http://bitbucket.org/pypy/pypy/changeset/94fec9f874f1/ Log:in-progress diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -100,8 +100,35 @@ return regalloc +def move_pushes_earlier(graph): +"""gc_push_roots and gc_pop_roots are pushes/pops to the shadowstack, +immediately enclosing the operation that needs them (typically a call). +Here, we try to move individual pushes earlier, in fact as early as +possible under the following conditions: we only move it across vars +that are 'interesting_vars'; and we stop when we encounter the +operation that produces the value, or when we encounter a gc_pop_roots +that pops off the same stack location. In the latter case, if that +gc_pop_roots pops the same value out of the same stack location, then +success: we can remove the gc_push_root on that path. + +If the process succeeds to remove the gc_push_root along at least +one path, we generate it explicitly on the other paths, and we +remove the original gc_push_root. If the process doesn't succeed +in doing any such removal, we don't do anything. + +Note that it would be possible to do exactly the same in the +opposite direction by exchanging the roles of "push/earlier" and +"pop/later". I think doing both is pointless---one direction is +enough. The direction we chose here keeps gc_pop_roots unmodified. +The C compiler should be better at discarding them if unused. +""" + +x.x.x.x + + def postprocess_graph(gct, graph): """Collect information about the gc_push_roots and gc_pop_roots added in this complete graph, and replace them with real operations. """ +regalloc = allocate_registers(graph) diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -33,7 +33,7 @@ return livevars def pop_roots(self, hop, livevars): -hop.genop("gc_pop_roots", livevars) # even if len(livevars) == 0 +hop.genop("gc_pop_roots", list(livevars)) # even if len(livevars) == 0 class ShadowStackRootWalker(BaseRootWalker): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy shadowstack-perf-2: many more tests for three extra lines of code
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84380:9584b8299e11 Date: 2016-05-11 17:23 +0200 http://bitbucket.org/pypy/pypy/changeset/9584b8299e11/ Log:many more tests for three extra lines of code diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -1,4 +1,5 @@ from rpython.flowspace.model import mkentrymap, Variable +from rpython.tool.algo.regalloc import perform_register_allocation def is_trivial_rewrite(op): @@ -93,6 +94,12 @@ return interesting_vars +def allocate_registers(graph): +interesting_vars = find_interesting_variables(graph) +regalloc = perform_register_allocation(graph, interesting_vars.__contains__) +return regalloc + + def postprocess_graph(gct, graph): """Collect information about the gc_push_roots and gc_pop_roots added in this complete graph, and replace them with real operations. diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py --- a/rpython/memory/gctransform/test/test_shadowcolor.py +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -11,13 +11,30 @@ graph.show() return graph +def nameof(v): +return v._name.rstrip('_') + def summary(interesting_vars): result = {} for v in interesting_vars: -name = v._name.rstrip('_') +name = nameof(v) result[name] = result.get(name, 0) + 1 return result +def summary_regalloc(regalloc): +result = [] +for block in regalloc.graph.iterblocks(): +print block.inputargs +for op in block.operations: +print '\t', op +blockvars = block.inputargs + [op.result for op in block.operations] +for v in blockvars: +if regalloc.consider_var(v): +result.append((nameof(v), regalloc.getcolor(v))) +print '\t\t%s: %s' % (v, regalloc.getcolor(v)) +result.sort() +return result + def test_find_predecessors_1(): def f(a, b): @@ -156,3 +173,72 @@ llop.gc_pop_roots(lltype.Void, a) graph = make_graph(f, [llmemory.GCREF, int]) assert summary(find_interesting_variables(graph)) == {'a': 4} + +def test_allocate_registers_1(): +def f(a, b): +llop.gc_push_roots(lltype.Void, a) +llop.gc_pop_roots(lltype.Void, a) +while b > 0: # 'a' remains interesting across the blocks of this loop +b -= 5 +llop.gc_push_roots(lltype.Void, a) +llop.gc_pop_roots(lltype.Void, a) +graph = make_graph(f, [llmemory.GCREF, int]) +regalloc = allocate_registers(graph) +assert summary_regalloc(regalloc) == [('a', 0)] * 4 + +def test_allocate_registers_2(): +def f(a, b, c): +llop.gc_push_roots(lltype.Void, a) +llop.gc_pop_roots(lltype.Void, a) +while b > 0: +b -= 5 +llop.gc_push_roots(lltype.Void, c) +llop.gc_pop_roots(lltype.Void, c) +graph = make_graph(f, [llmemory.GCREF, int, llmemory.GCREF]) +regalloc = allocate_registers(graph) +assert summary_regalloc(regalloc) == [('a', 0), ('c', 0)] + +def test_allocate_registers_3(): +def f(a, b, c): +llop.gc_push_roots(lltype.Void, c, a) +llop.gc_pop_roots(lltype.Void, c, a) +while b > 0: +b -= 5 +llop.gc_push_roots(lltype.Void, a) +llop.gc_pop_roots(lltype.Void, a) +graph = make_graph(f, [llmemory.GCREF, int, llmemory.GCREF]) +regalloc = allocate_registers(graph) +assert summary_regalloc(regalloc) == [('a', 1)] * 4 + [('c', 0)] + +def test_allocate_registers_4(): +def g(a, x): +return x # (or something different) +def f(a, b, c): +llop.gc_push_roots(lltype.Void, a, c) # 'a', 'c' +llop.gc_pop_roots(lltype.Void, a, c) +while b > 0: # 'a' only; 'c' not in push_roots +b -= 5 +llop.gc_push_roots(lltype.Void, a)# 'a' +d = g(a, c) +llop.gc_pop_roots(lltype.Void, a) +c = d +return c +graph = make_graph(f, [llmemory.GCREF, int, llmemory.GCREF]) +regalloc = allocate_registers(graph) +assert summary_regalloc(regalloc) == [('a', 1)] * 3 + [('c', 0)] + +def test_allocate_registers_5(): +def g(a, x): +return x # (or something different) +def f(a, b, c): +while b > 0: # 'a', 'c' +b -= 5 +llop.gc_push_roots(lltype.Void, a, c) # 'a', 'c' +g(a, c) +llop.gc_pop_roots(lltype.Void, a, c) +while b < 10: +b += 2 +return c +graph = make_graph(f, [llmemory.GCREF, int, llmemory.GCREF]) +regalloc = allocate_registers(graph) +assert summary_regalloc(regalloc) == [('a', 1)] * 2 + [('c', 0)] * 2 diff --git
[pypy-commit] pypy shadowstack-perf-2: Test that is_trivial_rewrite() is correctly used
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84379:e0900fa2a687 Date: 2016-05-11 17:04 +0200 http://bitbucket.org/pypy/pypy/changeset/e0900fa2a687/ Log:Test that is_trivial_rewrite() is correctly used diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py --- a/rpython/memory/gctransform/test/test_shadowcolor.py +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -65,6 +65,19 @@ pred = find_predecessors(graph, [(graph.returnblock, graph.getreturnvar())]) assert summary(pred) == {'a': 4, 'c': 1, 'v': 1} +def test_find_predecessors_trivial_rewrite(): +def f(a, b): # 'b' in empty startblock +while a > 100:# 'b' +a -= 2# 'b' +c = llop.same_as(lltype.Signed, b)# 'c', 'b' +while b > 10: # 'c' +b -= 2# 'c' +d = llop.same_as(lltype.Signed, c)# 'd', 'c' +return d # 'v' is the return var +graph = make_graph(f, [int, int]) +pred = find_predecessors(graph, [(graph.returnblock, graph.getreturnvar())]) +assert summary(pred) == {'b': 4, 'c': 4, 'd': 1, 'v': 1} + def test_find_successors_1(): def f(a, b): return a + b @@ -95,6 +108,19 @@ succ = find_successors(graph, [(graph.startblock, graph.getargs()[0])]) assert summary(succ) == {'a': 5} +def test_find_successors_trivial_rewrite(): +def f(a, b): # 'b' in empty startblock +while a > 100:# 'b' +a -= 2# 'b' +c = llop.same_as(lltype.Signed, b)# 'c', 'b' +while b > 10: # 'c', 'b' +b -= 2# 'c', 'b' +d = llop.same_as(lltype.Signed, c)# 'd', 'c' +return d # 'v' is the return var +graph = make_graph(f, [int, int]) +pred = find_successors(graph, [(graph.startblock, graph.getargs()[1])]) +assert summary(pred) == {'b': 6, 'c': 4, 'd': 1, 'v': 1} + def test_interesting_vars_0(): def f(a, b): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy shadowstack-perf-2: find_successors()
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84377:1fbf31cc03dc Date: 2016-05-11 16:55 +0200 http://bitbucket.org/pypy/pypy/changeset/1fbf31cc03dc/ Log:find_successors() diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -35,6 +35,30 @@ return pred +def find_successors(graph, pending_succ): +"""Return the set of variables where one of the 'pending_succ' can +end up. 'block_succ' is a list of (block, var) tuples. +""" +succ = set([v for block, v in pending_succ]) + +def add(block, v): +if isinstance(v, Variable): +if v not in succ: +pending_succ.append((block, v)) +succ.add(v) + +while pending_succ: +block, v = pending_succ.pop() +for op in block.operations: +if op.args and v is op.args[0] and is_trivial_rewrite(op): +add(block, op.result) +for link in block.exits: +for i, v1 in enumerate(link.args): +if v1 is v: +add(link.target, link.target.inputargs[i]) +return succ + + def find_interesting_variables(graph): # Decide which variables are "interesting" or not. Interesting # variables contain at least the ones that appear in gc_push_roots diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py --- a/rpython/memory/gctransform/test/test_shadowcolor.py +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -65,6 +65,36 @@ pred = find_precessors(graph, [(graph.returnblock, graph.getreturnvar())]) assert summary(pred) == {'a': 4, 'c': 1, 'v': 1} +def test_find_successors_1(): +def f(a, b): +return a + b +graph = make_graph(f, [int, int]) +succ = find_successors(graph, [(graph.startblock, graph.getargs()[0])]) +assert summary(succ) == {'a': 1} + +def test_find_successors_2(): +def f(a, b): +if b > 10: +return a + b +else: +return a - b +graph = make_graph(f, [int, int]) +succ = find_successors(graph, [(graph.startblock, graph.getargs()[0])]) +assert summary(succ) == {'a': 3} + +def test_find_successors_3(): +def f(a, b): +if b > 10: # 'a' condition block +a = a + b # 'a' input +while b > 100: +b -= 2 +while b > 5:# 'a' in loop header +b -= 2 # 'a' in loop body +return a * b# 'a' in product +graph = make_graph(f, [int, int]) +succ = find_successors(graph, [(graph.startblock, graph.getargs()[0])]) +assert summary(succ) == {'a': 5} + def test_interesting_vars_0(): def f(a, b): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy shadowstack-perf-2: Pass test_interesting_vars_3.
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84378:be524ccde2f4 Date: 2016-05-11 16:57 +0200 http://bitbucket.org/pypy/pypy/changeset/be524ccde2f4/ Log:Pass test_interesting_vars_3. diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -5,7 +5,7 @@ return op.opname in ('same_as', 'cast_pointer', 'cast_opaque_ptr') -def find_precessors(graph, pending_pred): +def find_predecessors(graph, pending_pred): """Return the set of variables whose content can end up inside one of the 'pending_pred', which is a list of (block, var) tuples. """ @@ -86,9 +86,10 @@ # where predecessors are variables which (sometimes) end in a # gc_push_roots, and successors are variables which (sometimes) # come from a gc_pop_roots. +pred = find_predecessors(graph, pending_pred) +succ = find_successors(graph, pending_succ) +interesting_vars |= (pred & succ) - -# return interesting_vars diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py --- a/rpython/memory/gctransform/test/test_shadowcolor.py +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -24,7 +24,7 @@ c = a + b return c graph = make_graph(f, [int, int]) -pred = find_precessors(graph, [(graph.returnblock, graph.getreturnvar())]) +pred = find_predecessors(graph, [(graph.returnblock, graph.getreturnvar())]) assert summary(pred) == {'c': 1, 'v': 1} def test_find_predecessors_2(): @@ -34,7 +34,7 @@ a -= 2 return c graph = make_graph(f, [int, int]) -pred = find_precessors(graph, [(graph.returnblock, graph.getreturnvar())]) +pred = find_predecessors(graph, [(graph.returnblock, graph.getreturnvar())]) assert summary(pred) == {'c': 3, 'v': 1} def test_find_predecessors_3(): @@ -47,7 +47,7 @@ c = a - b # 'c' created in this block return c # 'v' is the return var graph = make_graph(f, [int, int]) -pred = find_precessors(graph, [(graph.returnblock, graph.getreturnvar())]) +pred = find_predecessors(graph, [(graph.returnblock, graph.getreturnvar())]) assert summary(pred) == {'c': 2, 'v': 1} def test_find_predecessors_4(): @@ -62,7 +62,7 @@ c = a return c # 'v' is the return var graph = make_graph(f, [int, int]) -pred = find_precessors(graph, [(graph.returnblock, graph.getreturnvar())]) +pred = find_predecessors(graph, [(graph.returnblock, graph.getreturnvar())]) assert summary(pred) == {'a': 4, 'c': 1, 'v': 1} def test_find_successors_1(): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy shadowstack-perf-2: tests, code
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84376:142d9abed9dd Date: 2016-05-11 16:47 +0200 http://bitbucket.org/pypy/pypy/changeset/142d9abed9dd/ Log:tests, code diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -1,28 +1,68 @@ +from rpython.flowspace.model import mkentrymap, Variable + + +def is_trivial_rewrite(op): +return op.opname in ('same_as', 'cast_pointer', 'cast_opaque_ptr') + + +def find_precessors(graph, pending_pred): +"""Return the set of variables whose content can end up inside one +of the 'pending_pred', which is a list of (block, var) tuples. +""" +entrymap = mkentrymap(graph) +pred = set([v for block, v in pending_pred]) + +def add(block, v): +if isinstance(v, Variable): +if v not in pred: +pending_pred.append((block, v)) +pred.add(v) + +while pending_pred: +block, v = pending_pred.pop() +if v in block.inputargs: +var_index = block.inputargs.index(v) +for link in entrymap[block]: +prevblock = link.prevblock +if prevblock is not None: +add(prevblock, link.args[var_index]) +else: +for op in block.operations: +if op.result is v: +if is_trivial_rewrite(op): +add(block, op.args[0]) +break +return pred def find_interesting_variables(graph): # Decide which variables are "interesting" or not. Interesting # variables contain at least the ones that appear in gc_push_roots # and gc_pop_roots. -pending = [] +pending_pred = [] +pending_succ = [] interesting_vars = set() for block in graph.iterblocks(): for op in block.operations: if op.opname == 'gc_push_roots': for v in op.args: interesting_vars.add(v) -pending.append((block, v)) +pending_pred.append((block, v)) elif op.opname == 'gc_pop_roots': for v in op.args: assert v in interesting_vars # must be pushed just above -if not interesting_vars: -return +pending_succ.append((block, v)) # If there is a path from a gc_pop_roots(v) to a subsequent # gc_push_roots(w) where w contains the same value as v along that # path, then we consider all intermediate blocks along that path # which contain a copy of the same value, and add these variables -# as "interesting", too. +# as "interesting", too. Formally, a variable in a block is +# "interesting" if it is both a "predecessor" and a "successor", +# where predecessors are variables which (sometimes) end in a +# gc_push_roots, and successors are variables which (sometimes) +# come from a gc_pop_roots. + # return interesting_vars diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -29,15 +29,11 @@ def push_roots(self, hop, keep_current_args=False): livevars = self.get_livevars_for_roots(hop, keep_current_args) self.num_pushs += len(livevars) -if not livevars: -return [] -hop.genop("gc_push_roots", livevars) +hop.genop("gc_push_roots", livevars) # even if len(livevars) == 0 return livevars def pop_roots(self, hop, livevars): -if not livevars: -return -hop.genop("gc_pop_roots", livevars) +hop.genop("gc_pop_roots", livevars) # even if len(livevars) == 0 class ShadowStackRootWalker(BaseRootWalker): diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py --- a/rpython/memory/gctransform/test/test_shadowcolor.py +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -2,7 +2,7 @@ from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.test.test_llinterp import gengraph from rpython.conftest import option -from rpython.memory.gctransform.shadowcolor import find_interesting_variables +from rpython.memory.gctransform.shadowcolor import * def make_graph(f, argtypes): @@ -19,6 +19,53 @@ return result +def test_find_predecessors_1(): +def f(a, b): +c = a + b +return c +graph = make_graph(f, [int, int]) +pred = find_precessors(graph, [(graph.returnblock, graph.getreturnvar())]) +assert summary(pred) == {'c': 1, 'v': 1} + +def test_find_predecessors_2(): +def f(a, b): +c = a + b +while a > 0: +a -= 2 +return c +graph = make_graph(f, [int,
[pypy-commit] pypy shadowstack-perf-2: Yet another attempt at improving shadowstack
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84374:8db5e75d15b2 Date: 2016-05-11 15:48 +0200 http://bitbucket.org/pypy/pypy/changeset/8db5e75d15b2/ Log:Yet another attempt at improving shadowstack ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy shadowstack-perf-2: in-progress: starting with tests
Author: Armin RigoBranch: shadowstack-perf-2 Changeset: r84375:76c1df47dbe3 Date: 2016-05-11 16:15 +0200 http://bitbucket.org/pypy/pypy/changeset/76c1df47dbe3/ Log:in-progress: starting with tests diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -609,6 +609,9 @@ "the custom trace hook %r for %r can cause " "the GC to be called!" % (func, TP)) +def postprocess_graph(self, graph): +self.root_walker.postprocess_graph(self, graph) + def consider_constant(self, TYPE, value): self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc) diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py new file mode 100644 --- /dev/null +++ b/rpython/memory/gctransform/shadowcolor.py @@ -0,0 +1,35 @@ + + +def find_interesting_variables(graph): +# Decide which variables are "interesting" or not. Interesting +# variables contain at least the ones that appear in gc_push_roots +# and gc_pop_roots. +pending = [] +interesting_vars = set() +for block in graph.iterblocks(): +for op in block.operations: +if op.opname == 'gc_push_roots': +for v in op.args: +interesting_vars.add(v) +pending.append((block, v)) +elif op.opname == 'gc_pop_roots': +for v in op.args: +assert v in interesting_vars # must be pushed just above +if not interesting_vars: +return + +# If there is a path from a gc_pop_roots(v) to a subsequent +# gc_push_roots(w) where w contains the same value as v along that +# path, then we consider all intermediate blocks along that path +# which contain a copy of the same value, and add these variables +# as "interesting", too. + +# +return interesting_vars + + +def postprocess_graph(gct, graph): +"""Collect information about the gc_push_roots and gc_pop_roots +added in this complete graph, and replace them with real operations. +""" + diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py --- a/rpython/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -31,28 +31,13 @@ self.num_pushs += len(livevars) if not livevars: return [] -c_len = rmodel.inputconst(lltype.Signed, len(livevars) ) -base_addr = hop.genop("direct_call", [self.incr_stack_ptr, c_len ], - resulttype=llmemory.Address) -for k,var in enumerate(livevars): -c_k = rmodel.inputconst(lltype.Signed, k * sizeofaddr) -v_adr = gen_cast(hop.llops, llmemory.Address, var) -hop.genop("raw_store", [base_addr, c_k, v_adr]) +hop.genop("gc_push_roots", livevars) return livevars def pop_roots(self, hop, livevars): if not livevars: return -c_len = rmodel.inputconst(lltype.Signed, len(livevars) ) -base_addr = hop.genop("direct_call", [self.decr_stack_ptr, c_len ], - resulttype=llmemory.Address) -if self.gcdata.gc.moving_gc: -# for moving collectors, reload the roots into the local variables -for k,var in enumerate(livevars): -c_k = rmodel.inputconst(lltype.Signed, k * sizeofaddr) -v_newaddr = hop.genop("raw_load", [base_addr, c_k], - resulttype=llmemory.Address) -hop.genop("gc_reload_possibly_moved", [v_newaddr, var]) +hop.genop("gc_pop_roots", livevars) class ShadowStackRootWalker(BaseRootWalker): @@ -222,6 +207,10 @@ from rpython.rlib import _stacklet_shadowstack _stacklet_shadowstack.complete_destrptr(gctransformer) +def postprocess_graph(self, gct, graph): +from rpython.memory.gctransform import shadowcolor +shadowcolor.postprocess_graph(gct, graph) + # class ShadowStackPool(object): diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py new file mode 100644 --- /dev/null +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -0,0 +1,55 @@ +from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rtyper.test.test_llinterp import gengraph +from rpython.conftest import option +from rpython.memory.gctransform.shadowcolor import find_interesting_variables + + +def make_graph(f, argtypes): +t, rtyper, graph = gengraph(f, argtypes, viewbefore=False) +if getattr(option, 'view', False): +graph.show() +return graph +
[pypy-commit] pypy default: A minimal test for algo.regalloc, independent on the tests from jit.codewriter
Author: Armin RigoBranch: Changeset: r84373:71480708fb61 Date: 2016-05-11 15:27 +0200 http://bitbucket.org/pypy/pypy/changeset/71480708fb61/ Log:A minimal test for algo.regalloc, independent on the tests from jit.codewriter diff --git a/rpython/tool/algo/test/test_regalloc.py b/rpython/tool/algo/test/test_regalloc.py new file mode 100644 --- /dev/null +++ b/rpython/tool/algo/test/test_regalloc.py @@ -0,0 +1,60 @@ +from rpython.rtyper.test.test_llinterp import gengraph +from rpython.rtyper.lltypesystem import lltype +from rpython.tool.algo.regalloc import perform_register_allocation +from rpython.flowspace.model import Variable +from rpython.conftest import option + + +def is_int(v): +return v.concretetype == lltype.Signed + +def check_valid(graph, regalloc, consider_var): +if getattr(option, 'view', False): +graph.show() +num_renamings = 0 +for block in graph.iterblocks(): +inputs = [v for v in block.inputargs if consider_var(v)] +colors = [regalloc.getcolor(v) for v in inputs] +print inputs, ':', colors +assert len(inputs) == len(set(colors)) +in_use = dict(zip(colors, inputs)) +for op in block.operations: +for v in op.args: +if isinstance(v, Variable) and consider_var(v): +assert in_use[regalloc.getcolor(v)] is v +if consider_var(op.result): +in_use[regalloc.getcolor(op.result)] = op.result +for link in block.exits: +for i, v in enumerate(link.args): +if consider_var(v): +assert in_use[regalloc.getcolor(v)] is v +w = link.target.inputargs[i] +if regalloc.getcolor(v) is not regalloc.getcolor(w): +print '\trenaming %s:%d -> %s:%d' % ( +v, regalloc.getcolor(v), w, regalloc.getcolor(w)) +num_renamings += 1 +return num_renamings + + +def test_loop_1(): +def f(a, b): +while a > 0: +b += a +a -= 1 +return b +t, rtyper, graph = gengraph(f, [int, int], viewbefore=False) +regalloc = perform_register_allocation(graph, is_int) +num_renamings = check_valid(graph, regalloc, is_int) +assert num_renamings == 0 + +def test_loop_2(): +def f(a, b): +while a > 0: +b += a +if b < 10: +a, b = b, a +a -= 1 +return b +t, rtyper, graph = gengraph(f, [int, int], viewbefore=False) +regalloc = perform_register_allocation(graph, is_int) +check_valid(graph, regalloc, is_int) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge ufunc-outer which implements numpypy.ufunc.outer
Author: Matti PicusBranch: Changeset: r84371:0c3ac8d64955 Date: 2016-05-11 12:29 +0300 http://bitbucket.org/pypy/pypy/changeset/0c3ac8d64955/ Log:merge ufunc-outer which implements numpypy.ufunc.outer diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py --- a/pypy/module/micronumpy/ndarray.py +++ b/pypy/module/micronumpy/ndarray.py @@ -443,7 +443,7 @@ 'array does not have imaginary part to set') self.implementation.set_imag(space, self, w_value) -def reshape(self, space, w_shape, order): +def reshape(self, space, w_shape, order=NPY.ANYORDER): new_shape = get_shape_from_iterable(space, self.get_size(), w_shape) new_impl = self.implementation.reshape(self, new_shape, order) if new_impl is not None: 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 @@ -1480,7 +1480,21 @@ def test_outer(self): import numpy as np -from numpy import absolute +c = np.multiply.outer([1, 2, 3], [4, 5, 6]) +assert c.shape == (3, 3) +assert (c ==[[ 4, 5, 6], + [ 8, 10, 12], + [12, 15, 18]]).all() +A = np.array([[1, 2, 3], [4, 5, 6]]) +B = np.array([[1, 2, 3, 4]]) +c = np.multiply.outer(A, B) +assert c.shape == (2, 3, 1, 4) +assert (c == 1, 2, 3, 4]], + [[ 2, 4, 6, 8]], + [[ 3, 6, 9, 12]]], + [[[ 4, 8, 12, 16]], + [[ 5, 10, 15, 20]], + [[ 6, 12, 18, 24).all() exc = raises(ValueError, np.absolute.outer, [-1, -2]) assert exc.value[0] == 'outer product only supported for binary functions' diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py --- a/pypy/module/micronumpy/ufuncs.py +++ b/pypy/module/micronumpy/ufuncs.py @@ -363,12 +363,18 @@ out = space.call_method(obj, '__array_wrap__', out, space.w_None) return out -def descr_outer(self, space, __args__): -return self._outer(space, __args__) - -def _outer(self, space, __args__): -raise oefmt(space.w_ValueError, +def descr_outer(self, space, args_w): +if self.nin != 2: +raise oefmt(space.w_ValueError, "outer product only supported for binary functions") +if len(args_w) != 2: +raise oefmt(space.w_ValueError, +"exactly two arguments expected") +args = [convert_to_array(space, w_obj) for w_obj in args_w] +w_outshape = [space.wrap(i) for i in args[0].get_shape() + [1]*args[1].ndims()] +args0 = args[0].reshape(space, space.newtuple(w_outshape)) +return self.descr_call(space, Arguments.frompacked(space, +space.newlist([args0, args[1]]))) def parse_kwargs(self, space, kwds_w): w_casting = kwds_w.pop('casting', None) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-raisingops: hg merge default
Author: Armin RigoBranch: remove-raisingops Changeset: r84369:7652a3938aaa Date: 2016-05-11 10:02 +0200 http://bitbucket.org/pypy/pypy/changeset/7652a3938aaa/ Log:hg merge default diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -14,10 +14,11 @@ space.wrap(message)])) class W_HKEY(W_Root): -def __init__(self, hkey): +def __init__(self, space, hkey): self.hkey = hkey +self.register_finalizer(space) -def descr_del(self, space): +def _finalize_(self, space): self.Close(space) def as_int(self): @@ -64,7 +65,7 @@ @unwrap_spec(key=int) def new_HKEY(space, w_subtype, key): hkey = rffi.cast(rwinreg.HKEY, key) -return space.wrap(W_HKEY(hkey)) +return space.wrap(W_HKEY(space, hkey)) descr_HKEY_new = interp2app(new_HKEY) W_HKEY.typedef = TypeDef( @@ -91,7 +92,6 @@ __int__ - Converting a handle to an integer returns the Win32 handle. __cmp__ - Handle objects are compared using the handle value.""", __new__ = descr_HKEY_new, -__del__ = interp2app(W_HKEY.descr_del), __repr__ = interp2app(W_HKEY.descr_repr), __int__ = interp2app(W_HKEY.descr_int), __nonzero__ = interp2app(W_HKEY.descr_nonzero), @@ -480,7 +480,7 @@ ret = rwinreg.RegCreateKey(hkey, subkey, rethkey) if ret != 0: raiseWindowsError(space, ret, 'CreateKey') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(subkey=str, res=int, sam=rffi.r_uint) def CreateKeyEx(space, w_hkey, subkey, res=0, sam=rwinreg.KEY_WRITE): @@ -502,7 +502,7 @@ lltype.nullptr(rwin32.LPDWORD.TO)) if ret != 0: raiseWindowsError(space, ret, 'CreateKeyEx') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(subkey=str) def DeleteKey(space, w_hkey, subkey): @@ -549,7 +549,7 @@ ret = rwinreg.RegOpenKeyEx(hkey, subkey, res, sam, rethkey) if ret != 0: raiseWindowsError(space, ret, 'RegOpenKeyEx') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(index=int) def EnumValue(space, w_hkey, index): @@ -688,7 +688,7 @@ ret = rwinreg.RegConnectRegistry(machine, hkey, rethkey) if ret != 0: raiseWindowsError(space, ret, 'RegConnectRegistry') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(source=unicode) def ExpandEnvironmentStrings(space, source): diff --git a/rpython/translator/c/src/int.h b/rpython/translator/c/src/int.h --- a/rpython/translator/c/src/int.h +++ b/rpython/translator/c/src/int.h @@ -45,7 +45,21 @@ /* addition, subtraction */ #define OP_INT_ADD(x,y,r) r = (x) + (y) +#define OP_INT_SUB(x,y,r) r = (x) - (y) +#define OP_INT_MUL(x,y,r) r = (x) * (y) + +#ifdef __GNUC__ +# if __GNUC__ >= 5 +# define HAVE_BUILTIN_OVERFLOW +# elif defined(__has_builtin) /* clang */ +# if __has_builtin(__builtin_mul_overflow) +# define HAVE_BUILTIN_OVERFLOW +# endif +# endif +#endif + +#ifndef HAVE_BUILTIN_OVERFLOW /* cast to avoid undefined behaviour on overflow */ #define OP_INT_ADD_OVF(x,y,r) \ r = (Signed)((Unsigned)x + y); \ @@ -55,14 +69,10 @@ r = (Signed)((Unsigned)x + y); \ if ((r&~x) < 0) FAIL_OVF("integer addition") -#define OP_INT_SUB(x,y,r) r = (x) - (y) - #define OP_INT_SUB_OVF(x,y,r) \ r = (Signed)((Unsigned)x - y); \ if ((r^x) < 0 && (r^~y) < 0) FAIL_OVF("integer subtraction") -#define OP_INT_MUL(x,y,r) r = (x) * (y) - #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG #define OP_INT_MUL_OVF(x,y,r) \ { \ @@ -75,6 +85,17 @@ r = op_llong_mul_ovf(x, y) /* long == long long */ #endif +#else /* HAVE_BUILTIN_OVERFLOW */ +#define OP_INT_ADD_NONNEG_OVF(x,y,r) OP_INT_ADD_OVF(x,y,r) +#define OP_INT_ADD_OVF(x,y,r) \ + if (__builtin_add_overflow(x, y, )) FAIL_OVF("integer addition") +#define OP_INT_SUB_OVF(x,y,r) \ + if (__builtin_sub_overflow(x, y, )) FAIL_OVF("integer subtraction") +#define OP_INT_MUL_OVF(x,y,r) \ + if (__builtin_mul_overflow(x, y, )) FAIL_OVF("integer multiplication") +#endif + + /* shifting */ /* NB. shifting has same limitations as C: the shift count must be ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Use the __builtin_add_overflow built-ins if they are available:
Author: Armin RigoBranch: Changeset: r84368:e1b97a953f37 Date: 2016-05-11 10:01 +0200 http://bitbucket.org/pypy/pypy/changeset/e1b97a953f37/ Log:Use the __builtin_add_overflow built-ins if they are available: on GCC >= 5, and on recent enough clang. diff --git a/rpython/translator/c/src/int.h b/rpython/translator/c/src/int.h --- a/rpython/translator/c/src/int.h +++ b/rpython/translator/c/src/int.h @@ -53,7 +53,21 @@ /* addition, subtraction */ #define OP_INT_ADD(x,y,r) r = (x) + (y) +#define OP_INT_SUB(x,y,r) r = (x) - (y) +#define OP_INT_MUL(x,y,r) r = (x) * (y) + +#ifdef __GNUC__ +# if __GNUC__ >= 5 +# define HAVE_BUILTIN_OVERFLOW +# elif defined(__has_builtin) /* clang */ +# if __has_builtin(__builtin_mul_overflow) +# define HAVE_BUILTIN_OVERFLOW +# endif +# endif +#endif + +#ifndef HAVE_BUILTIN_OVERFLOW /* cast to avoid undefined behaviour on overflow */ #define OP_INT_ADD_OVF(x,y,r) \ r = (Signed)((Unsigned)x + y); \ @@ -63,14 +77,10 @@ r = (Signed)((Unsigned)x + y); \ if ((r&~x) < 0) FAIL_OVF("integer addition") -#define OP_INT_SUB(x,y,r) r = (x) - (y) - #define OP_INT_SUB_OVF(x,y,r) \ r = (Signed)((Unsigned)x - y); \ if ((r^x) < 0 && (r^~y) < 0) FAIL_OVF("integer subtraction") -#define OP_INT_MUL(x,y,r) r = (x) * (y) - #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG && !defined(_WIN64) #define OP_INT_MUL_OVF(x,y,r) \ { \ @@ -83,6 +93,17 @@ r = op_llong_mul_ovf(x, y) /* long == long long */ #endif +#else /* HAVE_BUILTIN_OVERFLOW */ +#define OP_INT_ADD_NONNEG_OVF(x,y,r) OP_INT_ADD_OVF(x,y,r) +#define OP_INT_ADD_OVF(x,y,r) \ + if (__builtin_add_overflow(x, y, )) FAIL_OVF("integer addition") +#define OP_INT_SUB_OVF(x,y,r) \ + if (__builtin_sub_overflow(x, y, )) FAIL_OVF("integer subtraction") +#define OP_INT_MUL_OVF(x,y,r) \ + if (__builtin_mul_overflow(x, y, )) FAIL_OVF("integer multiplication") +#endif + + /* shifting */ /* NB. shifting has same limitations as C: the shift count must be ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-raisingops: test fix
Author: Armin RigoBranch: remove-raisingops Changeset: r84367:3d4ae3e9cc30 Date: 2016-05-11 09:34 +0200 http://bitbucket.org/pypy/pypy/changeset/3d4ae3e9cc30/ Log:test fix diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py --- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py +++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py @@ -262,7 +262,7 @@ [i0] i1 = int_add(i0, 1) i2 = int_sub(i1, 10) -i3 = int_floordiv(i2, 100) +i3 = int_xor(i2, 100) i4 = int_mul(i1, 1000) jump(i4) """ @@ -298,7 +298,7 @@ [i0] i1 = int_add(i0, 1) i2 = int_sub(i1, 10) -i3 = int_floordiv(i2, 100) +i3 = int_xor(i2, 100) i4 = int_mul(i1, 1000) jump(i4) """ ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-raisingops: merge heads
Author: Armin RigoBranch: remove-raisingops Changeset: r84366:5bca3ef7ba7c Date: 2016-05-11 09:33 +0200 http://bitbucket.org/pypy/pypy/changeset/5bca3ef7ba7c/ Log:merge heads diff --git a/pypy/module/__pypy__/interp_intop.py b/pypy/module/__pypy__/interp_intop.py --- a/pypy/module/__pypy__/interp_intop.py +++ b/pypy/module/__pypy__/interp_intop.py @@ -2,6 +2,19 @@ from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.rarithmetic import r_uint, intmask +from rpython.rlib import jit + + +# XXX maybe temporary: hide llop.int_{floordiv,mod} from the JIT, +# because now it expects only Python-style divisions, not the +# C-style divisions of these two ll operations +@jit.dont_look_inside +def _int_floordiv(n, m): +return llop.int_floordiv(lltype.Signed, n, m) + +@jit.dont_look_inside +def _int_mod(n, m): +return llop.int_mod(lltype.Signed, n, m) @unwrap_spec(n=int, m=int) @@ -18,11 +31,11 @@ @unwrap_spec(n=int, m=int) def int_floordiv(space, n, m): -return space.wrap(llop.int_floordiv(lltype.Signed, n, m)) +return space.wrap(_int_floordiv(n, m)) @unwrap_spec(n=int, m=int) def int_mod(space, n, m): -return space.wrap(llop.int_mod(lltype.Signed, n, m)) +return space.wrap(_int_mod(n, m)) @unwrap_spec(n=int, m=int) def int_lshift(space, n, m): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy remove-raisingops: Revert the whole change for int_{add, sub, mul}_ovf. It can be argued
Author: Armin RigoBranch: remove-raisingops Changeset: r84365:7d31bc576cbc Date: 2016-05-11 09:33 +0200 http://bitbucket.org/pypy/pypy/changeset/7d31bc576cbc/ Log:Revert the whole change for int_{add,sub,mul}_ovf. It can be argued that the C backend should handle them directly, and more prosaically, it goes in the way of tests if they start seeing 'cast_int_to_float' and other unexpected operations diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -333,6 +333,17 @@ rewrite_op_float_gt = _rewrite_symmetric rewrite_op_float_ge = _rewrite_symmetric +def rewrite_op_int_add_ovf(self, op): +op0 = self._rewrite_symmetric(op) +op1 = SpaceOperation('-live-', [], None) +return [op1, op0] + +rewrite_op_int_mul_ovf = rewrite_op_int_add_ovf + +def rewrite_op_int_sub_ovf(self, op): +op1 = SpaceOperation('-live-', [], None) +return [op1, op] + def _noop_rewrite(self, op): return op @@ -426,7 +437,7 @@ if oopspec_name.startswith('list.') or oopspec_name.startswith('newlist'): prepare = self._handle_list_call elif oopspec_name.startswith('int.'): -prepare = self._handle_int_ovf +prepare = self._handle_int_special elif oopspec_name.startswith('stroruni.'): prepare = self._handle_stroruni_call elif oopspec_name == 'str.str2unicode': @@ -1479,6 +1490,7 @@ for _old, _new in [('bool_not', 'int_is_zero'), ('cast_bool_to_float', 'cast_int_to_float'), + ('int_add_nonneg_ovf', 'int_add_ovf'), ('keepalive', '-live-'), ('char_lt', 'int_lt'), @@ -1902,22 +1914,15 @@ llmemory.cast_ptr_to_adr(c_func.value)) self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func) -def _handle_int_ovf(self, op, oopspec_name, args): -opname = oopspec_name.replace('.', '_') -if oopspec_name in ('int.add_ovf', 'int.sub_ovf', 'int.mul_ovf'): -op0 = SpaceOperation(opname, args, op.result) -if oopspec_name in ('int.add_ovf', 'int.mul_ovf'): -op0 = self._rewrite_symmetric(op0) -oplist = [SpaceOperation('-live-', [], None), op0] -return oplist -elif oopspec_name == 'int.neg_ovf': +def _handle_int_special(self, op, oopspec_name, args): +if oopspec_name == 'int.neg_ovf': [v_x] = args op0 = SpaceOperation('int_sub_ovf', [Constant(0, lltype.Signed), v_x], op.result) -oplist = [SpaceOperation('-live-', [], None), op0] -return oplist +return self.rewrite_operation(op0) else: +opname = oopspec_name.replace('.', '_') os = getattr(EffectInfo, 'OS_' + opname.upper()) return self._handle_oopspec_call(op, args, os, EffectInfo.EF_ELIDABLE_CANNOT_RAISE) diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py --- a/rpython/jit/codewriter/test/test_flatten.py +++ b/rpython/jit/codewriter/test/test_flatten.py @@ -71,9 +71,6 @@ _descr_cannot_raise = FakeDescr() callinfocollection = FakeCallInfoCollection() def guess_call_kind(self, op): -if op.args[0].value._obj._name.startswith( -('ll_int_add_ovf', 'll_int_sub_ovf', 'll_int_mul_ovf')): -return 'builtin' return 'residual' def getcalldescr(self, op, oopspecindex=EffectInfo.OS_NONE, extraeffect=None, extradescr=None): diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py --- a/rpython/jit/codewriter/test/test_jtransform.py +++ b/rpython/jit/codewriter/test/test_jtransform.py @@ -272,17 +272,17 @@ assert op1.result == v3 assert op1.opname == name2[0] -@py.test.mark.parametrize('opname', ['add_ovf', 'mul_ovf']) -def test_symmetric_op_ovf(opname): +@py.test.mark.parametrize('opname', ['add_ovf', 'sub_ovf', 'mul_ovf']) +def test_int_op_ovf(opname): v3 = varoftype(lltype.Signed) for v1 in [varoftype(lltype.Signed), const(42)]: for v2 in [varoftype(lltype.Signed), const(43)]: -op = SpaceOperation('direct_call', [Constant(opname), v1, v2], v3) -oplist = Transformer(FakeCPU())._handle_int_ovf(op, 'int.'+opname, -[v1, v2]) +op = SpaceOperation('int_' + opname, [v1, v2], v3) +oplist = Transformer(FakeCPU()).rewrite_operation(op) op1, op0 = oplist -assert op0.opname
[pypy-commit] pypy remove-raisingops: hg merge default
Author: Armin RigoBranch: remove-raisingops Changeset: r84364:734a91c841ee Date: 2016-05-11 08:24 +0200 http://bitbucket.org/pypy/pypy/changeset/734a91c841ee/ Log:hg merge default diff too long, truncating to 2000 out of 37072 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -21,3 +21,4 @@ 246c9cf22037b11dc0e8c29ce3f291d3b8c5935a release-5.0 bbd45126bc691f669c4ebdfbd74456cd274c6b92 release-5.0.1 3260adbeba4a8b6659d1cc0d0b41f266769b74da release-5.1 +b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1 diff --git a/dotviewer/graphserver.py b/dotviewer/graphserver.py --- a/dotviewer/graphserver.py +++ b/dotviewer/graphserver.py @@ -143,6 +143,11 @@ if __name__ == '__main__': if len(sys.argv) != 2: +if len(sys.argv) == 1: +# start locally +import sshgraphserver +sshgraphserver.ssh_graph_server(['LOCAL']) +sys.exit(0) print >> sys.stderr, __doc__ sys.exit(2) if sys.argv[1] == '--stdio': diff --git a/dotviewer/sshgraphserver.py b/dotviewer/sshgraphserver.py --- a/dotviewer/sshgraphserver.py +++ b/dotviewer/sshgraphserver.py @@ -4,11 +4,14 @@ Usage: sshgraphserver.py hostname [more args for ssh...] +sshgraphserver.py LOCAL This logs in to 'hostname' by passing the arguments on the command-line to ssh. No further configuration is required: it works for all programs using the dotviewer library as long as they run on 'hostname' under the same username as the one sshgraphserver logs as. + +If 'hostname' is the string 'LOCAL', then it starts locally without ssh. """ import graphserver, socket, subprocess, random @@ -18,12 +21,19 @@ s1 = socket.socket() s1.bind(('127.0.0.1', socket.INADDR_ANY)) localhost, localport = s1.getsockname() -remoteport = random.randrange(1, 2) -# ^^^ and just hope there is no conflict -args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % (remoteport, localport)] -args = args + sshargs + ['python -u -c "exec input()"'] -print ' '.join(args[:-1]) +if sshargs[0] != 'LOCAL': +remoteport = random.randrange(1, 2) +# ^^^ and just hope there is no conflict + +args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % ( +remoteport, localport)] +args = args + sshargs + ['python -u -c "exec input()"'] +else: +remoteport = localport +args = ['python', '-u', '-c', 'exec input()'] + +print ' '.join(args) p = subprocess.Popen(args, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE) diff --git a/lib-python/2.7/distutils/cmd.py b/lib-python/2.7/distutils/cmd.py --- a/lib-python/2.7/distutils/cmd.py +++ b/lib-python/2.7/distutils/cmd.py @@ -298,8 +298,16 @@ src_cmd_obj.ensure_finalized() for (src_option, dst_option) in option_pairs: if getattr(self, dst_option) is None: -setattr(self, dst_option, -getattr(src_cmd_obj, src_option)) +try: +setattr(self, dst_option, +getattr(src_cmd_obj, src_option)) +except AttributeError: +# This was added after problems with setuptools 18.4. +# It seems that setuptools 20.9 fixes the problem. +# But e.g. on Ubuntu 14.04 with /usr/bin/virtualenv +# if I say "virtualenv -p pypy venv-pypy" then it +# just installs setuptools 18.4 from some cache... +pass def get_finalized_command(self, command, create=1): diff --git a/lib-python/2.7/test/test_descr.py b/lib-python/2.7/test/test_descr.py --- a/lib-python/2.7/test/test_descr.py +++ b/lib-python/2.7/test/test_descr.py @@ -1735,7 +1735,6 @@ ("__reversed__", reversed, empty_seq, set(), {}), ("__length_hint__", list, zero, set(), {"__iter__" : iden, "next" : stop}), -("__sizeof__", sys.getsizeof, zero, set(), {}), ("__instancecheck__", do_isinstance, return_true, set(), {}), ("__missing__", do_dict_missing, some_number, set(("__class__",)), {}), @@ -1747,6 +1746,8 @@ ("__format__", format, format_impl, set(), {}), ("__dir__", dir, empty_seq, set(), {}), ] +if test_support.check_impl_detail(): +specials.append(("__sizeof__", sys.getsizeof, zero, set(), {})) class Checker(object): def __getattr__(self, attr, test=self): @@ -1768,10 +1769,6 @@ raise MyException for name, runner, meth_impl, ok, env in specials: -if name == '__length_hint__' or name == '__sizeof__': -if not test_support.check_impl_detail(): -continue - class X(Checker):
[pypy-commit] pypy default: Forgot to fix _winreg for the new _finalize_() style
Author: Armin RigoBranch: Changeset: r84363:ee153d8516f5 Date: 2016-05-11 09:15 +0200 http://bitbucket.org/pypy/pypy/changeset/ee153d8516f5/ Log:Forgot to fix _winreg for the new _finalize_() style diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -14,10 +14,11 @@ space.wrap(message)])) class W_HKEY(W_Root): -def __init__(self, hkey): +def __init__(self, space, hkey): self.hkey = hkey +self.register_finalizer(space) -def descr_del(self, space): +def _finalize_(self, space): self.Close(space) def as_int(self): @@ -64,7 +65,7 @@ @unwrap_spec(key=int) def new_HKEY(space, w_subtype, key): hkey = rffi.cast(rwinreg.HKEY, key) -return space.wrap(W_HKEY(hkey)) +return space.wrap(W_HKEY(space, hkey)) descr_HKEY_new = interp2app(new_HKEY) W_HKEY.typedef = TypeDef( @@ -91,7 +92,6 @@ __int__ - Converting a handle to an integer returns the Win32 handle. __cmp__ - Handle objects are compared using the handle value.""", __new__ = descr_HKEY_new, -__del__ = interp2app(W_HKEY.descr_del), __repr__ = interp2app(W_HKEY.descr_repr), __int__ = interp2app(W_HKEY.descr_int), __nonzero__ = interp2app(W_HKEY.descr_nonzero), @@ -480,7 +480,7 @@ ret = rwinreg.RegCreateKey(hkey, subkey, rethkey) if ret != 0: raiseWindowsError(space, ret, 'CreateKey') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(subkey=str, res=int, sam=rffi.r_uint) def CreateKeyEx(space, w_hkey, subkey, res=0, sam=rwinreg.KEY_WRITE): @@ -502,7 +502,7 @@ lltype.nullptr(rwin32.LPDWORD.TO)) if ret != 0: raiseWindowsError(space, ret, 'CreateKeyEx') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(subkey=str) def DeleteKey(space, w_hkey, subkey): @@ -549,7 +549,7 @@ ret = rwinreg.RegOpenKeyEx(hkey, subkey, res, sam, rethkey) if ret != 0: raiseWindowsError(space, ret, 'RegOpenKeyEx') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(index=int) def EnumValue(space, w_hkey, index): @@ -688,7 +688,7 @@ ret = rwinreg.RegConnectRegistry(machine, hkey, rethkey) if ret != 0: raiseWindowsError(space, ret, 'RegConnectRegistry') -return space.wrap(W_HKEY(rethkey[0])) +return space.wrap(W_HKEY(space, rethkey[0])) @unwrap_spec(source=unicode) def ExpandEnvironmentStrings(space, source): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ufunc-outer: test, fix ufunc.outer, following numpy's c implementation
Author: Matti PicusBranch: ufunc-outer Changeset: r84362:fe644c4006dd Date: 2016-05-11 10:13 +0300 http://bitbucket.org/pypy/pypy/changeset/fe644c4006dd/ Log:test, fix ufunc.outer, following numpy's c implementation diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py --- a/pypy/module/micronumpy/ndarray.py +++ b/pypy/module/micronumpy/ndarray.py @@ -443,7 +443,7 @@ 'array does not have imaginary part to set') self.implementation.set_imag(space, self, w_value) -def reshape(self, space, w_shape, order): +def reshape(self, space, w_shape, order=NPY.ANYORDER): new_shape = get_shape_from_iterable(space, self.get_size(), w_shape) new_impl = self.implementation.reshape(self, new_shape, order) if new_impl is not None: 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 @@ -1480,7 +1480,21 @@ def test_outer(self): import numpy as np -from numpy import absolute +c = np.multiply.outer([1, 2, 3], [4, 5, 6]) +assert c.shape == (3, 3) +assert (c ==[[ 4, 5, 6], + [ 8, 10, 12], + [12, 15, 18]]).all() +A = np.array([[1, 2, 3], [4, 5, 6]]) +B = np.array([[1, 2, 3, 4]]) +c = np.multiply.outer(A, B) +assert c.shape == (2, 3, 1, 4) +assert (c == 1, 2, 3, 4]], + [[ 2, 4, 6, 8]], + [[ 3, 6, 9, 12]]], + [[[ 4, 8, 12, 16]], + [[ 5, 10, 15, 20]], + [[ 6, 12, 18, 24).all() exc = raises(ValueError, np.absolute.outer, [-1, -2]) assert exc.value[0] == 'outer product only supported for binary functions' diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py --- a/pypy/module/micronumpy/ufuncs.py +++ b/pypy/module/micronumpy/ufuncs.py @@ -363,12 +363,18 @@ out = space.call_method(obj, '__array_wrap__', out, space.w_None) return out -def descr_outer(self, space, __args__): -return self._outer(space, __args__) - -def _outer(self, space, __args__): -raise oefmt(space.w_ValueError, +def descr_outer(self, space, args_w): +if self.nin != 2: +raise oefmt(space.w_ValueError, "outer product only supported for binary functions") +if len(args_w) != 2: +raise oefmt(space.w_ValueError, +"exactly two arguments expected") +args = [convert_to_array(space, w_obj) for w_obj in args_w] +w_outshape = [space.wrap(i) for i in args[0].get_shape() + [1]*args[1].ndims()] +args0 = args[0].reshape(space, space.newtuple(w_outshape)) +return self.descr_call(space, Arguments.frompacked(space, +space.newlist([args0, args[1]]))) def parse_kwargs(self, space, kwds_w): w_casting = kwds_w.pop('casting', None) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-macros-cast2: problems with api_struct
Author: Matti PicusBranch: cpyext-macros-cast2 Changeset: r84360:ad44c12b677a Date: 2016-05-11 09:25 +0300 http://bitbucket.org/pypy/pypy/changeset/ad44c12b677a/ Log:problems with api_struct diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -1027,8 +1027,8 @@ # added only for the macro, not the decl continue restype, args = c_function_signature(db, func) -args = ', '.join(args) or "void" -members.append('%s (*%s)(%s);' % (restype, name, args)) +args_str = ', '.join(args) or "void" +members.append('%s (*%s)(%s);' % (restype, name, args_str)) structindex[name] = len(structindex) structmembers = '\n'.join(members) struct_declaration_code = """\ @@ -1268,16 +1268,14 @@ if not func: continue casts.append(name) -_name = mangle_name(prefix, name) -assert _name is not None, 'error converting %s' % name -restype, args = c_function_signature(db, func) -l_args = ', '.join(['a%d' % i for i in xrange(len(args))]) -r_args = ', '.join(['(%s)a%d' % (a.split('arg')[0], i) +if not api_struct: +_name = mangle_name(prefix, name) +assert _name is not None, 'error converting %s' % name +restype, args = c_function_signature(db, func) +l_args = ', '.join(['a%d' % i for i in xrange(len(args))]) +r_args = ', '.join(['(%s)a%d' % (a.split('arg')[0], i) for i,a in enumerate(args)]) -_name = mangle_name(prefix, name) -header.append("#define %s(%s) %s(%s)" % (name, l_args, _name, r_args)) -print casts - +header.append("#define %s(%s) %s(%s)" % (name, l_args, _name, r_args)) for header_name, header_functions in FUNCTIONS_BY_HEADER.iteritems(): if header_name not in decls: header = decls[header_name] = [] @@ -1289,13 +1287,13 @@ for name, func in sorted(header_functions.iteritems()): if not func: continue +_name = mangle_name(prefix, name) +assert _name is not None, 'error converting %s' % name if name not in casts: -_name = mangle_name(prefix, name) -assert _name is not None, 'error converting %s' % name header.append("#define %s %s" % (name, _name)) restype, args = c_function_signature(db, func) -args = ', '.join(args) or "void" -header.append("PyAPI_FUNC(%s) %s(%s);" % (restype, _name, args)) +args_str = ', '.join(args) or "void" +header.append("PyAPI_FUNC(%s) %s(%s);" % (restype, _name, args_str)) if api_struct: callargs = ', '.join('arg%d' % (i,) for i in range(len(func.argtypes))) @@ -1303,7 +1301,7 @@ body = "{ _pypyAPI.%s(%s); }" % (_name, callargs) else: body = "{ return _pypyAPI.%s(%s); }" % (_name, callargs) -functions.append('%s %s(%s)\n%s' % (restype, name, args, body)) +functions.append('%s %s(%s)\n%s' % (restype, name, args_str, body)) for name in VA_TP_LIST: name_no_star = process_va_name(name) header = ('%s pypy_va_get_%s(va_list* vp)' % ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-macros-cast2: generate 'casting' macros for some functions
Author: Matti PicusBranch: cpyext-macros-cast2 Changeset: r84357:781c52f85655 Date: 2016-05-10 23:50 +0300 http://bitbucket.org/pypy/pypy/changeset/781c52f85655/ Log:generate 'casting' macros for some functions ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ufunc-outer: implement numpypy.ufunc.outer
Author: Matti PicusBranch: ufunc-outer Changeset: r84361:c929b6b04c28 Date: 2016-05-11 09:26 +0300 http://bitbucket.org/pypy/pypy/changeset/c929b6b04c28/ Log:implement numpypy.ufunc.outer ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy cpyext-macros-cast2: copy tests from cpyext=macros-cast
Author: Matti PicusBranch: cpyext-macros-cast2 Changeset: r84358:a450940bdbd5 Date: 2016-05-10 23:51 +0300 http://bitbucket.org/pypy/pypy/changeset/a450940bdbd5/ Log:copy tests from cpyext=macros-cast diff --git a/pypy/module/cpyext/test/test_bytesobject.py b/pypy/module/cpyext/test/test_bytesobject.py --- a/pypy/module/cpyext/test/test_bytesobject.py +++ b/pypy/module/cpyext/test/test_bytesobject.py @@ -288,6 +288,24 @@ # This does not test much, but at least the refcounts are checked. assert module.test_intern_inplace('s') == 's' +def test_bytes_macros(self): +"""The PyString_* macros cast, and calls expecting that build.""" +module = self.import_extension('foo', [ + ("test_macro_invocations", "METH_NOARGS", + """ +PyObject* o = PyString_FromString(""); +PyStringObject* u = (PyStringObject*)o; + +PyString_GET_SIZE(u); +PyString_GET_SIZE(o); + +PyString_AS_STRING(o); +PyString_AS_STRING(u); + +return o; + """)]) +assert module.test_macro_invocations() == '' + def test_hash_and_state(self): module = self.import_extension('foo', [ ("test_hash", "METH_VARARGS", diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py --- a/pypy/module/cpyext/test/test_datetime.py +++ b/pypy/module/cpyext/test/test_datetime.py @@ -117,3 +117,106 @@ datetime.timedelta, datetime.tzinfo) module.clear_types() + +def test_macros(self): +module = self.import_extension('foo', [ +("test_date_macros", "METH_NOARGS", + """ + PyDateTime_IMPORT; + if (!PyDateTimeAPI) { + PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI"); + return NULL; + } + PyObject* obj = PyDate_FromDate(2000, 6, 6); + PyDateTime_Date* d = (PyDateTime_Date*)obj; + + PyDateTime_GET_YEAR(obj); + PyDateTime_GET_YEAR(d); + + PyDateTime_GET_MONTH(obj); + PyDateTime_GET_MONTH(d); + + PyDateTime_GET_DAY(obj); + PyDateTime_GET_DAY(d); + + return obj; + """), +("test_datetime_macros", "METH_NOARGS", + """ + PyDateTime_IMPORT; + if (!PyDateTimeAPI) { + PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI"); + return NULL; + } + PyObject* obj = PyDateTime_FromDateAndTime(2000, 6, 6, 6, 6, 6, 6); + PyDateTime_DateTime* dt = (PyDateTime_DateTime*)obj; + + PyDateTime_GET_YEAR(obj); + PyDateTime_GET_YEAR(dt); + + PyDateTime_GET_MONTH(obj); + PyDateTime_GET_MONTH(dt); + + PyDateTime_GET_DAY(obj); + PyDateTime_GET_DAY(dt); + + PyDateTime_DATE_GET_HOUR(obj); + PyDateTime_DATE_GET_HOUR(dt); + + PyDateTime_DATE_GET_MINUTE(obj); + PyDateTime_DATE_GET_MINUTE(dt); + + PyDateTime_DATE_GET_SECOND(obj); + PyDateTime_DATE_GET_SECOND(dt); + + PyDateTime_DATE_GET_MICROSECOND(obj); + PyDateTime_DATE_GET_MICROSECOND(dt); + + return obj; + """), +("test_time_macros", "METH_NOARGS", + """ + PyDateTime_IMPORT; + if (!PyDateTimeAPI) { + PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI"); + return NULL; + } + PyObject* obj = PyTime_FromTime(6, 6, 6, 6); + PyDateTime_Time* t = (PyDateTime_Time*)obj; + + PyDateTime_TIME_GET_HOUR(obj); + PyDateTime_TIME_GET_HOUR(t); + + PyDateTime_TIME_GET_MINUTE(obj); + PyDateTime_TIME_GET_MINUTE(t); + + PyDateTime_TIME_GET_SECOND(obj); + PyDateTime_TIME_GET_SECOND(t); + + PyDateTime_TIME_GET_MICROSECOND(obj); + PyDateTime_TIME_GET_MICROSECOND(t); + + return obj; + """), +("test_delta_macros", "METH_NOARGS", + """ + PyDateTime_IMPORT; + if (!PyDateTimeAPI) { + PyErr_SetString(PyExc_RuntimeError, "No PyDateTimeAPI"); + return NULL; + } + PyObject* obj = PyDelta_FromDSU(6, 6, 6); + PyDateTime_Delta* delta = (PyDateTime_Delta*)obj; + + PyDateTime_DELTA_GET_DAYS(obj); +
[pypy-commit] pypy cpyext-macros-cast2: first try at generating casting macros, but must remove second macro from pypy_macros.h
Author: Matti PicusBranch: cpyext-macros-cast2 Changeset: r84359:463b5eaaf35d Date: 2016-05-11 01:04 +0300 http://bitbucket.org/pypy/pypy/changeset/463b5eaaf35d/ Log:first try at generating casting macros, but must remove second macro from pypy_macros.h diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -301,7 +301,7 @@ DEFAULT_HEADER = 'pypy_decl.h' def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER, -gil=None, result_borrowed=False, result_is_ll=False): +gil=None, result_borrowed=False, result_is_ll=False, cast=False): """ Declares a function to be exported. - `argtypes`, `restype` are lltypes and describe the function signature. @@ -313,6 +313,8 @@ a C function pointer, but not exported by the API headers. - set `gil` to "acquire", "release" or "around" to acquire the GIL, release the GIL, or both +- 'cast' if True will create an UPPER CASE macro definition that casts + the first argument to the proper PyObject* type """ if isinstance(restype, lltype.Typedef): real_restype = restype.OF @@ -433,6 +435,8 @@ if header == DEFAULT_HEADER: FUNCTIONS[func_name] = api_function FUNCTIONS_BY_HEADER.setdefault(header, {})[func_name] = api_function +if cast: +CASTS.setdefault(header, {})[func_name] = api_function INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests return unwrapper_raise # used in 'normal' RPython code. return decorate @@ -451,6 +455,7 @@ INTERPLEVEL_API = {} FUNCTIONS = {} +CASTS = {} FUNCTIONS_BY_HEADER = {} # These are C symbols which cpyext will export, but which are defined in .c @@ -995,7 +1000,6 @@ arg = db.gettype(argtype) arg = arg.replace('@', 'arg%d' % (i,)).strip() args.append(arg) -args = ', '.join(args) or "void" return restype, args #_ @@ -1023,6 +1027,7 @@ # added only for the macro, not the decl continue restype, args = c_function_signature(db, func) +args = ', '.join(args) or "void" members.append('%s (*%s)(%s);' % (restype, name, args)) structindex[name] = len(structindex) structmembers = '\n'.join(members) @@ -1254,6 +1259,25 @@ for decl in FORWARD_DECLS: pypy_decls.append("%s;" % (decl,)) +casts = [] +for header_name, header_functions in CASTS.iteritems(): +header = decls[header_name] +for name, func in sorted(header_functions.iteritems()): +# create define casts like +# #define PyInt_AS_LONG(a1) PyPyInt_AS_LONG(PyObject *)a1) +if not func: +continue +casts.append(name) +_name = mangle_name(prefix, name) +assert _name is not None, 'error converting %s' % name +restype, args = c_function_signature(db, func) +l_args = ', '.join(['a%d' % i for i in xrange(len(args))]) +r_args = ', '.join(['(%s)a%d' % (a.split('arg')[0], i) +for i,a in enumerate(args)]) +_name = mangle_name(prefix, name) +header.append("#define %s(%s) %s(%s)" % (name, l_args, _name, r_args)) +print casts + for header_name, header_functions in FUNCTIONS_BY_HEADER.iteritems(): if header_name not in decls: header = decls[header_name] = [] @@ -1265,14 +1289,12 @@ for name, func in sorted(header_functions.iteritems()): if not func: continue -if header == DEFAULT_HEADER: -_name = name -else: -# this name is not included in pypy_macros.h +if name not in casts: _name = mangle_name(prefix, name) assert _name is not None, 'error converting %s' % name header.append("#define %s %s" % (name, _name)) restype, args = c_function_signature(db, func) +args = ', '.join(args) or "void" header.append("PyAPI_FUNC(%s) %s(%s);" % (restype, _name, args)) if api_struct: callargs = ', '.join('arg%d' % (i,) @@ -1408,7 +1430,7 @@ def setup_library(space): "NOT_RPYTHON" use_micronumpy = setup_micronumpy(space) -export_symbols = sorted(FUNCTIONS) + sorted(SYMBOLS_C) + sorted(GLOBALS) +export_symbols = sorted(FUNCTIONS) + sorted(SYMBOLS_C) + sorted(GLOBALS) # dict -> list from rpython.translator.c.database import LowLevelDatabase db = LowLevelDatabase() prefix = 'PyPy' diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py ---
[pypy-commit] pypy cpyext-ext: merge default into branch
Author: Matti PicusBranch: cpyext-ext Changeset: r84356:f5d55063ed2d Date: 2016-05-09 21:00 +0300 http://bitbucket.org/pypy/pypy/changeset/f5d55063ed2d/ Log:merge default into branch diff too long, truncating to 2000 out of 24254 lines diff --git a/dotviewer/graphserver.py b/dotviewer/graphserver.py --- a/dotviewer/graphserver.py +++ b/dotviewer/graphserver.py @@ -143,6 +143,11 @@ if __name__ == '__main__': if len(sys.argv) != 2: +if len(sys.argv) == 1: +# start locally +import sshgraphserver +sshgraphserver.ssh_graph_server(['LOCAL']) +sys.exit(0) print >> sys.stderr, __doc__ sys.exit(2) if sys.argv[1] == '--stdio': diff --git a/dotviewer/sshgraphserver.py b/dotviewer/sshgraphserver.py --- a/dotviewer/sshgraphserver.py +++ b/dotviewer/sshgraphserver.py @@ -4,11 +4,14 @@ Usage: sshgraphserver.py hostname [more args for ssh...] +sshgraphserver.py LOCAL This logs in to 'hostname' by passing the arguments on the command-line to ssh. No further configuration is required: it works for all programs using the dotviewer library as long as they run on 'hostname' under the same username as the one sshgraphserver logs as. + +If 'hostname' is the string 'LOCAL', then it starts locally without ssh. """ import graphserver, socket, subprocess, random @@ -18,12 +21,19 @@ s1 = socket.socket() s1.bind(('127.0.0.1', socket.INADDR_ANY)) localhost, localport = s1.getsockname() -remoteport = random.randrange(1, 2) -# ^^^ and just hope there is no conflict -args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % (remoteport, localport)] -args = args + sshargs + ['python -u -c "exec input()"'] -print ' '.join(args[:-1]) +if sshargs[0] != 'LOCAL': +remoteport = random.randrange(1, 2) +# ^^^ and just hope there is no conflict + +args = ['ssh', '-S', 'none', '-C', '-R%d:127.0.0.1:%d' % ( +remoteport, localport)] +args = args + sshargs + ['python -u -c "exec input()"'] +else: +remoteport = localport +args = ['python', '-u', '-c', 'exec input()'] + +print ' '.join(args) p = subprocess.Popen(args, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE) diff --git a/lib-python/2.7/test/test_descr.py b/lib-python/2.7/test/test_descr.py --- a/lib-python/2.7/test/test_descr.py +++ b/lib-python/2.7/test/test_descr.py @@ -1735,7 +1735,6 @@ ("__reversed__", reversed, empty_seq, set(), {}), ("__length_hint__", list, zero, set(), {"__iter__" : iden, "next" : stop}), -("__sizeof__", sys.getsizeof, zero, set(), {}), ("__instancecheck__", do_isinstance, return_true, set(), {}), ("__missing__", do_dict_missing, some_number, set(("__class__",)), {}), @@ -1747,6 +1746,8 @@ ("__format__", format, format_impl, set(), {}), ("__dir__", dir, empty_seq, set(), {}), ] +if test_support.check_impl_detail(): +specials.append(("__sizeof__", sys.getsizeof, zero, set(), {})) class Checker(object): def __getattr__(self, attr, test=self): @@ -1768,10 +1769,6 @@ raise MyException for name, runner, meth_impl, ok, env in specials: -if name == '__length_hint__' or name == '__sizeof__': -if not test_support.check_impl_detail(): -continue - class X(Checker): pass for attr, obj in env.iteritems(): diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -397,20 +397,7 @@ data. Later, when this new cdata object is garbage-collected, 'destructor(old_cdata_object)' will be called. """ -try: -gcp = self._backend.gcp -except AttributeError: -pass -else: -return gcp(cdata, destructor) -# -with self._lock: -try: -gc_weakrefs = self.gc_weakrefs -except AttributeError: -from .gc_weakref import GcWeakrefs -gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self) -return gc_weakrefs.build(cdata, destructor) +return self._backend.gcp(cdata, destructor) def _get_cached_btype(self, type): assert self._lock.acquire(False) is False diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py --- a/lib_pypy/cffi/backend_ctypes.py +++ b/lib_pypy/cffi/backend_ctypes.py @@ -460,6 +460,11 @@ return x._value raise TypeError("character expected, got %s" % type(x).__name__) +def __nonzero__(self): +