Thanks to visit codestin.com
Credit goes to github.com

Skip to content

update of Scanner to handle longs with up to 53 bits only #186

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

Merged
merged 6 commits into from
Dec 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip
Binary file not shown.
57 changes: 57 additions & 0 deletions sources/net.sf.j2s.core/dist/swingjs/differences.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ever be shadowed or overridden by subclasses. For example, we see in java.lang.T
----------------------------------


updated 12/6/2020 -- note about restrictions on long, including BitSet and Scanner
updated 3/21/2020 -- adds note about HashMap, Hashtable, and HashSet iterator ordering
updated 3/20/2020 -- adds note about interning, new String("xxx"), and "xxx"
updated 2/26/2020 -- adds Graphics.setClip issue
Expand Down Expand Up @@ -480,6 +481,8 @@ MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS

See below for a full discussion.

Restrictions on long
Restriction on BitSet and Scanner
HashMap, Hashtable, and HashSet iterator ordering
interning, new String("xxx") vs "xxx"
Names with "$" and "_"
Expand Down Expand Up @@ -586,6 +589,60 @@ changed to JSToolkit.isDispatchThread()
MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
=====================================================================

restrictions on long
--------------------

Java's 64-bit long type is not supported in JavaScript. There is no Int64Array in JavaScript,
and 0x20000000000000 + 1 evaluates to 0x20000000000000, not 0x20000000000001.
(Likewise, -0x20000000000000 - 1 is left unchanged.)

The largest "integer" value in JavaScript is 9007199254740991 (9.007199254740991E13, or 0x1FFFFFFFFFFFFFF).
Effectively, you get to use only 53 bits of the long, not 64. Trying to set a long larger than
0x1FFFFFFFFFFFFFF or smaller than -0x1FFFFFFFFFFFFFF will result in a NumberFormatException.

The transpiler handles conversion to long the same as Java for all cases other than from double.

For small double values, there is no problem, and, in fact, this is a known trick used to round
doubles and floats toward zero:

double d;
d = (long) 3.8;
assert(d == 3);
d = (long) -3.8;
assert(d == -3);

SwingJS will evaluate (long) d as 0 for d > 9007199254740991
or d < -9007199254740991, same as Java returns for Double.NaN.
So, in Java we have:

assert(((long) Double.NaN) == 0);
assert(((int) Double.NaN) == 0);
assert(((long) Float.NaN) == 0);
assert(((int) Float.NaN) == 0);

and also, in JavaScript only, we also have:

double d = 0x2000000000000L;
assert(((long) d) == 0);


restrictions on BitSet and Scanner
----------------------------------

Because of the issue of long being only 53 bits, any time a method returns a long value, considerations must
be made as to whether this will work in JavaScript. In particular, BitSet and Scanner have issues.

In SwingJS, java.util.BitSet has been implemented as a 32-bit integer-based bitset. This was no problem in
Java 6, but starting with Java 7, a method was added to BitSet that allows for the extraction of the
underlying long[] word data. This is not work in JavaScript. Instead, SwingJS java.util.Bitset.toLongArray() will deliver
32-bit int[] data.

SwingJS Scanner has hasNextLong() and nextLong(), and although it will scan through long numbers,
Scanner will choke on long numbers greater than the JavaScript 53-bit limit. hasNextLong() will
return false, and nextLong() will throw an InputMismatchException triggered by the NumberFormatException
thrown by Long.parseLong().


HashMap, Hashtable, and HashSet iterator ordering
-------------------------------------------------

Expand Down
Binary file modified sources/net.sf.j2s.core/dist/swingjs/net.sf.j2s.core.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion sources/net.sf.j2s.core/dist/swingjs/timestamp
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20201205151557
20201206115202
Binary file modified sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/SwingJS-site.zip
Binary file not shown.
57 changes: 57 additions & 0 deletions sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/differences.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ever be shadowed or overridden by subclasses. For example, we see in java.lang.T
----------------------------------


updated 12/6/2020 -- note about restrictions on long, including BitSet and Scanner
updated 3/21/2020 -- adds note about HashMap, Hashtable, and HashSet iterator ordering
updated 3/20/2020 -- adds note about interning, new String("xxx"), and "xxx"
updated 2/26/2020 -- adds Graphics.setClip issue
Expand Down Expand Up @@ -480,6 +481,8 @@ MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS

