[pypy-svn] r19946 - in pypy/dist/pypy/translator/llvm: . module test

rxe at codespeak.net rxe at codespeak.net
Wed Nov 16 20:20:49 CET 2005


Author: rxe
Date: Wed Nov 16 20:20:44 2005
New Revision: 19946

Added:
   pypy/dist/pypy/translator/llvm/module/raisingop.h
Modified:
   pypy/dist/pypy/translator/llvm/build_llvm_module.py
   pypy/dist/pypy/translator/llvm/externs2ll.py
   pypy/dist/pypy/translator/llvm/genllvm.py
   pypy/dist/pypy/translator/llvm/module/genexterns.c
   pypy/dist/pypy/translator/llvm/module/support.py
   pypy/dist/pypy/translator/llvm/opwriter.py
   pypy/dist/pypy/translator/llvm/test/test_exc_operation.py
Log:
Add missing exception throwing operations.

Rewrite raising operations in C via expanding out macros genc's src/int.h.

Also:

* added verify pass to simple optimisations in build llvm module
* smalls refactor to genllvm interface to allow translation
* simplify the extfunctions in module support, since we dont need dependencies anymore




Modified: pypy/dist/pypy/translator/llvm/build_llvm_module.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/build_llvm_module.py	(original)
+++ pypy/dist/pypy/translator/llvm/build_llvm_module.py	Wed Nov 16 20:20:44 2005
@@ -27,6 +27,8 @@
 
     # clean up disgusting code
     "-simplifycfg",
+
+    "-verify",
     ]))
 
 flags = os.popen("gccas /dev/null -o /dev/null -debug-pass=Arguments 2>&1").read()[17:-1].split()

Modified: pypy/dist/pypy/translator/llvm/externs2ll.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs2ll.py	(original)
+++ pypy/dist/pypy/translator/llvm/externs2ll.py	Wed Nov 16 20:20:44 2005
@@ -163,9 +163,8 @@
                 predeclarefn(c_name, db.repr_name(obj._obj))
 
     include_files = []
-    add = include_files.append 
+    add = include_files.append
     add(path_join(os.path.dirname(__file__), "module", "genexterns.c"))
-
     from pypy.translator.c import extfunc
     src_path = path_join(os.path.dirname(extfunc.__file__), "src")
 
@@ -176,6 +175,12 @@
         s = open(f).read()
 
         # XXX this is getting a tad (even more) ridiculous
+        if s.find('__RAISING_OP__') >= 0:
+            s2 = open(path_join(os.path.dirname(__file__),
+                                "module",
+                                "raisingop.h")).read()
+            s = s.replace('__RAISING_OP__', s2)
+            
         for name in ["ll_osdefs.h", "thread_pthread.h"]:
             include_str = '#include "%s"' % name
             if s.find(include_str) >= 0:

Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py	Wed Nov 16 20:20:44 2005
@@ -8,7 +8,8 @@
 from pypy.tool.udir import udir
 from pypy.translator.llvm.codewriter import CodeWriter
 from pypy.translator.llvm import extfuncnode
-from pypy.translator.llvm.module.support import extdeclarations, extfunctions
+from pypy.translator.llvm.module.support import extdeclarations,  \
+      extfunctions, entry_functions
 from pypy.translator.llvm.node import LLVMNode
 from pypy.translator.llvm.externs2ll import post_setup_externs, generate_llfile
 from pypy.translator.llvm.gc import GcPolicy
@@ -16,7 +17,7 @@
 from pypy.translator.translator import Translator
 from pypy.translator.llvm.log import log
 
