Skip to content

Commit

Permalink
Merge pull request scala-js#4677 from sjrd/independent-javalib
Browse files Browse the repository at this point in the history
Make the javalib independent of the Scala library.
  • Loading branch information
sjrd authored Jul 24, 2022
2 parents 8b26ad3 + 93d3997 commit 8bc832f
Show file tree
Hide file tree
Showing 49 changed files with 1,002 additions and 315 deletions.
4 changes: 3 additions & 1 deletion javalib/src/main/scala/java/io/BufferedReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ class BufferedReader(in: Reader, sz: Int) extends Reader {

def this(in: Reader) = this(in, 4096)

private[this] var buf = new Array[Char](sz)
// Workaround 2.11 with no-specialization ; buf should be initialized on the same line
private[this] var buf: Array[Char] = null
buf = new Array[Char](sz)

/** Last valid value in the buffer (exclusive) */
private[this] var end = 0
Expand Down
70 changes: 51 additions & 19 deletions javalib/src/main/scala/java/math/BigDecimal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,13 @@ object BigDecimal {

private final val LongFivePows = newArrayOfPows(28, 5)

private final val LongFivePowsBitLength =
Array.tabulate[Int](LongFivePows.length)(i => bitLength(LongFivePows(i)))
private final val LongFivePowsBitLength = {
val len = LongFivePows.length
val result = new Array[Int](len)
for (i <- 0 until len)
result(i) = bitLength(LongFivePows(i))
result
}

/** An array of longs with powers of ten.
*
Expand All @@ -68,24 +73,37 @@ object BigDecimal {
*/
private[math] final val LongTenPows = newArrayOfPows(19, 10)

private final val LongTenPowsBitLength =
Array.tabulate[Int](LongTenPows.length)(i => bitLength(LongTenPows(i)))
private final val LongTenPowsBitLength = {
val len = LongTenPows.length
val result = new Array[Int](len)
for (i <- 0 until len)
result(i) = bitLength(LongTenPows(i))
result
}

private final val BigIntScaledByZeroLength = 11

/** An array with the first <code>BigInteger</code> scaled by zero.
*
* (<code>[0,0],[1,0],...,[10,0]</code>).
*/
private final val BigIntScaledByZero =
Array.tabulate[BigDecimal](BigIntScaledByZeroLength)(new BigDecimal(_, 0))
private final val BigIntScaledByZero = {
val result = new Array[BigDecimal](BigIntScaledByZeroLength)
for (i <- 0 until BigIntScaledByZeroLength)
result(i) = new BigDecimal(i, 0)
result
}

/** An array with the zero number scaled by the first positive scales.
*
* (<code>0*10^0, 0*10^1, ..., 0*10^10</code>).
*/
private final val ZeroScaledBy =
Array.tabulate[BigDecimal](BigIntScaledByZeroLength)(new BigDecimal(0, _))
private final val ZeroScaledBy = {
val result = new Array[BigDecimal](BigIntScaledByZeroLength)
for (i <- 0 until BigIntScaledByZeroLength)
result(i) = new BigDecimal(0, i)
result
}

/** A string filled with 100 times the character `'0'`.
* It is not a `final` val so that it isn't copied at every call site.
Expand Down Expand Up @@ -205,8 +223,13 @@ object BigDecimal {
else 0
}

private[math] def newArrayOfPows(len: Int, pow: Int): Array[Long] =
Array.iterate(1L, len)(_ * pow)
private[math] def newArrayOfPows(len: Int, pow: Int): Array[Long] = {
val result = new Array[Long](len)
result(0) = 1L
for (i <- 1 until len)
result(i) = result(i - 1) * pow
result
}

/** Return an increment that can be -1,0 or 1, depending on {@code roundingMode}.
*
Expand Down Expand Up @@ -276,11 +299,20 @@ object BigDecimal {
32 - java.lang.Integer.numberOfLeadingZeros(smallValue)
}

@inline
private def charNotEqualTo(c: Char, cs: Char*): Boolean = !cs.contains(c)
private def charNotEqualTo(c: Char, cs: Array[Char]): Boolean = !charEqualTo(c, cs)

@inline
private def charEqualTo(c: Char, cs: Char*): Boolean = cs.contains(c)
private def charEqualTo(c: Char, cs: Array[Char]): Boolean = {
// scalastyle:off return
val len = cs.length
var i = 0
while (i != len) {
if (cs(i) == c)
return true
i += 1
}
false
// scalastyle:on return
}

@inline
private def insertString(s: String, pos: Int, s2: String): String =
Expand Down Expand Up @@ -374,12 +406,12 @@ class BigDecimal() extends Number with Comparable[BigDecimal] {
if (offset <= last && in(offset) == '+') {
index += 1
// Fail if the next character is another sign.
if (index < last && charEqualTo(in(index), '+', '-'))
if (index < last && charEqualTo(in(index), Array('+', '-')))
throw new NumberFormatException("For input string: " + in.toString)
} else {
// check that '-' is not followed by another sign
val isMinus = index <= last && in(index) == '-'
val nextIsSign = index + 1 < last && charEqualTo(in(index + 1), '+', '-')
val nextIsSign = index + 1 < last && charEqualTo(in(index + 1), Array('+', '-'))
if (isMinus && nextIsSign)
throw new NumberFormatException("For input string: " + in.toString)
}
Expand All @@ -388,7 +420,7 @@ class BigDecimal() extends Number with Comparable[BigDecimal] {
var counter = 0
var wasNonZero = false
// Accumulating all digits until a possible decimal point
while (index <= last && charNotEqualTo(in(index), '.', 'e', 'E')) {
while (index <= last && charNotEqualTo(in(index), Array('.', 'e', 'E'))) {
if (!wasNonZero) {
if (in(index) == '0') counter += 1
else wasNonZero = true
Expand All @@ -404,7 +436,7 @@ class BigDecimal() extends Number with Comparable[BigDecimal] {
index += 1
// Accumulating all digits until a possible exponent
val begin = index
while (index <= last && charNotEqualTo(in(index), 'e', 'E')) {
while (index <= last && charNotEqualTo(in(index), Array('e', 'E'))) {
if (!wasNonZero) {
if (in(index) == '0') counter += 1
else wasNonZero = true
Expand All @@ -420,7 +452,7 @@ class BigDecimal() extends Number with Comparable[BigDecimal] {
}

// An exponent was found
if ((index <= last) && charEqualTo(in(index), 'e', 'E')) {
if ((index <= last) && charEqualTo(in(index), Array('e', 'E'))) {
index += 1
// Checking for a possible sign of scale
val indexIsPlus = index <= last && in(index) == '+'
Expand Down
7 changes: 6 additions & 1 deletion javalib/src/main/scala/java/math/BigInteger.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ object BigInteger {
new BigInteger(1, 4), new BigInteger(1, 5), new BigInteger(1, 6),
new BigInteger(1, 7), new BigInteger(1, 8), new BigInteger(1, 9), TEN)

private final val TWO_POWS = Array.tabulate[BigInteger](32)(i => BigInteger.valueOf(1L << i))
private final val TWO_POWS = {
val result = new Array[BigInteger](32)
for (i <- 0 until 32)
result(i) = BigInteger.valueOf(1L << i)
result
}

/** The first non zero digit is either -1 if sign is zero, otherwise it is >= 0.
*
Expand Down
5 changes: 4 additions & 1 deletion javalib/src/main/scala/java/math/Division.scala
Original file line number Diff line number Diff line change
Expand Up @@ -884,11 +884,14 @@ private[math] object Division {
for (i <- 0 until modulusLen) {
var innnerCarry: Int = 0 // unsigned
val m = Multiplication.unsignedMultAddAdd(res(i), n2, 0, 0).toInt
for (j <- 0 until modulusLen) {
// Work around Scala 2.11 limitation with the IR cleaner ; should be for (j <- 0 until modulusLen)
var j = 0
while (j < modulusLen) {
val nextInnnerCarry =
unsignedMultAddAdd(m, modulusDigits(j), res(i + j), innnerCarry)
res(i + j) = nextInnnerCarry.toInt
innnerCarry = (nextInnnerCarry >> 32).toInt
j += 1
}
val nextOuterCarry =
(outerCarry & UINT_MAX) + (res(i + modulusLen) & UINT_MAX) + (innnerCarry & UINT_MAX)
Expand Down
19 changes: 15 additions & 4 deletions javalib/src/main/scala/java/math/Multiplication.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,13 @@ private[math] object Multiplication {

for (i <- 0 until aLen) {
carry = 0
for (j <- i + 1 until aLen) {
// Work around Scala 2.11 limitation with the IR cleaner ; should be for (j <- i + 1 until aLen)
var j = i + 1
while (j < aLen) {
val t = unsignedMultAddAdd(a(i), a(j), res(i + j), carry)
res(i + j) = t.toInt
carry = (t >>> 32).toInt
j += 1
}
res(i + aLen) = carry
}
Expand Down Expand Up @@ -439,16 +442,24 @@ private[math] object Multiplication {
for (i <- 0 until aLen) {
var carry = 0
val aI = a(i)
for (j <- 0 until bLen) {
// Work around Scala 2.11 limitation with the IR cleaner ; should be for (j <- 0 until bLen)
var j = 0
while (j < bLen) {
val added = unsignedMultAddAdd(aI, b(j), t(i + j), carry)
t(i + j) = added.toInt
carry = (added >>> 32).toInt
j += 1
}
t(i + bLen) = carry
}
}
}

private def newArrayOfPows(len: Int, pow: Int): Array[Int] =
Array.iterate(1, len)(_ * pow)
private def newArrayOfPows(len: Int, pow: Int): Array[Int] = {
val result = new Array[Int](len)
result(0) = 1
for (i <- 1 until len)
result(i) = result(i - 1) * pow
result
}
}
9 changes: 7 additions & 2 deletions javalib/src/main/scala/java/math/Primality.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,13 @@ private[math] object Primality {
(18, 13), (31, 23), (54, 43), (97, 75))

/** All {@code BigInteger} prime numbers with bit length lesser than 8 bits. */
private val BiPrimes =
Array.tabulate[BigInteger](Primes.length)(i => BigInteger.valueOf(Primes(i)))
private val BiPrimes = {
val len = Primes.length
val result = new Array[BigInteger](len)
for (i <- 0 until len)
result(i) = BigInteger.valueOf(Primes(i))
result
}

/** A random number is generated until a probable prime number is found.
*
Expand Down
9 changes: 5 additions & 4 deletions javalib/src/main/scala/java/net/URI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import scala.annotation.tailrec

import java.nio._
import java.nio.charset.{CodingErrorAction, StandardCharsets}
import java.util.JSUtils._

final class URI(origStr: String) extends Serializable with Comparable[URI] {

Expand All @@ -35,10 +36,10 @@ final class URI(origStr: String) extends Serializable with Comparable[URI] {
if (_fld == null)
throw new URISyntaxException(origStr, "Malformed URI")

private val _isAbsolute = _fld(AbsScheme).isDefined
private val _isOpaque = _fld(AbsOpaquePart).isDefined
private val _isAbsolute = undefOrIsDefined(_fld(AbsScheme))
private val _isOpaque = undefOrIsDefined(_fld(AbsOpaquePart))

@inline private def fld(idx: Int): String = _fld(idx).orNull
@inline private def fld(idx: Int): String = undefOrGetOrNull(_fld(idx))

@inline private def fld(absIdx: Int, relIdx: Int): String =
if (_isAbsolute) fld(absIdx) else fld(relIdx)
Expand Down Expand Up @@ -187,7 +188,7 @@ final class URI(origStr: String) extends Serializable with Comparable[URI] {
def getUserInfo(): String = decodeComponent(_userInfo)

override def hashCode(): Int = {
import scala.util.hashing.MurmurHash3._
import java.util.internal.MurmurHash3._
import URI.normalizeEscapes

def normalizeEscapesHash(str: String): Int =
Expand Down
12 changes: 6 additions & 6 deletions javalib/src/main/scala/java/nio/ByteBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ object ByteBuffer {

// Extended API

def wrap(array: ArrayBuffer): ByteBuffer =
TypedArrayByteBuffer.wrap(array)
def wrapArrayBuffer(array: ArrayBuffer): ByteBuffer =
TypedArrayByteBuffer.wrapArrayBuffer(array)

def wrap(array: ArrayBuffer, byteOffset: Int, length: Int): ByteBuffer =
TypedArrayByteBuffer.wrap(array, byteOffset, length)
def wrapArrayBuffer(array: ArrayBuffer, byteOffset: Int, length: Int): ByteBuffer =
TypedArrayByteBuffer.wrapArrayBuffer(array, byteOffset, length)

def wrap(array: Int8Array): ByteBuffer =
TypedArrayByteBuffer.wrap(array)
def wrapInt8Array(array: Int8Array): ByteBuffer =
TypedArrayByteBuffer.wrapInt8Array(array)
}

abstract class ByteBuffer private[nio] (
Expand Down
4 changes: 2 additions & 2 deletions javalib/src/main/scala/java/nio/CharBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ object CharBuffer {

// Extended API

def wrap(array: Uint16Array): CharBuffer =
TypedArrayCharBuffer.wrap(array)
def wrapUint16Array(array: Uint16Array): CharBuffer =
TypedArrayCharBuffer.wrapUint16Array(array)
}

abstract class CharBuffer private[nio] (
Expand Down
46 changes: 46 additions & 0 deletions javalib/src/main/scala/java/nio/DataViewExt.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Scala.js (https://www.scala-js.org/)
*
* Copyright EPFL.
*
* Licensed under Apache License 2.0
* (https://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package java.nio

import scala.scalajs.js.typedarray.DataView

/** Copy of features in `scala.scalajs.js.typedarray.DateViewExt`.
*
* Defined as functions instead of extension methods, because the AnyVal over
* a JS type generates an `equals` method that references `BoxesRunTime`.
*/
private[nio] object DataViewExt {
/** Reads a 2's complement signed 64-bit integers from the data view.
* @param index Starting index
* @param littleEndian Whether the number is stored in little endian
*/
@inline
def dataViewGetInt64(dataView: DataView, index: Int, littleEndian: Boolean): Long = {
val high = dataView.getInt32(index + (if (littleEndian) 4 else 0), littleEndian)
val low = dataView.getInt32(index + (if (littleEndian) 0 else 4), littleEndian)
(high.toLong << 32) | (low.toLong & 0xffffffffL)
}

/** Writes a 2's complement signed 64-bit integers to the data view.
* @param index Starting index
* @param value Value to be written
* @param littleEndian Whether to store the number in little endian
*/
@inline
def dataViewSetInt64(dataView: DataView, index: Int, value: Long, littleEndian: Boolean): Unit = {
val high = (value >>> 32).toInt
val low = value.toInt
dataView.setInt32(index + (if (littleEndian) 4 else 0), high, littleEndian)
dataView.setInt32(index + (if (littleEndian) 0 else 4), low, littleEndian)
}
}
7 changes: 4 additions & 3 deletions javalib/src/main/scala/java/nio/DataViewLongBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@

package java.nio

import java.nio.DataViewExt._

import scala.scalajs.js.typedarray._
import DataViewExt._

private[nio] final class DataViewLongBuffer private (
override private[nio] val _dataView: DataView,
Expand Down Expand Up @@ -86,11 +87,11 @@ private[nio] final class DataViewLongBuffer private (

@inline
private[nio] def load(index: Int): Long =
_dataView.getInt64(8 * index, !isBigEndian)
dataViewGetInt64(_dataView, 8 * index, !isBigEndian)

@inline
private[nio] def store(index: Int, elem: Long): Unit =
_dataView.setInt64(8 * index, elem, !isBigEndian)
dataViewSetInt64(_dataView, 8 * index, elem, !isBigEndian)

@inline
override private[nio] def load(startIndex: Int,
Expand Down
4 changes: 2 additions & 2 deletions javalib/src/main/scala/java/nio/DoubleBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ object DoubleBuffer {

// Extended API

def wrap(array: Float64Array): DoubleBuffer =
TypedArrayDoubleBuffer.wrap(array)
def wrapFloat64Array(array: Float64Array): DoubleBuffer =
TypedArrayDoubleBuffer.wrapFloat64Array(array)
}

abstract class DoubleBuffer private[nio] (
Expand Down
4 changes: 2 additions & 2 deletions javalib/src/main/scala/java/nio/FloatBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ object FloatBuffer {

// Extended API

def wrap(array: Float32Array): FloatBuffer =
TypedArrayFloatBuffer.wrap(array)
def wrapFloat32Array(array: Float32Array): FloatBuffer =
TypedArrayFloatBuffer.wrapFloat32Array(array)
}

abstract class FloatBuffer private[nio] (
Expand Down
Loading

0 comments on commit 8bc832f

Please sign in to comment.