1. yasirs
  2. pypy

Commits

Alex Gaynor  committed cfeea45

do the error checking for math.fmod in RPython, so it can be removed by the JIT (more efficient than round tripping with geterrno/seterrno)

  • Participants
  • Parent commits e688491
  • Branches default

Comments (0)

Files changed (3)

File pypy/module/pypyjit/test_pypy_c/test_math.py

View file
             i7 = int_add(i0, f1)
             --TICK--
             jump(..., descr=)
+        """)
+
+    def test_fmod(self):
+        def main(n):
+            import math
+
+            s = 0
+            while n > 0:
+                s += math.fmod(n, 2.0)
+                n -= 1
+            return s
+        log = self.run(main, [500])
+        assert log.result == main(500)
+        loop, = log.loops_by_filename(self.filepath)
+        assert loop.match("""
+            i1 = int_gt(i0, 0)
+            guard_true(i1, descr=...)
+            f1 = cast_int_to_float(i0)
+            i2 = float_eq(f1, inf)
+            i3 = float_eq(f1, -inf)
+            i4 = int_or(i2, i3)
+            i5 = int_is_true(i4)
+            guard_false(i5, descr=...)
+            f2 = call(ConstClass(fmod), f1, 2.0, descr=<FloatCallDescr>)
+            f3 = float_add(f0, f2)
+            i6 = int_sub(i0, 1)
+            --TICK--
+            jump(..., descr=)
         """)

File pypy/rpython/extfuncregistry.py

View file
        ('log10', [float], float),
        ('sin', [float], float),
        ('cos', [float], float),
+       ('atan2', [float, float], float),
+       ('hypot', [float, float], float),
+       ('frexp', [float], (float, int)),
+       ('ldexp', [float, int], float),
+       ('modf', [float], (float, float)),
+       ('fmod', [float, float], float),
+       ('pow', [float, float], float),
     ]),
 ]
 for module, methods in _register:
                           sandboxsafe=True,
                           llimpl=getattr(ll_math, method_name))
 
-
-complex_math_functions = [
-    ('frexp', [float],        (float, int)),
-    ('ldexp', [float, int],   float),
-    ('modf',  [float],        (float, float)),
-    ] + [(name, [float, float], float)
-         for name in 'atan2', 'fmod', 'hypot', 'pow']
-
-for name, args, res in complex_math_functions:
-    func = getattr(math, name)
-    llimpl = getattr(ll_math, 'll_math_%s' % name, None)
-    oofake = getattr(oo_math, 'll_math_%s' % name, None)
-    register_external(func, args, res, 'll_math.ll_math_%s' % name,
-                      llimpl=llimpl, oofakeimpl=oofake,
-                      sandboxsafe=True)
-
-
 # ___________________________
 # os.path functions
 

File pypy/rpython/lltypesystem/module/ll_math.py

View file
 
 
 def ll_math_fmod(x, y):
-    if isinf(y):
-        if isinf(x):
-            raise ValueError("math domain error")
-        return x  # fmod(x, +/-Inf) returns x for finite x (or if x is a NaN).
+    if isinf(x) and not isnan(y):
+        raise ValueError("math domain error")
 
-    _error_reset()
-    r = math_fmod(x, y)
-    errno = rposix.get_errno()
-    if isnan(r):
-        if isnan(x) or isnan(y):
-            errno = 0
-        else:
-            errno = EDOM
-    if errno:
-        _likely_raise(errno, r)
-    return r
+    if y == 0:
+        raise ValueError("math domain error")
+
+    return math_fmod(x, y)
 
 
 def ll_math_hypot(x, y):