-# keep for propersity sake 
+# XXX for propersity sake 
 """run_pypy-llvm.sh [aug 29th 2005]
 before slotifying: 350Mb
 after  slotifying: 300Mb, 35 minutes until the .ll file is fully written.
@@ -154,10 +155,7 @@
         codewriter.append(self.exceptionpolicy.llvmcode(self.entrynode))
 
         # write support implementations
-        for key, (deps, impl) in extfunctions.items():
-            print key
-            if key in ["%main_noargs", "%main"]:
-                continue
+        for impl in extfunctions.values():
             codewriter.append(impl)
         self._checkpoint('write support implentations')
 
@@ -171,9 +169,26 @@
         codewriter.comment("End of file")
 
         self._checkpoint('done')
-
+        self.filename = filename
         return filename
     
+    def compile_llvm_source(self, optimize=True, exe_name=None):
+        assert hasattr(self, "filename")
+        if exe_name is not None:
+            # standalone
+            return build_llvm_module.make_module_from_llvm(self, self.filename,
+                                                           optimize=optimize,
+                                                           exe_name=exe_name)
+        else:
+            # use pyrex to create module for CPython
+            postfix = ''
+            basename = self.filename.purebasename + '_wrapper' + postfix + '.pyx'
+            pyxfile = self.filename.new(basename = basename)
+            write_pyx_wrapper(self, pyxfile)    
+            return build_llvm_module.make_module_from_llvm(self, self.filename,
+                                                           pyxfile=pyxfile,
+                                                           optimize=optimize)
+    
     def get_entry_point(self, func):
         if func is None:
             func = self.translator.entrypoint
@@ -216,12 +231,10 @@
         # XXX we need to create our own main() that calls the actual
         # entry_point function
         entryfunc_name = self.entrynode.getdecl().split('%pypy_', 1)[1]
-        entryfunc_name = entryfunc_name.split('(')[0]
-        print entryfunc_name
-        if entryfunc_name not in ["main_noargs", "main"]:
-            return
-        llcode = extfunctions["%" + entryfunc_name][1]        
-        codewriter.append(llcode)
+        entryfunc_name = entryfunc_name.split('(')[0]        
+        llcode = entry_functions.get(entryfunc_name, None)
+        if llcode:
+            codewriter.append(llcode)
 
     def _checkpoint(self, msg=None):
         if not self.logging:
@@ -251,7 +264,7 @@
             log('STATS %s' % str(s))
 
 def genllvm(translator, gcpolicy=None, exceptionpolicy=None,
-            log_source=False, optimize=True, exe_name=None, logging=False):
+            log_source=False, logging=False, **kwds):
 
     gen = GenLLVM(translator,
                   GcPolicy.new(gcpolicy),
@@ -262,20 +275,7 @@
     if log_source:
         log(open(filename).read())
 
-    if exe_name is not None:
-        # standalone
-        return build_llvm_module.make_module_from_llvm(gen, filename,
-                                                       optimize=optimize,
-                                                       exe_name=exe_name)
-    else:
-        # use pyrex to create module for CPython
-        postfix = ''
-        basename = filename.purebasename + '_wrapper' + postfix + '.pyx'
-        pyxfile = filename.new(basename = basename)
-        write_pyx_wrapper(gen, pyxfile)    
-        return build_llvm_module.make_module_from_llvm(gen, filename,
-                                                       pyxfile=pyxfile,
-                                                       optimize=optimize)
+    return gen.compile_llvm_source(**kwds)
 
 def compile_module(function, annotation, view=False, **kwds):
     t = Translator(function)

Modified: pypy/dist/pypy/translator/llvm/module/genexterns.c
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/genexterns.c	(original)
+++ pypy/dist/pypy/translator/llvm/module/genexterns.c	Wed Nov 16 20:20:44 2005
@@ -24,4 +24,7 @@
 //the placeholder in the next line gets replaced by the actual python.h path
 #include __PYTHON_H__
 
+// overflows/zeros/values raising operations
+__RAISING_OP__
+
 // Append some genc files here manually from python

Added: pypy/dist/pypy/translator/llvm/module/raisingop.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/module/raisingop.h	Wed Nov 16 20:20:44 2005
@@ -0,0 +1,215 @@
+/* expanded macros of genc's c/int.h */
+
+int pypyop_int_neg_ovf(int x) {
+  long r = -x;
+  if (x >= 0 || x != -x){
+    return r;
+  } else {
+    raisePyExc_OverflowError("integer negate");
+    return 0;
+  }
+}
+
+int pypyop_int_abs_ovf(int x) {
+  int r = x >= 0 ? x : -x;
+  if (x >= 0 || x != -x) {
+    return r;
+  } else {
+    raisePyExc_OverflowError("integer absolute");
+    return 0;
+  }
+}
+
+int pypyop_int_add_ovf(int x, int y) {
+  int r = x + y;
+  
+  if ((r^x) >= 0 || (r^y) >= 0) {
+    return r;
+  } else {
+    raisePyExc_OverflowError("integer addition");
+    return 0;
+  }
+}
+
+int pypyop_int_sub_ovf(int x, int y) {
+  int r = x - y;
+  
+  if ((r^x) >= 0 || (r^(~y)) >= 0) {
+    return r;
+  } else {
+    raisePyExc_OverflowError("integer subtraction");
+    return 0;
+  }
+
+  return r;
+}
+
+int _pypyop_int_mul_ovf(long a, long b, long *longprod) {
+  double doubled_longprod;	/* (double)longprod */
+  double doubleprod;		/* (double)a * (double)b */
+  
+  *longprod = a * b;
+  doubleprod = (double)a * (double)b;
+  doubled_longprod = (double)*longprod;
+  
+  /* Fast path for normal case:  small multiplicands, and no info
+     is lost in either method. */
+  if (doubled_longprod == doubleprod)
+    return 1;
+  
+  /* Somebody somewhere lost info.  Close enough, or way off?  Note
+     that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
+     The difference either is or isn't significant compared to the
+     true value (of which doubleprod is a good approximation).
+  */
+  {
+    const double diff = doubled_longprod - doubleprod;
+    const double absdiff = diff >= 0.0 ? diff : -diff;
+    const double absprod = doubleprod >= 0.0 ? doubleprod :
+      -doubleprod;
+    /* absdiff/absprod <= 1/32 iff
+       32 * absdiff <= absprod -- 5 good bits is "close enough" */
+    if (32.0 * absdiff <= absprod)
+      return 1;
+    return 0;
+  }
+}
+
+int pypyop_int_mul_ovf(int x, int y) {
+  long r;
+
+#ifndef HAVE_LONG_LONG
+  
+  if (_pypyop_int_mul_ovf(x, y, &r)) {
+      return r;
+  } else {
+    raisePyExc_OverflowError("integer multiplication");
+  }
+
+#else
+  
+  PY_LONG_LONG lr = (PY_LONG_LONG)(x) * (PY_LONG_LONG)(y);
+  r = (long)lr;
+  if ((PY_LONG_LONG)r == lr) {
+    return r;
+  } else {
+    raisePyExc_OverflowError("integer multiplication");
+  }
+#endif
+}
+
+int pypyop_int_lshift_ovf_val(int x, int y) {
+  int r;
+
+  if (y < 0) {
+    raisePyExc_ValueError("negative shift count");
+    return 0;
+  }
+
+  r = x << y;
+  if (x != Py_ARITHMETIC_RIGHT_SHIFT(long, r, y)) {
+    raisePyExc_OverflowError("x<<y loosing bits or changing sign");
+    return 0;
+  }
+
+  return r;
+}
+
+int pypyop_int_rshift_val(int x, int y) {
+  if (y < 0) {
+    raisePyExc_ValueError("negative shift count");
+    return 0;
+  } else {
+    return x >> y;
+  }
+}
+
+long _pypyop_divmod_adj(long x, long y, long *p_rem) {
+
+  long xdivy = x / y;
+  long xmody = x - xdivy * y;
+  /* If the signs of x and y differ, and the remainder is non-0,
+   * C89 doesn't define whether xdivy is now the floor or the
+   * ceiling of the infinitely precise quotient.  We want the floor,
+   * and we have it iff the remainder's sign matches y's.
+   */
+  if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
+    xmody += y;
+    --xdivy;
+    assert(xmody && ((y ^ xmody) >= 0));
+  }
+  if (p_rem)
+    *p_rem = xmody;
+  return xdivy;
+}
+
+int pypyop_int_floordiv_ovf_zer(int x, int y) {
+  if (y) {
+    if (y == -1 && x < 0 && ((unsigned long) x << 1) == 0) {
+      raisePyExc_OverflowError("integer division");
+      return 0;
+      } else {
+	return _pypyop_divmod_adj(x, y, NULL);
+      }
+  } else {
+    raisePyExc_ZeroDivisionError("integer division");
+    return 0;
+  }
+}
+
+int pypyop_int_floordiv_zer(int x, int y) {
+  if (y) {
+    return _pypyop_divmod_adj(x, y, NULL);
+  } else {
+    raisePyExc_ZeroDivisionError("integer division");
+    return 0;
+  }
+}
+
+unsigned int pypyop_uint_floordiv_zer(unsigned int x, unsigned int y) {
+  if (y) {
+    return x / y;
+  } else {
+    raisePyExc_ZeroDivisionError("integer division");
+    return 0;
+  }
+}
+
+int pypyop_int_mod_ovf_zer(int x, int y) {
+  long r;
+  if (y) {
+    if (y == -1 && x < 0 && ((unsigned long) x << 1) == 0) {
+      _pypyop_divmod_adj(x, y, &r);
+      return r;
+    } else {
+      raisePyExc_OverflowError("integer modulo");
+      return 0;
+    }
+
+  } else {
+    raisePyExc_ZeroDivisionError("integer modulo");
+    return 0;
+  }
+}
+
+int pypyop_int_mod_zer(int x, int y) {
+  long r;
+  if (y) {
+      _pypyop_divmod_adj(x, y, &r);
+      return r;
+  } else {
+    raisePyExc_ZeroDivisionError("integer modulo");
+    return 0;
+  }
+}
+
+unsigned int pypyop_uint_mod_zer(unsigned int x, unsigned int y) {
+  unsigned long r;
+  if (y) {
+      _pypyop_divmod_adj(x, y, &r);
+      return r;
+  } else {
+    raisePyExc_ZeroDivisionError("integer modulo");
+    return 0;
+  }
+}

Modified: pypy/dist/pypy/translator/llvm/module/support.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/support.py	(original)
+++ pypy/dist/pypy/translator/llvm/module/support.py	Wed Nov 16 20:20:44 2005
@@ -3,6 +3,7 @@
 %last_exception_type  = internal global %RPYTHON_EXCEPTION_VTABLE* null
 %last_exception_value = internal global %RPYTHON_EXCEPTION* null
 
+; XXXX This in a translation option - move to exception.py!
 ;8208=8192+16 in the next line because the last one (16 bytes maxsize) might start at 8190 for instance.
 %exception_ringbuffer = internal global [8208 x sbyte] zeroinitializer
 %exception_ringbuffer_index = internal global uint 0
@@ -12,28 +13,27 @@
 declare ccc void %llvm.memcpy(sbyte*, sbyte*, uint, uint)
 """
 
