[pypy-commit] pypy reflex-support: remove raised OperationError that could be caught at the interp level (speeds up overloads)

wlav noreply at buildbot.pypy.org
Wed Feb 15 00:45:30 CET 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r52495:070a3cb94e09
Date: 2012-02-14 15:45 -0800
http://bitbucket.org/pypy/pypy/changeset/070a3cb94e09/

Log:	remove raised OperationError that could be caught at the interp
	level (speeds up overloads)

diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -1,6 +1,5 @@
 import sys
 
-from pypy.interpreter.error import OperationError
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rlib.rarithmetic import r_singlefloat
 from pypy.rlib import jit, libffi, clibffi, rfloat
@@ -39,8 +38,7 @@
         return fieldptr
 
     def _is_abstract(self, space):
-        raise OperationError(space.w_NotImplementedError,
-                             space.wrap("no converter available")) # more detailed part is not rpython: (actual: %s)" % type(self).__name__))
+        raise TypeError("no converter available")
 
     def convert_argument(self, space, w_obj, address):
         self._is_abstract(space)
@@ -129,8 +127,7 @@
         try:
             byteptr[0] = buf.get_raw_address()
         except ValueError:
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("raw buffer interface not supported"))
+            raise TypeError("raw buffer interface not supported")
 
 
 class NumericTypeConverterMixin(object):
@@ -181,8 +178,7 @@
         self.name = name
 
     def convert_argument(self, space, w_obj, address):
-        raise OperationError(space.w_NotImplementedError,
-                             space.wrap('no converter available for type "%s"' % self.name))
+        raise TypeError('no converter available for type "%s"' % self.name)
 
 
 class BoolConverter(TypeConverter):
@@ -192,8 +188,7 @@
     def _unwrap_object(self, space, w_obj):
         arg = space.c_int_w(w_obj)
         if arg != False and arg != True:
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("boolean value should be bool, or integer 1 or 0"))
+            raise ValueError("boolean value should be bool, or integer 1 or 0")
         return arg
 
     def convert_argument(self, space, w_obj, address):
@@ -226,16 +221,14 @@
         if space.isinstance_w(w_value, space.w_int):
             ival = space.c_int_w(w_value)
             if ival < 0 or 256 <= ival:
-                raise OperationError(space.w_TypeError,
-                                     space.wrap("char arg not in range(256)"))
+                raise ValueError("char arg not in range(256)")
 
             value = rffi.cast(rffi.CHAR, space.c_int_w(w_value))
         else:
             value = space.str_w(w_value)
 
         if len(value) != 1:  
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("char expected, got string of size %d" % len(value)))
+            raise ValueError("char expected, got string of size %d" % len(value))
         return value[0] # turn it into a "char" to the annotator
 
     def convert_argument(self, space, w_obj, address):
@@ -515,10 +508,8 @@
                     obj.cppclass.handle, self.cpptype.handle, obj.rawobject)
                 obj_address = capi.direct_ptradd(obj.rawobject, offset)
                 return rffi.cast(capi.C_OBJECT, obj_address)
-        raise OperationError(space.w_TypeError,
-                             space.wrap("cannot pass %s as %s" % (
-                                 space.type(w_obj).getname(space, "?"),
-                                 self.cpptype.name)))
+        raise TypeError("cannot pass %s as %s" %
+                        (space.type(w_obj).getname(space, "?"), self.cpptype.name))
 
     def convert_argument(self, space, w_obj, address):
         x = rffi.cast(rffi.VOIDPP, address)
diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -1,6 +1,5 @@
 import sys
 
-from pypy.interpreter.error import OperationError
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rlib import libffi, clibffi
 
@@ -21,8 +20,7 @@
 
     def execute(self, space, w_returntype, func, cppthis, num_args, args):
         rtype = capi.charp2str_free(capi.c_method_result_type(func.cpptype.handle, func.method_index))
-        raise OperationError(space.w_NotImplementedError,
-                             space.wrap('return type not available or supported ("%s")' % rtype))
+        raise TypeError('return type not available or supported ("%s")' % rtype)
 
     def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -8,7 +8,7 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 
 from pypy.rlib import libffi, rdynload, rweakref
-from pypy.rlib import jit, debug
+from pypy.rlib import jit, debug, objectmodel
 
 from pypy.module.cppyy import converter, executor, helper
 
@@ -115,7 +115,7 @@
         args_expected = len(self.arg_defs)
         args_given = len(args_w)
         if args_expected < args_given or args_given < self.args_required:
-            raise OperationError(self.space.w_TypeError, self.space.wrap("wrong number of arguments"))
+            raise TypeError("wrong number of arguments")
 
         if self.methgetter and cppthis: # only for methods
             try:
@@ -264,13 +264,8 @@
             cppyyfunc = self.functions[i]
             try:
                 return cppyyfunc.call(cppthis, w_type, args_w)
-            except OperationError, e:
-                if not (e.match(space, space.w_TypeError) or \
-                        e.match(space, space.w_NotImplementedError)):
-                    raise
+            except Exception, e:
                 errmsg += '\n\t'+str(e)
-            except KeyError:
-                pass
 
         raise OperationError(space.w_TypeError, space.wrap(errmsg))
 
@@ -314,13 +309,23 @@
     def get(self, w_cppinstance, w_type):
         cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance, can_be_None=True)
         offset = self._get_offset(cppinstance)
-        return self.converter.from_memory(self.space, w_cppinstance, w_type, offset)
+        try:
+            return self.converter.from_memory(self.space, w_cppinstance, w_type, offset)
+        except Exception, e:
+            raise OperationError(self.space.w_TypeError, self.space.wrap(str(e)))
+        except ValueError, e:
+            raise OperationError(self.space.w_ValueError, self.space.wrap(str(e)))
 
     def set(self, w_cppinstance, w_value):
         cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance, can_be_None=True)
         offset = self._get_offset(cppinstance)
-        self.converter.to_memory(self.space, w_cppinstance, w_value, offset)
-        return self.space.w_None
+        try:
+            self.converter.to_memory(self.space, w_cppinstance, w_value, offset)
+            return self.space.w_None
+        except TypeError, e:
+            raise OperationError(self.space.w_TypeError, self.space.wrap(str(e)))
+        except ValueError, e:
+            raise OperationError(self.space.w_ValueError, self.space.wrap(str(e)))
 
 W_CPPDataMember.typedef = TypeDef(
     'CPPDataMember',
diff --git a/pypy/module/cppyy/test/bench1.py b/pypy/module/cppyy/test/bench1.py
--- a/pypy/module/cppyy/test/bench1.py
+++ b/pypy/module/cppyy/test/bench1.py
@@ -64,6 +64,14 @@
             addDataToInt.call(instance, None, i)
         return i
 
+class CppyyInterpBench2(CppyyInterpBench1):
+    def __call__(self):
+        addDataToInt = self.cls.get_overload("overloadedAddDataToInt")
+        instance = self.inst
+        for i in range(NNN):
+            addDataToInt.call(instance, None, i)
+        return i
+
 class CppyyPythonBench1(object):
     scale = 1
     def __init__(self):
@@ -112,14 +120,16 @@
     # warm-up
     print "warming up ... "
     interp_bench1 = CppyyInterpBench1()
+    interp_bench2 = CppyyInterpBench2()
     python_bench1 = CppyyPythonBench1()
-    interp_bench1(); python_bench1()
+    interp_bench1(); interp_bench2(); python_bench1()
 
     # to allow some consistency checking
     print "C++ reference uses %.3fs" % t_cppref
 
     # test runs ...
     print_bench("cppyy interp", run_bench(interp_bench1))
+    print_bench("... overload", run_bench(interp_bench2))
     print_bench("cppyy python", run_bench(python_bench1))
     stat, t_cintex = commands.getstatusoutput("python bench1.py --pycintex")
     print_bench("pycintex    ", float(t_cintex))
diff --git a/pypy/module/cppyy/test/example01.cxx b/pypy/module/cppyy/test/example01.cxx
--- a/pypy/module/cppyy/test/example01.cxx
+++ b/pypy/module/cppyy/test/example01.cxx
@@ -91,6 +91,18 @@
     return m_somedata + a;
 }
 
+int example01::overloadedAddDataToInt(int a, int b) {
+   return m_somedata + a + b;
+}
+
+int example01::overloadedAddDataToInt(int a) {
+   return m_somedata + a;
+}
+
+int example01::overloadedAddDataToInt(int a, int b, int c) {
+   return m_somedata + a + b + c;
+}
+
 double example01::addDataToDouble(double a) {
     return m_somedata + a;
 }
diff --git a/pypy/module/cppyy/test/example01.h b/pypy/module/cppyy/test/example01.h
--- a/pypy/module/cppyy/test/example01.h
+++ b/pypy/module/cppyy/test/example01.h
@@ -39,6 +39,9 @@
 
 public:        // instance methods
     int addDataToInt(int a);
