[pypy-commit] pypy cpyext-macros-cast2: abandon branch

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 
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

2016-05-11 Thread devin.jeanpierre
Author: Devin Jeanpierre 
Branch: 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.

2016-05-11 Thread devin.jeanpierre
Author: Devin Jeanpierre 
Branch: 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.

2016-05-11 Thread devin.jeanpierre
Author: Devin Jeanpierre 
Branch: 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.

2016-05-11 Thread devin.jeanpierre
Author: Devin Jeanpierre 
Branch: 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.

2016-05-11 Thread devin.jeanpierre
Author: Devin Jeanpierre 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread rlamy
Author: Ronan Lamy 
Branch: 
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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread rlamy
Author: Ronan Lamy 
Branch: 
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

2016-05-11 Thread cfbolz
Author: Carl Friedrich Bolz 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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()

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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.

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 
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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 
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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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:

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 
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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 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

2016-05-11 Thread arigo
Author: Armin Rigo 
Branch: 
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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 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

2016-05-11 Thread mattip
Author: Matti Picus 
Branch: 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):
+