See below for a full discussion.

Restrictions on long
Restriction on BitSet and Scanner
HashMap, Hashtable, and HashSet iterator ordering
interning, new String("xxx") vs "xxx"
Names with "$" and "_"
Expand Down Expand Up @@ -586,6 +589,60 @@ changed to JSToolkit.isDispatchThread()
MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
=====================================================================

restrictions on long
--------------------

Java's 64-bit long type is not supported in JavaScript. There is no Int64Array in JavaScript,
and 0x20000000000000 + 1 evaluates to 0x20000000000000, not 0x20000000000001.
(Likewise, -0x20000000000000 - 1 is left unchanged.)

The largest "integer" value in JavaScript is 9007199254740991 (9.007199254740991E13, or 0x1FFFFFFFFFFFFFF).
Effectively, you get to use only 53 bits of the long, not 64. Trying to set a long larger than
0x1FFFFFFFFFFFFFF or smaller than -0x1FFFFFFFFFFFFFF will result in a NumberFormatException.

The transpiler handles conversion to long the same as Java for all cases other than from double.

For small double values, there is no problem, and, in fact, this is a known trick used to round
doubles and floats toward zero:

double d;
d = (long) 3.8;
assert(d == 3);
d = (long) -3.8;
assert(d == -3);

SwingJS will evaluate (long) d as 0 for d > 9007199254740991
or d < -9007199254740991, same as Java returns for Double.NaN.
So, in Java we have:

assert(((long) Double.NaN) == 0);
assert(((int) Double.NaN) == 0);
assert(((long) Float.NaN) == 0);
assert(((int) Float.NaN) == 0);

and also, in JavaScript only, we also have:

double d = 0x2000000000000L;
assert(((long) d) == 0);


restrictions on BitSet and Scanner
----------------------------------

Because of the issue of long being only 53 bits, any time a method returns a long value, considerations must
be made as to whether this will work in JavaScript. In particular, BitSet and Scanner have issues.

In SwingJS, java.util.BitSet has been implemented as a 32-bit integer-based bitset. This was no problem in
Java 6, but starting with Java 7, a method was added to BitSet that allows for the extraction of the
underlying long[] word data. This is not work in JavaScript. Instead, SwingJS java.util.Bitset.toLongArray() will deliver
32-bit int[] data.

SwingJS Scanner has hasNextLong() and nextLong(), and although it will scan through long numbers,
Scanner will choke on long numbers greater than the JavaScript 53-bit limit. hasNextLong() will
return false, and nextLong() will throw an InputMismatchException triggered by the NumberFormatException
thrown by Long.parseLong().


HashMap, Hashtable, and HashSet iterator ordering
-------------------------------------------------