+    int overloadedAddDataToInt(int a, int b);
+    int overloadedAddDataToInt(int a);
+    int overloadedAddDataToInt(int a, int b, int c);
     double addDataToDouble(double a);
     int addDataToAtoi(const char* str);
     char* addToStringValue(const char* str);
diff --git a/pypy/module/cppyy/test/test_cppyy.py b/pypy/module/cppyy/test/test_cppyy.py
--- a/pypy/module/cppyy/test/test_cppyy.py
+++ b/pypy/module/cppyy/test/test_cppyy.py
@@ -59,7 +59,7 @@
 
         raises(TypeError, 't.get_overload("staticAddOneToInt").call(None, None, 1, [])')
         raises(TypeError, 't.get_overload("staticAddOneToInt").call(None, None, 1.)')
-        raises(OverflowError, 't.get_overload("staticAddOneToInt").call(None, None, maxint32+1)')
+        raises(TypeError, 't.get_overload("staticAddOneToInt").call(None, None, maxint32+1)')
 
     def test02_static_double(self):
         """Test passing of a double and returning of a double on a static function."""
diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py
--- a/pypy/module/cppyy/test/test_datatypes.py
+++ b/pypy/module/cppyy/test/test_datatypes.py
@@ -253,8 +253,8 @@
         assert c.s_uchar               == 'c'
         c.s_uchar                       = 'd'
         assert cppyy_test_data.s_uchar == 'd'
-        raises(TypeError, setattr, cppyy_test_data, 's_uchar', -1)
-        raises(TypeError, setattr, c,               's_uchar', -1)
+        raises(ValueError, setattr, cppyy_test_data, 's_uchar', -1)
+        raises(ValueError, setattr, c,               's_uchar', -1)
 
         # integer types
         c.s_short                        = -102
diff --git a/pypy/module/cppyy/test/test_fragile.py b/pypy/module/cppyy/test/test_fragile.py
--- a/pypy/module/cppyy/test/test_fragile.py
+++ b/pypy/module/cppyy/test/test_fragile.py
@@ -83,7 +83,7 @@
 
         e = fragile.E()
         raises(TypeError, e.overload, None)
-        raises(NotImplementedError, getattr, e, 'm_pp_no_such')
+        raises(TypeError, getattr, e, 'm_pp_no_such')
 
     def test05_wrong_arg_addressof(self):
         """Test addressof() error reporting"""
diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py
--- a/pypy/module/cppyy/test/test_pythonify.py
+++ b/pypy/module/cppyy/test/test_pythonify.py
@@ -60,7 +60,7 @@
 
         raises(TypeError, 'example01_class.staticAddOneToInt(1, [])')
         raises(TypeError, 'example01_class.staticAddOneToInt(1.)')
-        raises(OverflowError, 'example01_class.staticAddOneToInt(maxint32+1)')
+        raises(TypeError, 'example01_class.staticAddOneToInt(maxint32+1)')
         res = example01_class.staticAddToDouble(0.09)
         assert res == 0.09 + 0.01
 
diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py
--- a/pypy/module/cppyy/test/test_zjit.py
+++ b/pypy/module/cppyy/test/test_zjit.py
@@ -151,3 +151,23 @@
         space = FakeSpace()
         result = self.meta_interp(f, [], listops=True, backendopt=True, listcomp=True)
         self.check_jitcell_token_count(1)
+
+    def test_overload(self):
+        space = FakeSpace()
+        drv = jit.JitDriver(greens=[], reds=["i", "inst", "addDataToInt"])
+        def f():
+            lib = interp_cppyy.load_dictionary(space, "./example01Dict.so")
+            cls  = interp_cppyy.type_byname(space, "example01")
+            inst = cls.get_overload("example01").call(None, FakeReturnType(), [FakeInt(0)])
+            addDataToInt = cls.get_overload("overloadedAddDataToInt")
+            assert isinstance(inst, interp_cppyy.W_CPPInstance)
+            i = 10
+            while i > 0:
+                drv.jit_merge_point(inst=inst, addDataToInt=addDataToInt, i=i)
+                addDataToInt.call(inst, None, [FakeInt(i)])
+                i -= 1
+            return 7
+        f()
+        space = FakeSpace()
+        result = self.meta_interp(f, [], listops=True, backendopt=True, listcomp=True)
+        self.check_jitcell_token_count(1)


More information about the pypy-commit mailing list