-
Notifications
You must be signed in to change notification settings - Fork 0
Report JS tree in targetPureWasm=true in Analyzer #24
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
Conversation
FloatingPointBits.longBitsToDouble(bits) | ||
linkTimeIf(LinkingInfo.targetPureWasm) { | ||
// TODO: implement for Wasm without intrinsic? | ||
throw new AssertionError("Not implemented.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use (a copy of) the "polyfills" in FloatingPointBits
for the 4 floating point bits conversions.
// TODO: implement for Wasm without intrinsic? | ||
throw new AssertionError("Not implemented.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TODO: implement for Wasm without intrinsic? | |
throw new AssertionError("Not implemented.") | |
(toUnsignedLong(dividend) / toUnsignedLong(divisor)).toInt |
// TODO: implement for Wasm without intrinsic? | ||
throw new AssertionError("Not implemented.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TODO: implement for Wasm without intrinsic? | |
throw new AssertionError("Not implemented.") | |
(toUnsignedLong(dividend) % toUnsignedLong(divisor)).toInt |
// TODO: implement for Wasm without intrinsic? | ||
throw new AssertionError("Not implemented.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use the algorithm under "See Hacker's Delight" from clz32Dynamic
just below.
linkTimeIf(!LinkingInfo.targetPureWasm) { | ||
if (writableStackTrace) | ||
fillInStackTrace() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider moving this test inside fillInStackTrace()
instead. User code can call fillInStackTrace
; it should link IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def equals(x: Object, y: Object): Boolean = | ||
if (scala.scalajs.LinkingInfo.targetPureWasm) { | ||
linkTimeIf(LinkingInfo.targetPureWasm) { | ||
equals2(x, y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one should be
if (x eq y) true
else equals2(x, y)
for pure Wasm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
528f905
to
ae95e4a
Compare
ae95e4a
to
16522a3
Compare
Previously, when `targetPureWasm = true`, JS-related trees would lead to link failure at `FunctionEmitter` with an exception. However, this report only indicated which location contained the JS interop, and not the call path leading to it. This made it difficult to tell how the JS interop code was reached. This commit introduces a new `JSInteropInPureWasm` error that specifically flags JS-related trees discovered within a reachable code path when `targetPureWasm` is enabled. Now, if the Analyzer detects JS interop under these conditions, it reports not just the location but also the sequence of calls that led to that point, that improves the debugging experience for pure Wasm targets. e.g. ``` [error] Uses JS interop with targetPureWasm = true [error] dispatched from scala.collection.mutable.ArrayBuilder$.scala$collection$mutable$ArrayBuilder$$genericArrayBuilderResult(java.lang.Class,scala.scalajs.js.Array)java.lang.Object [error] called from scala.collection.mutable.ArrayBuilder$generic.result()java.lang.Object [error] dispatched from scala.collection.mutable.Builder.result()java.lang.Object [error] called from scala.collection.generic.GenericCompanion.apply(scala.collection.Seq)scala.collection.GenTraversable [error] dispatched from scala.collection.immutable.Set$.apply(scala.collection.Seq)scala.collection.GenTraversable [error] called from org.scalajs.testsuite.javalib.lang.ThrowablesTest.suppression()void [error] called from testSuiteWASI.JavalibLangTest$.run()void [error] called from testSuiteWASI.Run$.main([java.lang.String)void [error] called from static testSuiteWASI.Run.main([java.lang.String)void [error] called from core module module initializers [error] involving instantiated classes: [error] scala.collection.mutable.ArrayBuilder$generic [error] scala.collection.mutable.HashSet$ [error] scala.collection.Seq$ [error] scala.collection.immutable.Set$ [error] org.scalajs.testsuite.javalib.lang.ThrowablesTest [error] testSuiteWASI.JavalibLangTest$ [error] testSuiteWASI.Run$ ```
16522a3
to
6c8be06
Compare
@inline def abs(a: scala.Double): scala.Double = js.Math.abs(a) | ||
@inline def abs(a: scala.Float): scala.Float = | ||
linkTimeIf(LinkingInfo.targetPureWasm) { | ||
if (a == -0.0) 0.0f |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've got a better one:
Float.intBitsToFloat(Float.floatToIntBits(a) & ~Int.MinValue)
😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha right, masking all bits except the sign bit turns into abs
, nice 😄
Is there any reason to use ~Int.MinValue
rather than Int.MaxValue
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MinValue
is synonymous of SignBit
. So it's clear that we're masking off the sign bit.
With MaxValue
it's less obvious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense 👍
|
||
@inline def abs(a: scala.Double): scala.Double = | ||
linkTimeIf(LinkingInfo.targetPureWasm) { | ||
if (a == -0.0) 0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And likewise here:
Double.longBitsToDouble(Double.doubleToLongBits(a) & ~Long.MinValue)
To avoid analyzer reports the `JSInteropInPureWasm` error
6c8be06
to
eeb00ff
Compare
cherry-picking scala-js@95d74bfPreviously, when
targetPureWasm = true
, JS-related treeswould lead to link failure at
FunctionEmitter
with an exception.However, this report only indicated which location contained the JS interop, and not the call path leading to it.
This made it difficult to tell how the JS interop code was reached.
This commit introduces a new
JSInteropInPureWasm
error that specifically flags JS-related trees discovered within a reachable code path whentargetPureWasm
is enabled.Now, if the Analyzer detects JS interop under these conditions, it reports not just the location but also the sequence of calls that led to that point, that improves the debugging experience for pure Wasm targets.