[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