Expand Down
Binary file modified sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/net.sf.j2s.core.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion sources/net.sf.j2s.core/dist/swingjs/ver/3.2.9/timestamp
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20201205151557
20201206115202
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class CorePlugin extends Plugin {
// if you change the x.x.x number, be sure to also indicate that in
// j2sApplet.js and also (Bob only) update.bat, update-clean.bat


// BH 2020.12.06 -- 3.2.9-v1r fix for (long) double using |0
// BH 2020.11.20 -- 3.2.9-v1q fix for new ImmutableCollections.ListN<>(E...) should use Object[]
// BH 2020.08.03 -- 3.2.9-v1p fix for boxing boolean should be Boolean.valueOf$, not new Boolean
// BH 2020.08.01 -- 3.2.9-v1o fix for lambda expressions too static
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@

// TODO: superclass inheritance for JAXB XmlAccessorType

//BH 2020.12.06 -- 3.2.9-v1r fix for (long) double using |0
//BH 2020.11.20 -- 3.2.9-v1q fix for new ImmutableCollections.ListN<>(E...) should use Object[]
//BH 2020.08.03 -- 3.2.9-v1p fix for boxing boolean should be Boolean.valueOf$, not new Boolean
//BH 2020.08.01 -- 3.2.9-v1o fix for lambda expressions too static
Expand Down Expand Up @@ -4589,7 +4590,7 @@ private boolean addPrimitiveTypedExpression(Expression left, IVariableBinding as
// a = ($b$[0] = a | right, $b$[0])

String classIntArray = null;
String more = null;
String more = null, less = null;

String prefix = (isAssignment ? "=" : "");
boolean fromChar = ("char".equals(rightName));
Expand All @@ -4611,7 +4612,8 @@ private boolean addPrimitiveTypedExpression(Expression left, IVariableBinding as
break;
case "long":
if (isDiv || !fromIntType) {
more = "|0)";
less = "Clazz.toLong(";
more = ")";
addParens = true;
} else {
left = null;
Expand Down Expand Up @@ -4662,6 +4664,8 @@ private boolean addPrimitiveTypedExpression(Expression left, IVariableBinding as
buffer.append("(");
buffer.append(classIntArray).append(" = ");
temp_processingArrayIndex = true;
} else if (less != null) {
buffer.append(less);
} else if (more == "|0)") {
buffer.append("(");
}
Expand Down
Binary file modified sources/net.sf.j2s.java.core/dist/SwingJS-site.zip
Binary file not shown.
57 changes: 57 additions & 0 deletions sources/net.sf.j2s.java.core/dist/differences.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ever be shadowed or overridden by subclasses. For example, we see in java.lang.T
----------------------------------


updated 12/6/2020 -- note about restrictions on long, including BitSet and Scanner
updated 3/21/2020 -- adds note about HashMap, Hashtable, and HashSet iterator ordering
updated 3/20/2020 -- adds note about interning, new String("xxx"), and "xxx"
updated 2/26/2020 -- adds Graphics.setClip issue
Expand Down Expand Up @@ -480,6 +481,8 @@ MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS

See below for a full discussion.

Restrictions on long
Restriction on BitSet and Scanner
HashMap, Hashtable, and HashSet iterator ordering
interning, new String("xxx") vs "xxx"
Names with "$" and "_"
Expand Down Expand Up @@ -586,6 +589,60 @@ changed to JSToolkit.isDispatchThread()
MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
=====================================================================

restrictions on long
--------------------

Java's 64-bit long type is not supported in JavaScript. There is no Int64Array in JavaScript,
and 0x20000000000000 + 1 evaluates to 0x20000000000000, not 0x20000000000001.
(Likewise, -0x20000000000000 - 1 is left unchanged.)

The largest "integer" value in JavaScript is 9007199254740991 (9.007199254740991E13, or 0x1FFFFFFFFFFFFFF).
Effectively, you get to use only 53 bits of the long, not 64. Trying to set a long larger than
0x1FFFFFFFFFFFFFF or smaller than -0x1FFFFFFFFFFFFFF will result in a NumberFormatException.

The transpiler handles conversion to long the same as Java for all cases other than from double.

For small double values, there is no problem, and, in fact, this is a known trick used to round
doubles and floats toward zero:

double d;
d = (long) 3.8;
assert(d == 3);
d = (long) -3.8;
assert(d == -3);

SwingJS will evaluate (long) d as 0 for d > 9007199254740991
or d < -9007199254740991, same as Java returns for Double.NaN.
So, in Java we have:

assert(((long) Double.NaN) == 0);
assert(((int) Double.NaN) == 0);
assert(((long) Float.NaN) == 0);
assert(((int) Float.NaN) == 0);

and also, in JavaScript only, we also have:

double d = 0x2000000000000L;
assert(((long) d) == 0);


restrictions on BitSet and Scanner
----------------------------------

Because of the issue of long being only 53 bits, any time a method returns a long value, considerations must
be made as to whether this will work in JavaScript. In particular, BitSet and Scanner have issues.

In SwingJS, java.util.BitSet has been implemented as a 32-bit integer-based bitset. This was no problem in
Java 6, but starting with Java 7, a method was added to BitSet that allows for the extraction of the
underlying long[] word data. This is not work in JavaScript. Instead, SwingJS java.util.Bitset.toLongArray() will deliver
32-bit int[] data.

SwingJS Scanner has hasNextLong() and nextLong(), and although it will scan through long numbers,
Scanner will choke on long numbers greater than the JavaScript 53-bit limit. hasNextLong() will
return false, and nextLong() will throw an InputMismatchException triggered by the NumberFormatException
thrown by Long.parseLong().


HashMap, Hashtable, and HashSet iterator ordering
-------------------------------------------------

Expand Down
57 changes: 57 additions & 0 deletions sources/net.sf.j2s.java.core/doc/Differences.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ever be shadowed or overridden by subclasses. For example, we see in java.lang.T
----------------------------------


updated 12/6/2020 -- note about restrictions on long, including BitSet and Scanner
updated 3/21/2020 -- adds note about HashMap, Hashtable, and HashSet iterator ordering
updated 3/20/2020 -- adds note about interning, new String("xxx"), and "xxx"
updated 2/26/2020 -- adds Graphics.setClip issue
Expand Down Expand Up @@ -480,6 +481,8 @@ MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS

See below for a full discussion.

Restrictions on long
Restriction on BitSet and Scanner
HashMap, Hashtable, and HashSet iterator ordering
interning, new String("xxx") vs "xxx"
Names with "$" and "_"
Expand Down Expand Up @@ -586,6 +589,60 @@ changed to JSToolkit.isDispatchThread()
MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
=====================================================================

restrictions on long
--------------------

Java's 64-bit long type is not supported in JavaScript. There is no Int64Array in JavaScript,
and 0x20000000000000 + 1 evaluates to 0x20000000000000, not 0x20000000000001.
(Likewise, -0x20000000000000 - 1 is left unchanged.)

The largest "integer" value in JavaScript is 9007199254740991 (9.007199254740991E13, or 0x1FFFFFFFFFFFFFF).
Effectively, you get to use only 53 bits of the long, not 64. Trying to set a long larger than
0x1FFFFFFFFFFFFFF or smaller than -0x1FFFFFFFFFFFFFF will result in a NumberFormatException.

The transpiler handles conversion to long the same as Java for all cases other than from double.

For small double values, there is no problem, and, in fact, this is a known trick used to round
doubles and floats toward zero:

double d;
d = (long) 3.8;
assert(d == 3);
d = (long) -3.8;
assert(d == -3);

SwingJS will evaluate (long) d as 0 for d > 9007199254740991
or d < -9007199254740991, same as Java returns for Double.NaN.
So, in Java we have:

assert(((long) Double.NaN) == 0);
assert(((int) Double.NaN) == 0);
assert(((long) Float.NaN) == 0);
assert(((int) Float.NaN) == 0);

and also, in JavaScript only, we also have:

double d = 0x2000000000000L;
assert(((long) d) == 0);


restrictions on BitSet and Scanner
----------------------------------

Because of the issue of long being only 53 bits, any time a method returns a long value, considerations must
be made as to whether this will work in JavaScript. In particular, BitSet and Scanner have issues.

In SwingJS, java.util.BitSet has been implemented as a 32-bit integer-based bitset. This was no problem in
Java 6, but starting with Java 7, a method was added to BitSet that allows for the extraction of the
underlying long[] word data. This is not work in JavaScript. Instead, SwingJS java.util.Bitset.toLongArray() will deliver
32-bit int[] data.

SwingJS Scanner has hasNextLong() and nextLong(), and although it will scan through long numbers,
Scanner will choke on long numbers greater than the JavaScript 53-bit limit. hasNextLong() will
return false, and nextLong() will throw an InputMismatchException triggered by the NumberFormatException
thrown by Long.parseLong().


HashMap, Hashtable, and HashSet iterator ordering
-------------------------------------------------

Expand Down
3 changes: 2 additions & 1 deletion sources/net.sf.j2s.java.core/src/java/util/BitSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;

import javajs.api.JSONEncodable;
import javajs.util.SB;
import swingjs.JSUtil;


/**
Expand Down Expand Up @@ -1028,6 +1028,7 @@ public BitSet get(int fromIndex, int toIndex) {
* @return
*/
public long[] toLongArray() {
JSUtil.notImplemented("BitSet.toLongArray returns a 32-bit array");
long[] a = new long[words.length];
for (int i = a.length; --i >= 0;)
a[i] = words[i];
Expand Down
Loading