Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dart2js issue with negating a value via an index from a list #23858

Open
sethladd opened this issue Jul 17, 2015 · 3 comments
Open

dart2js issue with negating a value via an index from a list #23858

sethladd opened this issue Jul 17, 2015 · 3 comments
Labels
area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) web-dart2js

Comments

@sethladd
Copy link
Contributor

https://dartpad.dartlang.org/8a387639cb5fdb219ffe

main() {
  var a = [0.0];
  a[0] = -0.0;
  print("a[0] is ${a[0]} , is negative? ${a[0].isNegative}"); // "a[0]=-0.0 true"

  var b = [0.0];
  print(b); // [0.0]
  b[0] = -b[0];
  print(b); // [-0.0]
  print("b[0] is ${b[0]} , is negative? ${b[0].isNegative}"); // "b[0]=0 true" (?)
}

Output from Dart Pad (dart2js):

a[0] is -0.0 , is negative? true
[0]
[-0.0]
b[0] is 0 , is negative? true

Expected: b[0] is -0.0 , is negative? true

Actual: b[0] is 0 , is negative? true


Output from the VM:

a[0] is -0.0 , is negative? true
[0.0]
[-0.0]
b[0] is -0.0 , is negative? true
@rakudrama
Copy link
Member

Consider

var x1 = 0;
var x2 = 0.0;

Under dart2js, 0 and 0.0 are represented by the same bits.
That means it must always be true that (x1 is int) == (x2 is int).
Since the run time test x2 is int == true, we analyze 0.0 as if it is an int.
Somewhere we are missing that in this world int is a subtype of double (because every JavaScript number is a double, but some represent integer values).
We also have a type inference rule that x is int ==> (-x) is int.
This leads us to an optimization that works for int values but not for doubles.
We can stringify an int value x via the idiomatic JavaScript expression ""+x.
This cannot be used for doubles since it prints -0.0 as 0.
We must either (1) make sure that -0.0 is not an int, and change the inference rule to contradict int.unary- to say the result is num, or (2) consider -0.0 to be an int and give up on generating idiomatic JavaScript.

Currently the expression confuse(-0.0) is int returns true.
To change this would require a much slower 'is int' test.
ES6 has a Number.isInteger test that also considers -0.0 to be an integer (but excludes infinities).
So it seems that we must be much more careful about generating idiomatic JavaScript for interpolation and track whether a value can be -0.0 to avoid the inconsistency.

There is a related bug with constant-folding the string representation of 0.0.
Since 0 and 0.0 are the the identical representation, dart2js should only ever print one of 0 or 0.0.
The following program prints both:

import 'package:expect/expect.dart';

@NoInline()
@AssumeDynamic()
confuse(x) => x;

main() {
  var z = 0.0;
  print('z = ${z}');
  print('confuse(z) = ${confuse(z)}');
  z = -z;
  z = -z;
  print('z = ${z}');
  print('confuse(z) = ${confuse(z)}');
}
z = 0
confuse(z) = 0
z = 0.0
confuse(z) = 0

Notice how the string is completely constant-folded, but differently:

    main: function() {
      P.print("z = 0");
      P.print("confuse(z) = " + H.S(T.confuse(0)));
      P.print("z = 0.0");
      P.print("confuse(z) = " + H.S(T.confuse(0.0)));
    }

Even more curious, this happens only for 0.0, not, say, 1.0.

@kevmoo kevmoo added type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed Type-Defect labels Mar 1, 2016
@vsmenon vsmenon added the area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. label Jul 20, 2019
@lrhn
Copy link
Member

lrhn commented Mar 20, 2024

Bug still here. DartPad now uses DDC, which doesn't have the issue.

@rakudrama
Copy link
Member

See #49870 for a more up-to-date analysis.
I think the best way to fix this is with a couple of breaking changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) web-dart2js
Projects
None yet
Development

No branches or pull requests

5 participants