Closed DartBot closed 9 years ago
cc @floitschG.
See Issue #2725 JavaScript supports only 32 bit values for bitwise and shift operations. There will always be some discrepancy between the VM and JavaScript so long as JavaScript native numbers are used. Two possible policies: (1) all results are in the range [-2^31, 2^31) (2) all results are in the range [0, 2^32)
I believe dart2js is consciously implementing (2) because that makes crypto libraries work. frog mostly implements (1).
What we need is a clear description of how (and why) dart2js is dealing with these issues so we can quickly triage this endless list of edge cases as examples of the underlying problem.
Stephen is right that we always return something in the range [0, 2^32], but the behavior described in this issue is a bug. The idea was to transform "x bitOp y" into (in Dart semantics) (x bitOp y) & 0x32bit I wrongly assumed that (x >> y) & 32bit would be equivalent to JS "x >>> y". I'm going to fix this on Monday.
Added Accepted label.
Was this fixed in r7899?
This issue was originally filed by rice@google.com
Consider the following code:
void main() { int negativeOne = -1; if (1 + 1 != 2) negativeOne = 999; // defeat constant-folding in the compiler print("${negativeOne >> 8}"); }
In the VM, it prints -1, while dart2js prints 16777215. dart2js emits this following code:
$.main = function() { var negativeOne = -1; $.print('' + $.stringToString($.shr(negativeOne, 8))); };
$.shr = function(a, b) { if ($.checkNumbers(a, b) === true) { if ($.ltB(b, 0)) { throw $.captureStackTrace($.IllegalArgumentException$1(b)); } if ($.gtB(b, 31)) { return 0; } return a >>> b; } return a.operator$shr$1(b); };
The upshot is that dart2js compiles the dart expression '-1 >> 8' to the js expression '-1 >>> 8', which does not match the VM behavior.
This makes it difficult to implement bit operations reliably in dart2js, which is gating other library work.