Skip to content

Commit 7b523c9

Browse files
committed
Announcing Scala.js 1.9.0.
1 parent 7e86862 commit 7b523c9

File tree

6 files changed

+164
-34
lines changed

6 files changed

+164
-34
lines changed

_config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ colors: #in hex code if not noted else
6464

6565
### VERSIONS ###
6666
versions:
67-
scalaJS: 1.8.0
67+
scalaJS: 1.9.0
6868
scalaJSBinary: 1
6969
scalaJS06x: 0.6.33
7070
scalaJS06xBinary: 0.6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
layout: post
3+
title: Announcing Scala.js 1.9.0
4+
category: news
5+
tags: [releases]
6+
permalink: /news/2022/02/14/announcing-scalajs-1.9.0/
7+
---
8+
9+
10+
We are excited to announce the release of Scala.js 1.9.0!
11+
12+
Starting with this release, Scala.js will use its strict-floats mode by default (what previously required `withStrictFloats(true)`).
13+
`Float` values are now always guaranteed to fit in 32-bit floating point data, and all `Float` operations strictly follow IEEE-754 float32 semantics.
14+
15+
This release also brings support for `java.util.BitSet`, and fixes some bugs.
16+
It also updates the version of the Scala standard library to 2.13.8 for 2.13.x versions.
17+
18+
Read on for more details.
19+
20+
<!--more-->
21+
22+
## Getting started
23+
24+
If you are new to Scala.js, head over to [the tutorial]({{ BASE_PATH }}/tutorial/).
25+
26+
If you need help with anything related to Scala.js, you may find our community [in `#scala-js` on Discord](https://discord.com/invite/scala) and [on Stack Overflow](https://stackoverflow.com/questions/tagged/scala.js).
27+
28+
Bug reports can be filed [on GitHub](https://github.com/scala-js/scala-js/issues).
29+
30+
## Release notes
31+
32+
If upgrading from Scala.js 0.6.x, make sure to read [the release notes of Scala.js 1.0.0]({{ BASE_PATH }}/news/2020/02/25/announcing-scalajs-1.0.0/) first, as they contain a host of important information, including breaking changes.
33+
34+
This is a **minor** release:
35+
36+
* It is backward binary compatible with all earlier versions in the 1.x series: libraries compiled with 1.0.x through 1.8.x can be used with 1.9.0 without change.
37+
* Despite being a minor release, 1.9.0 is forward binary compatible with 1.8.x. It is *not* forward binary compatible with 1.7.x. Libraries compiled with 1.9.0 can be used with 1.8.x but not with 1.7.x or earlier.
38+
* It is *not* entirely backward source compatible: it is not guaranteed that a codebase will compile *as is* when upgrading from 1.8.x (in particular in the presence of `-Xfatal-warnings`).
39+
40+
As a reminder, libraries compiled with 0.6.x cannot be used with Scala.js 1.x; they must be republished with 1.x first.
41+
42+
## Strict floats by default
43+
44+
### Background
45+
46+
Until 1.8.0, Scala.js used non-strict floats by default.
47+
This meant that `Float` values and their operations were allowed to behave like `Double`s; either always, sometimes or never, in unpredictable ways.
48+
This was done in the name of run-time performance, because correctly implementing 32-bit float operations requires the built-in function [`Math.fround`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround).
49+
It was considered acceptable because there are few use cases for demanding the reduced precision of `Float`s, and even the JDK did not mandate strict floating point operations by default.
50+
51+
It was always possible to require the Scala.js linker to use strict float semantics using the following setting:
52+
53+
{% highlight scala %}
54+
scalaJSLinkerConfig ~= { _.withSemantics(_.withStrictFloats(true)) }
55+
{% endhighlight scala %}
56+
57+
### What changes
58+
59+
Starting with 1.9.0, Scala.js uses strict float semantics by default.
60+
The rationale for this change is that several conditions have changed since Scala.js was first designed:
61+
62+
* We emit ECMAScript 2015 by default, which requires that `Math.fround` be available
63+
* Even when targeting ES 5.1, `Math.fround` has been widely available in browsers and other JS engines for years
64+
* [Java 17 restored strict floating point operations everywhere](https://openjdk.java.net/jeps/306)
65+
66+
Using strict floats means that `Float` values will always be representable with 32 bits, and that `Float` operations will always follow the IEEE-754 specification for the `float32` format.
67+
This should not have any impact except in the following case:
68+
69+
* `x.isInstanceOf[Float]` used to return `true` when `x` was any `number`. It will now return `false` if it cannot be represented with a 32-bit float.
70+
71+
This change of semantics can in theory break some code, although we do not expect that to happen on any non-contrived example.
72+
73+
Since using strict float semantics is a link-time decision, it applies to the whole program.
74+
Therefore, the changes are also applied to the code in libraries that you may use.
75+
76+
### Performance impact
77+
78+
The switch to strict floats may have a slight performance impact on the `isInstanceOf[Float]` operation, although benchmarks suggest that it is negligible.
79+
80+
There *will* be a performance impact if you are targeting a JS engine that does *not* support `Math.fround` (such as Internet Explorer), which implies emitting ES 5.1 code.
81+
On such engines, Scala.js uses its own version of `fround` in user land (a so-called *polyfill*).
82+
We have optimized our `fround` polyfill to the greatest extent possible, but benchmarks still suggest that `Float`-intensive applications can experience up to a 4x performance hit.
83+
84+
### Reverting to non-strict float semantics
85+
86+
If you really want to, you can switch back to non-strict float semantics with the following linker setting:
87+
88+
{% highlight scala %}
89+
scalaJSLinkerConfig ~= { _.withSemantics(_.withStrictFloats(true)) }
90+
{% endhighlight scala %}
91+
92+
This is however *deprecated*, and will eventually *cease to have any effect* in a later major or minor version of Scala.js.
93+
94+
## Miscellaneous
95+
96+
### New JDK APIs
97+
98+
The following class was added (thanks to [@er1c](https://github.com/er1c)):
99+
100+
* `java.util.BitSet`
101+
102+
The following methods were added (thanks to [@armanbilge](https://github.com/armanbilge)):
103+
104+
* `java.lang.Byte.toUnsignedInt`
105+
* `java.lang.Byte.toUnsignedLong`
106+
* `java.lang.Short.toUnsignedInt`
107+
* `java.lang.Short.toUnsignedLong`
108+
109+
### New ECMAScript APIs
110+
111+
The following methods of `js.BigInt` were added (thanks to [@catap](https://github.com/catap)):
112+
113+
* `toString(radix: Int)`
114+
* the `/` operator
115+
116+
### Upgrade to GCC v20220202
117+
118+
We upgraded to the Google Closure Compiler v20220202.
119+
120+
## Bug fixes
121+
122+
Among others, the following bugs have been fixed in 1.9.0:
123+
124+
* [#4616](https://github.com/scala-js/scala-js/issues/4616) Calling `getClass` with `SmallestModules` module split style causes reference error
125+
* [#4621](https://github.com/scala-js/scala-js/issues/4621) The side effects of JS binary (and unary) operators can be lost
126+
* [#4627](https://github.com/scala-js/scala-js/issues/4627) `ArrayBuilder.length` and `.knownSize` always return 0.
127+
128+
You can find the full list [on GitHub](https://github.com/scala-js/scala-js/issues?q=is%3Aissue+milestone%3Av1.9.0+is%3Aclosed).

doc/all-api.md

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ title: All previous versions of the Scala.js API
55

66
## All previous versions of the API
77

8+
### Scala.js 1.9.0
9+
* [1.9.0 scalajs-library]({{ site.production_url }}/api/scalajs-library/1.9.0/scala/scalajs/js/index.html)
10+
* [1.9.0 scalajs-test-interface]({{ site.production_url }}/api/scalajs-test-interface/1.9.0/)
11+
* [1.9.0 scalajs-ir]({{ site.production_url }}/api/scalajs-ir/1.9.0/org/scalajs/ir/index.html)
12+
* [1.9.0 scalajs-linker-interface]({{ site.production_url }}/api/scalajs-linker-interface/1.9.0/org/scalajs/linker/interface/index.html) ([Scala.js version]({{ site.production_url }}/api/scalajs-linker-interface-js/1.9.0/org/scalajs/linker/interface/index.html))
13+
* [1.9.0 scalajs-linker]({{ site.production_url }}/api/scalajs-linker/1.9.0/org/scalajs/linker/index.html) ([Scala.js version]({{ site.production_url }}/api/scalajs-linker-js/1.9.0/org/scalajs/linker/index.html))
14+
* [1.9.0 scalajs-test-adapter]({{ site.production_url }}/api/scalajs-sbt-test-adapter/1.9.0/org/scalajs/testing/adapter/index.html)
15+
* [1.9.0 sbt-scalajs]({{ site.production_url }}/api/sbt-scalajs/1.9.0/#org.scalajs.sbtplugin.package)
16+
817
### Scala.js 1.8.0
918
* [1.8.0 scalajs-library]({{ site.production_url }}/api/scalajs-library/1.8.0/scala/scalajs/js/index.html)
1019
* [1.8.0 scalajs-test-interface]({{ site.production_url }}/api/scalajs-test-interface/1.8.0/)

doc/internals/version-history.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ title: Version history
55

66
## Version history of Scala.js
77

8+
- [1.9.0](/news/2022/02/14/announcing-scalajs-1.9.0/)
89
- [1.8.0](/news/2021/12/10/announcing-scalajs-1.8.0/)
910
- [1.7.1](/news/2021/10/07/announcing-scalajs-1.7.1/)
1011
- [1.7.0](/news/2021/08/04/announcing-scalajs-1.7.0/)

doc/semantics.md

+24-32
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,7 @@ However, a few differences exist, which we mention here.
1010

1111
## Primitive data types
1212

13-
All nine primitive data types of Scala, i.e., `Boolean`, `Char`, `Byte`, `Short`, `Int`, `Long`, `Float`, `Double` and `Unit`, work exactly as on the JVM, with the following four exceptions.
14-
15-
### Floats can behave as Doubles by default
16-
17-
Scala.js underspecifies the behavior of `Float`s by default.
18-
Any `Float` value can be stored as a `Double` instead, and any operation on
19-
`Float`s can be computed with double precision.
20-
The choice of whether or not to behave as such, when and where, is left to the
21-
implementation.
22-
23-
If exact single precision operations are important to your application, you can
24-
enable strict-floats semantics in Scala.js, with the following sbt setting:
25-
26-
{% highlight scala %}
27-
scalaJSLinkerConfig ~= { _.withSemantics(_.withStrictFloats(true)) }
28-
{% endhighlight %}
29-
30-
Note that this can have a major impact on performance of your application on
31-
JS interpreters that do not support
32-
[the `Math.fround` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround).
13+
All nine primitive data types of Scala, i.e., `Boolean`, `Char`, `Byte`, `Short`, `Int`, `Long`, `Float`, `Double` and `Unit`, work exactly as on the JVM, with the following three exceptions.
3314

3415
### `toString` of `Float`, `Double` and `Unit`
3516

@@ -58,27 +39,19 @@ type they were created with. The following are examples:
5839
- 1 matches `Byte`, `Short`, `Int`, `Float`, `Double`
5940
- 128 (`> Byte.MaxValue`) matches `Short`, `Int`, `Float`, `Double`
6041
- 32768 (`> Short.MaxValue`) matches `Int`, `Float`, `Double`
61-
- 2147483647 matches `Int`, `Double` if strict-floats are enabled
62-
(because that number cannot be represented in a strict 32-bit `Float`),
63-
otherwise `Int`, `Float` and `Double`
42+
- 2147483647 matches `Int` and `Double`, but not `Float`
43+
(because that number cannot be represented in a 32-bit `Float`)
6444
- 2147483648 (`> Int.MaxValue`) matches `Float`, `Double`
6545
- 1.5 matches `Float`, `Double`
66-
- 1.4 matches `Double` only if strict-floats are enabled,
67-
otherwise `Float` and `Double`
68-
(unlike 1.5, the value 1.4 cannot be represented in a strict 32-bit `Float`)
46+
- 1.4 only matches `Double`
47+
(unlike 1.5, the value 1.4 cannot be represented in a 32-bit `Float`)
6948
- `NaN`, `Infinity`, `-Infinity` and `-0.0` match `Float`, `Double`
7049

7150
As a consequence, the following apparent subtyping relationships hold:
7251

7352
Byte <:< Short <:< Int <:< Double
7453
<:< Float <:<
7554

76-
if strict-floats are enabled, or
77-
78-
Byte <:< Short <:< Int <:< Float =:= Double
79-
80-
otherwise.
81-
8255
### `getClass()`
8356

8457
In Scala/JVM as well as Scala.js, when assigning a primitive value to an `Any` (or a generic type), and asking for its `getClass()`, Scala returns the *boxed class* of the value's type, rather than the primitive value.
@@ -94,6 +67,25 @@ Instead, it uses the more sensible `java.lang.Void`, as `Void` is the boxed clas
9467
This means that while `java.lang.Void` is not instantiable on the JVM, in Scala.js it has a singleton instance, namely `()`.
9568
This also manifests itself in `Array[Unit]` which is effectively `Array[java.lang.Void]` at run-time, instead of `Array[scala.runtime.BoxedUnit]`.
9669

70+
### Non-strict floats (deprecated; default until Scala.js 1.8.0)
71+
72+
Until v1.8.0, Scala.js underspecified the behavior of `Float`s by default with so-called *non-strict floats*.
73+
74+
Non-strict floats can still be enabled with the following sbt setting:
75+
76+
{% highlight scala %}
77+
scalaJSLinkerConfig ~= { _.withSemantics(_.withStrictFloats(false)) }
78+
{% endhighlight %}
79+
80+
Under non-strict floats, any `Float` value can be stored as a `Double` instead, and any operation on `Float`s can be computed with double precision.
81+
The choice of whether or not to behave as such, when and where, is left to the implementation.
82+
In addition, `x.isInstanceOf[Float]` will return `true` for any `number` values (not only the ones that fit in a 32-bit float).
83+
84+
Non-strict floats are deprecated and will eventually be removed in a later major or minor version of Scala.js.
85+
86+
Enabling non-strict floats may significantly improve the performance (up to 4x for `Float`-intensive applications) when targeting JS engines that do not support [the `Math.fround` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround), such as Internet Explorer (which implies emitting ES 5.1 code).
87+
If you are in that situation, we advise to use `Double`s instead of `Float`s as much as possible.
88+
9789
## Undefined behaviors
9890

9991
The JVM is a very well specified environment, which even specifies how some

libraries/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Show your true colors by adding a Scala.js badge on your site! Select the lowest
2323

2424
If you don't find your version of Scala.js, that's probably because it is forward-compatible with its predecessor,
2525
in which case you should take the latest available version older than your version of Scala.js.
26-
For example, for Scala.js 0.6.7, use the 0.6.6+ badge.
26+
For example, for Scala.js 1.9.x, use the 1.8.0+ badge.
2727

2828
{% include badge-generator.html %}
2929

0 commit comments

Comments
 (0)