-
 extfunctions = {}
 
-extfunctions["%RPyString_AsString"] = ((), """
+extfunctions["%RPyString_AsString"] = """
 internal fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) {
     %source1ptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1
     %source1 = cast [0 x sbyte]* %source1ptr to sbyte*
     ret sbyte* %source1
 }
 
-""")
+"""
 
-extfunctions["%RPyString_Size"] = ((), """
+extfunctions["%RPyString_Size"] = """
 internal fastcc int %RPyString_Size(%RPyString* %structstring) {
     %sizeptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0
     %size = load int* %sizeptr
     ret int %size
 }
 
-""")
+"""
 
-extfunctions["%RPyString_FromString"] = ((), """
+extfunctions["%RPyString_FromString"] = """
 internal fastcc %RPyString* %RPyString_FromString(sbyte* %s) {
     %lenu      = call ccc uint %strlen(sbyte* %s)
     %len       = cast uint %lenu to int
@@ -46,11 +46,11 @@
     ret %RPyString* %rpy
 }
 
-""")
+"""
 
-#abs functions
-extfunctions["%int_abs"] = ((), """
-internal fastcc int %int_abs(int %x) {
+# abs functions
+extfunctions["%pypyop_int_abs"] = """
+internal fastcc int %pypyop_int_abs(int %x) {
 block0:
     %cond1 = setge int %x, 0
     br bool %cond1, label %return_block, label %block1
@@ -62,10 +62,10 @@
     ret int %result
 }
 
-""")
+"""
 
-extfunctions["%float_abs"] = ((), """
-internal fastcc double %float_abs(double %x) {
+extfunctions["%pypyop_float_abs"] = """
+internal fastcc double %pypyop_float_abs(double %x) {
 block0:
     %cond1 = setge double %x, 0.0
     br bool %cond1, label %return_block, label %block1
@@ -77,13 +77,12 @@
     ret double %result
 }
 
-""")
-
+"""
 
 
-#prepare exceptions
-for exc in "ZeroDivisionError OverflowError ValueError".split():    #_ZER _OVF _VAL
-    extfunctions["%%prepare_%(exc)s" % locals()] = ((), """
+# prepare exceptions
+for exc in "ZeroDivisionError OverflowError ValueError".split():
+    extfunctions["%%prepare_%(exc)s" % locals()] = """
 internal fastcc void %%prepare_%(exc)s() {
     %%exception_value = cast %%structtype.%(exc)s* %%structinstance.%(exc)s to %%RPYTHON_EXCEPTION*
     %%tmp             = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0
@@ -92,12 +91,13 @@
     store %%RPYTHON_EXCEPTION* %%exception_value, %%RPYTHON_EXCEPTION** %%last_exception_value
     ret void
 }
-""" % locals())
+""" % locals()
 
 
-#prepare and raise exceptions (%msg not used right now!)
-for exc in "IOError ZeroDivisionError OverflowError ValueError RuntimeError".split():    #_ZER _OVF _VAL
-    extfunctions["%%raisePyExc_%(exc)s" % locals()] = ((), """
+# prepare and raise exceptions (%msg not used right now!)
+for exc in "IOError ZeroDivisionError " \
+           "OverflowError ValueError RuntimeError".split():
+    extfunctions["%%raisePyExc_%(exc)s" % locals()] = """
 internal fastcc void %%raisePyExc_%(exc)s(sbyte* %%msg) {
     %%exception_value = cast %%structtype.%(exc)s* %%structinstance.%(exc)s to %%RPYTHON_EXCEPTION*
     %%tmp             = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0
@@ -107,172 +107,21 @@
     call fastcc void %%unwind()
     ret void
 }
-""" % locals())
-
-
-#error-checking-code
-
-zer_test = """
-    %%cond = seteq %s %%y, 0
-    br bool %%cond, label %%is_0, label %%is_not_0
-is_0:
-    call fastcc void %%prepare_ZeroDivisionError()
-    call fastcc void %%unwind()
-    ret %s 0
-
-is_not_0:
-"""
-int_zer_test    = zer_test % ('int'   ,'int')
-double_zer_test = zer_test % ('double','double')
-
-
-#overflow: normal operation, ...if ((x) >= 0 || (x) != -(x)) OK else _OVF()
-#note: XXX this hardcoded int32 minint value is used because of a pre llvm1.6 bug!
-
-int_ovf_test = """
-    %cond2 = setne int %x, -2147483648
-    br bool %cond2, label %return_block, label %ovf
-ovf:
-;    %cond2 = setge int %x, 0
-;    br bool %cond2, label %return_block, label %ovf2
-;ovf2:
-;    %xneg  = sub int 0, %x
-;    %cond3 = setne int %x, %xneg
-;    br bool %cond3, label %return_block, label %ovf3
-;ovf3:
-    call fastcc void %prepare_OverflowError()
-    call fastcc void %unwind()
-    ret int 0
-"""
-
-
-#binary with ZeroDivisionError only
-
-for func_inst in "floordiv_zer:div mod_zer:rem".split():
-    func, inst = func_inst.split(':')
-    for prefix_type_ in "int:int uint:uint".split():
-        prefix, type_ = prefix_type_.split(':')
-        type_zer_test = zer_test % (type_, type_)
-        extfunctions["%%%(prefix)s_%(func)s" % locals()] = ((), """
-internal fastcc %(type_)s %%%(prefix)s_%(func)s(%(type_)s %%x, %(type_)s %%y) {
-    %(type_zer_test)s
-    %%z = %(inst)s %(type_)s %%x, %%y
-    ret %(type_)s %%z
-}
-
-""" % locals())
-
-
-#unary with OverflowError only
-
-extfunctions["%int_neg_ovf"] = ((), """
-internal fastcc int %%int_neg_ovf(int %%x) {
-block1:
-    %%x2 = sub int 0, %%x
-    %(int_ovf_test)s
-return_block:
-    ret int %%x2
-}
-""" % locals())
-
-extfunctions["%int_abs_ovf"] = ((), """
-internal fastcc int %%int_abs_ovf(int %%x) {
-block0:
-    %%cond1 = setge int %%x, 0
-    br bool %%cond1, label %%return_block, label %%block1
-block1:
-    %%x2 = sub int 0, %%x
-    %(int_ovf_test)s
-return_block:
-    %%result = phi int [%%x, %%block0], [%%x2, %%block1]
-    ret int %%result
-}
-""" % locals())
-
-
-#binary with OverflowError only
-
-extfunctions["%int_add_ovf"] = ((), """
-internal fastcc int %%int_add_ovf(int %%x, int %%y) {
-    %%t = add int %%x, %%y
-    %(int_ovf_test)s
-return_block:
-    ; XXX: TEST int_add_ovf checking
-    ret int %%t
-}
-""" % locals())
-
-extfunctions["%int_sub_ovf"] = ((), """
-internal fastcc int %%int_sub_ovf(int %%x, int %%y) {
-    %%t = sub int %%x, %%y
-    %(int_ovf_test)s
-return_block:
-    ; XXX: TEST int_sub_ovf checking
-    ret int %%t
-}
-""" % locals())
-
-extfunctions["%int_mul_ovf"] = ((), """
-internal fastcc int %%int_mul_ovf(int %%x, int %%y) {
-    %%t = mul int %%x, %%y
-    %(int_ovf_test)s
-return_block:
-    ; XXX: TEST int_mul_ovf checking
-    ret int %%t
-}
-""" % locals())
-
-
-#binary with OverflowError and ValueError
-
-extfunctions["%int_lshift_ovf_val"] = ((), """
-internal fastcc int %%int_lshift_ovf_val(int %%x, int %%y) {
-    %%yu = cast int %%y to ubyte
-    %%t = shl int %%x, ubyte %%yu
-    %(int_ovf_test)s
-return_block:
-    ; XXX: TODO int_lshift_ovf_val checking VAL
-    ret int %%t
-}
-""" % locals())
-
-
-#binary with OverflowError and ZeroDivisionError
-
-extfunctions["%int_floordiv_ovf_zer"] = ((), """
-internal fastcc int %%int_floordiv_ovf_zer(int %%x, int %%y) {
-    %(int_zer_test)s
-    %%t = div int %%x, %%y
-    %(int_ovf_test)s
-return_block:
-    ; XXX: TEST int_floordiv_ovf_zer checking
-    ret int %%t
-}
-""" % locals())
-
-extfunctions["%int_mod_ovf_zer"] = ((), """
-internal fastcc int %%int_mod_ovf_zer(int %%x, int %%y) {
-    %(int_zer_test)s
-    %%t = rem int %%x, %%y
-    %(int_ovf_test)s
-return_block:
-    ; XXX: TEST int_mod_ovf_zer checking
-    ret int %%t
-}
-""" % locals())
-
+""" % locals()
 
 # main functions to be moved to genexterns
+# XXX rewrite these in C
+entry_functions = {}
 
-extfunctions["%main_noargs"] = [(), """
+entry_functions["main_noargs"] = """
 int %main(int %argc, sbyte** %argv) {
     store int 0, int* %GC_all_interior_pointers
     %ret  = call fastcc int %pypy_main_noargs()
     ret int %ret
 }
-"""]
+"""
 
-extfunctions["%main"] = [(), """
+entry_functions["entry_point"] = """
 int %main(int %argc, sbyte** %argv) {
 entry:
     store int 0, int* %GC_all_interior_pointers
@@ -295,4 +144,4 @@
     %ret  = call fastcc int %pypy_entry_point(%RPyListOfString* %pypy_argv)
     ret int %ret
 }
-"""]
+"""

Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Wed Nov 16 20:20:44 2005
@@ -135,7 +135,7 @@
     keepalive = _skipped
 
     def int_abs(self, op):
-        functionref = '%' + op.opname
+        functionref = '%pypyop_' + op.opname
         ExternalFuncNode.used_external_functions[functionref] = True
         self.codewriter.call(self.db.repr_arg(op.result),
                              self.db.repr_arg_type(op.result),
@@ -297,17 +297,12 @@
 
         if op.opname == 'invoke:direct_call':
             functionref = self.db.repr_arg(op_args[0])
-        else:   #operation
+
+        else:
+            # operation - provided by genexterns 
             opname = op.opname.split(':',1)[1]
-            op_args = ['%' + opname] + op_args
+            op_args = ['%pypyop_' + opname] + op_args
             functionref = op_args[0]
-            if functionref in extfunctions:
-                ExternalFuncNode.used_external_functions[functionref] = True
-            else:
-                msg = "exception raising operation %s not found" %(op.opname,)
-                self.codewriter.comment('XXX: Error: ' + msg)
-                # XXX commented out for testing
-                #assert functionref in extfunctions, msg
         
         assert len(op_args) >= 1
         # at least one label and one exception label

Modified: pypy/dist/pypy/translator/llvm/test/test_exc_operation.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_exc_operation.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/test_exc_operation.py	Wed Nov 16 20:20:44 2005
@@ -73,32 +73,65 @@
 ############################
 
 def test_int_overflow():
-    py.test.skip("ovf operator exception not implemented")
-    fn = compile_function(snippet.add_func, [int])
-    raises(OverflowError, fn, sys.maxint)
+    def fn(i):
+        try:
+            return snippet.add_func(i)
+        except OverflowError:
+            return 123
+    f = compile_function(fn, [int])
+    assert f(10) == 11
+    assert f(sys.maxint) == 123
 
 def test_int_div_ovf_zer():
-    py.test.skip("ovf_zer operator exception not implemented")
-    fn = compile_function(snippet.div_func, [int])
-    raises(OverflowError, fn, -1)
-    raises(ZeroDivisionError, fn, 0)
+    def fn(i):
+        try:
+            return snippet.div_func(i)
+        except OverflowError:
+            return 123
+        except ZeroDivisionError:
+            return 1234
+        
+    fn = compile_function(fn, [int])
+    assert fn(-1) == 123
+    assert fn(0) == 1234
 
 def test_int_mod_ovf_zer():
-    py.test.skip("ovf_zer operator exception not implemented")
-    fn = compile_function(snippet.mod_func, [int])
-    raises(OverflowError, fn, -1)
-    raises(ZeroDivisionError, fn, 0)
+    def fn(i):
+        try:
+            return snippet.mod_func(i)
+        except OverflowError:
+            return 123
+        except ZeroDivisionError:
+            return 1234
+            
+    fn = compile_function(fn, [int])
+    assert fn(0) == 1234
+    assert fn(1) == 123
 
 def test_int_rshift_val():
-    py.test.skip("val operator exception not implemented")
-    fn = compile_function(snippet.rshift_func, [int])
-    raises(ValueError, fn, -1)
+    def fn(i):
+        try:
+            return snippet.rshift_func(i)
+        except ValueError:
+            return 123
+        
+    f = compile_function(fn, [int])
+    assert f(0) == -sys.maxint - 1
+    assert f(-1) == 123
 
 def test_int_lshift_ovf_val():
-    py.test.skip("ovf_val operator exception not implemented")
-    fn = compile_function(snippet.lshift_func, [int])
-    raises(ValueError, fn, -1)
-    raises(OverflowError, fn, 1)
+    def fn(i):
+        try:
+            return snippet.lshift_func(i)
+        except ValueError:
+            return 123
+        except OverflowError:
+            return 1234
+        
+    f = compile_function(fn, [int])
+    assert f(0) == -sys.maxint-1
+    assert f(-1) == 123
+    assert f(1) == 1234
 
 def test_uint_arith():
     py.test.skip("zer operator exception not implemented")
@@ -113,7 +146,6 @@
         assert f(i) == fn(i)
 
 def test_int_add_ovf():
-    py.test.skip("ovf operator exception not implemented")
     def add_func(i):
         try:
             return ovfcheck(i + 1)
@@ -126,23 +158,23 @@
     assert f(sys.maxint) == 123
 
 def test_int_sub_ovf():
-    py.test.skip("ovf operator exception not implemented")
     def sub_func(i):
         try:
-            return ovfcheck(i - 1)
+            return ovfcheck(i - 2)
         except OverflowError:
             return 123
     f = compile_function(sub_func, [int])
     assert f(0) == sub_func(0)
-    assert f(0) == 1
     assert f(sys.maxint) == sub_func(sys.maxint)
-    assert f(sys.maxint) == 123
+    assert f(-sys.maxint) == 123
 
-def test_shift_with_overflow():
-    py.test.skip("shift operator exception not implemented")
-    shl = compile_function(llvmsnippet.shiftleft, [int, int])
-    shr = compile_function(llvmsnippet.shiftright, [int, int])
-    for i in [1, 2, 3, 100000, 2000000, sys.maxint - 1]:
-        for j in [1, 2, 3, 100000, 2000000, sys.maxint - 1]:
-            assert shl(i, j) == i << j
-            assert shr(i, j) == i >> j
+def test_int_mul_ovf():
+    def mul_func(i):
+        try:
+            return ovfcheck(i * 100)
+        except OverflowError:
+            return 123
+    f = compile_function(mul_func, [int])
+    assert f(0) == mul_func(0)
+    assert f(567) == mul_func(567)
+    assert f(sys.maxint) == 123



More information about the Pypy-commit mailing list