Skip to content

Dart2js minified vs non-minified treats shifts differently if value < 0 #30841

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

Closed
nex3 opened this issue Sep 20, 2017 · 5 comments
Closed

Dart2js minified vs non-minified treats shifts differently if value < 0 #30841

nex3 opened this issue Sep 20, 2017 · 5 comments
Labels
area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) web-dart2js

Comments

@nex3
Copy link
Member

nex3 commented Sep 20, 2017

From @stephan-gruen on September 12, 2017 13:0

I ran into this while testing out the BZip2Encoder class from the widely used archive library, which does not work if minified.
At the end of the day this is why: the shift result from unminified and minified JavaScript is not the same if the value is negativ. So this is bad as the behavior should be the same.

print('1 >> 0  = ${1 >> 0}');
print('0 >> 0  = ${0 >> 0}');
print('-1 >> 0  = ${-1 >> 0}');
print('-2 >> 0  = ${-2 >> 0}');

print('1 >> 1  = ${1 >> 1}');
print('0 >> 1  = ${0 >> 1}');
print('-1 >> 1  = ${-1 >> 1}');
print('-2 >> 1  = ${-2 >> 1}');

print('1 << 0  = ${1 << 0}');
print('0 << 0  = ${0 << 0}');
print('-1 << 0  = ${-1 << 0}');
print('-2 << 0  = ${-2 << 0}');

print('1 << 1  = ${1 << 1}');
print('0 << 1  = ${0 << 1}');
print('-1 << 1  = ${-1 << 1}');
print('-2 << 1  = ${-2 << 1}');

pub build mode Debug (uses dart2js to generate unminified JavaScript):

 1 >> 0  = 1
 0 >> 0  = 0
-1 >> 0  = -1
-2 >> 0  = -2
 1 >> 1  = 0
 0 >> 1  = 0
-1 >> 1  = -1
-2 >> 1  = -1
 1 << 0  = 1
 0 << 0  = 0
-1 << 0  = -1
-2 << 0  = -2 
 1 << 1  = 2
 0 << 1  = 0
-1 << 1  = -2
-2 << 1  = -4

pub build mode Release (uses dart2js to generate minified JavaScript):

1 >> 0  = 1
0 >> 0  = 0
-1 >> 0  = 4294967295
-2 >> 0  = 4294967294
1 >> 1  = 0
0 >> 1  = 0
-1 >> 1  = 4294967295
-2 >> 1  = 4294967295
1 << 0  = 1
0 << 0  = 0
-1 << 0  = 4294967295
-2 << 0  = 4294967294
1 << 1  = 2
0 << 1  = 0
-1 << 1  = 4294967294
-2 << 1  = 4294967292

Copied from original issue: dart-lang/pub#1703

@nex3 nex3 changed the title Pub build modes debug and release treat shifts diffent if value < 0 Dart2js minified vs non-minified treats shifts differently if value < 0 Sep 20, 2017
@nex3 nex3 added web-dart2js type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Sep 20, 2017
@rakudrama
Copy link
Member

The difference can't be minification - it does not work in a way that could make this difference - all minification does is choose short names.
When I compile a 'main' program containing the above code with dart2js --checked vs dart2js --minify I get identical outputs.

I suspect that you are running in a browser and the debug run is on Dartium and not compiled by dart2js at all, and the release run is compiled with dart2js and run with Chrome.

Please confirm. If this is the case, it is working as intended.

You can force the sign back by replacing a >> 1 with (a >> 1).toSigned(32).

@stephan-gruen
Copy link

So I checked and your are right that this is not a minified vs unminified, but
more a development vs. release issue.

My point is that the behavior of the shift during development and release is different.

Using dart-sdk 1.25.0-dev.16.3 and dart-sdk 2.0.0-dev.2.0 (Results are the same)

Run from WebStorm as Debug in
Dartium 50.0.2661.108
-1 >> 0 = -1

Run a test:

group('shift', () {
   test('zero', () {
   	expect(-1 >> 0, 4294967295);
   });
 });

Test failed:

Expected: <4294967295>
  Actual: <-1>

Pub: Build mode Debug, uploaded to Webserver
Dartium 50.0.2661.108 32-Bit:
-1 >> 0 = -1

Chrome 61.0.3163.10 64-Bit:
-1 >> 0 = 4294967295

Firefox 56.0 32-Bit:
-1 >> 0 = 4294967295

Pub: Build mode Release, uploaded to Webserver
Dartium 50.0.2661.108 32-Bit:
-1 >> 0 = 4294967295

Chrome 61.0.3163.10 64-Bit:
-1 >> 0 = 4294967295

Firefox 56.0 32-Bit:
-1 >> 0 = 4294967295

@vsmenon vsmenon added the area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop. label Jul 20, 2019
@rakudrama
Copy link
Member

I'm closing this issue:
(1) There is no difference between minified and unminified, or between DDC and dart2js
(2) The reference of Dartium is obsolete
(3) There is work underway to better describe the necessary differences between VM and web implementations (@vsmenon )

@stephan-gruen
Copy link

stephan-gruen commented Feb 9, 2021

This is 3 years old and was not fixed? Oh me, oh my...

Server:
"D:\dart-sdk\dart-sdk 2.13.0-12.0.dev\bin\dart.exe" --enable-asserts --pause_isolates_on_start --enable-vm-service:55630 D:\dart-apps\webV\vaderService\bin\server.dart

1 >> 0  = 1
0 >> 0  = 0
-1 >> 0  = -1
-2 >> 0  = -2
1 >> 1  = 0
0 >> 1  = 0
-1 >> 1  = -1
-2 >> 1  = -1
1 << 0  = 1
0 << 0  = 0
-1 << 0  = -1
-2 << 0  = -2
1 << 1  = 2
0 << 1  = 0
-1 << 1  = -2
-2 << 1  = -4

Client:
"D:\dart-sdk\dart-sdk 2.13.0-12.0.dev\bin\pub.bat" global run webdev serve web:53325
"D:\dart-sdk\dart-sdk 2.13.0-12.0.dev\bin\pub.bat" global run webdev build --output=web:build

1 >> 0  = 1
0 >> 0  = 0
-1 >> 0  = 4294967295
-2 >> 0  = 4294967294
1 >> 1  = 0
0 >> 1  = 0
-1 >> 1  = 4294967295
-2 >> 1  = 4294967295
1 << 0  = 1
0 << 0  = 0
-1 << 0  = 4294967295
-2 << 0  = 4294967294
1 << 1  = 2
0 << 1  = 0
-1 << 1  = 4294967294
-2 << 1  = 4294967292
// still not possible
// e.g. in a loop to unpack data
b = b << 1;
if (b < 0) {
  // No more data
}

@vsmenon
Copy link
Member

vsmenon commented Feb 10, 2021

Unfortunately, it's working as intended for the VM and Web to differ on int operations. We're going to better document this ( #42924 ), but the gist is that we need to make a tradeoff between precisely equivalent int semantics on the one hand and performance/code size on the other. We've chosen to go with the latter.

You can see more discussion on why >> behaves as it does on the web here: dart-lang/language#1434

In your example above, you can do b = (b << 1).toSigned(32); to force the semantics you want.

@vsmenon vsmenon closed this as completed Feb 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-web-js Issues related to JavaScript support for Dart Web, including DDC, dart2js, 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

4 participants