Fix wrong const optimization for "1.0 / 0.0" case

In cpython, "1.0 / 0.0" raises ZeroDivisionError
```
>>> 1.0 / 0.0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zer
```

but RustPython doesn't
```
>>>>> 1.0 / 0.0
inf
```

This is because they emits different byte codes.

```
$ echo "1.0 / 0.0" > zero-div.py

$ python -m dis zero-div.py
  1           0 LOAD_CONST               0 (1.0)
              2 LOAD_CONST               1 (0.0)
              4 BINARY_TRUE_DIVIDE
              6 POP_TOP
              8 LOAD_CONST               2 (None)
             10 RETURN_VALUE

$ cargo run --example dis zero-div.py
zero-div.py:
                 0 LoadConst            (inf)
                 1 Pop
                 2 LoadConst            (None)
                 3 ReturnValue
```

This commit stops optimization for zero division case
to generate same byte codes.
This commit is contained in:
ichyo committed 2019-10-24 00:26:02 +09:00
1 parent e4bded8ca3
commit 74c02d416e
2 files changed
+5 -1

No files matched your search

+1 -1
View File
@@ -52,7 +52,7 @@ pub fn operator(buf: &mut impl OptimizationBuffer) {
(op!(Multiply), lc!(Float, lhs), lc!(Float, rhs)) => {
emitconst!(buf, [lhs_meta, rhs_meta], Float, lhs * rhs)
}
(op!(Divide), lc!(Float, lhs), lc!(Float, rhs)) => {
(op!(Divide), lc!(Float, lhs), lc!(Float, rhs)) if rhs != 0.0 => {
emitconst!(buf, [lhs_meta, rhs_meta], Float, lhs / rhs)
}
(op!(Power), lc!(Float, lhs), lc!(Float, rhs)) => {
+4
View File
@@ -144,6 +144,10 @@ assert_raises(ZeroDivisionError, lambda: 2 / 0.0)
assert_raises(ZeroDivisionError, lambda: 2 // 0.0)
assert_raises(ZeroDivisionError, lambda: 2 % 0.0)
# assert_raises(ZeroDivisionError, divmod, 2, 0.0)
assert_raises(ZeroDivisionError, lambda: 2.0 / 0.0)
assert_raises(ZeroDivisionError, lambda: 2.0 // 0.0)
assert_raises(ZeroDivisionError, lambda: 2.0 % 0.0)
assert_raises(ZeroDivisionError, divmod, 2.0, 0.0)
assert 1.2.__int__() == 1
assert 1.2.__float__() == 1.2