8000 Merge pull request #55 from scala-wasm/provide-essential-externs-to-t… · scala-wasm/scala-wasm@46c724a · GitHub
[go: up one dir, main page]

Skip to content

Commit 46c724a

Browse files
authored
Merge pull request #55 from scala-wasm/provide-essential-externs-to-target-pure-wasm
Provide essential externs to target pure wasm
2 parents 7c02eb3 + b25e513 commit 46c724a

File tree

19 files changed

+406
-23
lines changed

19 files changed

+406
-23
lines changed

examples/test-component-model/src/main/scala/componentmodel/Exports.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ object TestImports {
7878
import Basics._
7979
import Tests._
8080
import Countable._
81+
val start = System.currentTimeMillis()
8182
assert(1 == roundtripU8(1))
8283
assert(0 == roundtripS8(0))
8384
assert(0 == roundtripU16(0))
@@ -169,6 +170,8 @@ object TestImports {
169170
// unknown handle index 1 (?)
170171
assert(100 == Counter.sum(c1, c2).valueOf())
171172
}
173+
val end = System.currentTimeMillis()
174+
println(s"elapsed: ${(end - start).toInt} ms")
172175
}
173176
}
174177

examples/test-suite-wasi/src/main/scala/test-suites-wasi/Run.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ object Run {
66
JavalibLangTest.run()
77
JavalibUtilTest.run()
88
LibraryTest.run()
9+
10+
println("Test suite completed")
911
}
1012
}

javalib/src/main/scala/java/lang/Math.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ object Math {
153153
@inline def atan(a: scala.Double): scala.Double = js.Math.atan(a)
154154
@inline def atan2(y: scala.Double, x: scala.Double): scala.Double = js.Math.atan2(y, x)
155155

156-
@inline def random(): scala.Double = js.Math.random()
156+
@inline def random(): scala.Double =
157+
if (LinkingInfo.targetPureWasm) WasmSystem.random()
158+
else js.Math.random()
157159

158160
@inline def toDegrees(a: scala.Double): scala.Double = a * 180.0 / PI
159161
@inline def toRadians(a: scala.Double): scala.Double = a / 180.0 * PI

javalib/src/main/scala/java/lang/System.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ object System {
6868

6969
@inline
7070
def currentTimeMillis(): scala.Long =
71-
(new js.Date).getTime().toLong
71+
if (LinkingInfo.targetPureWasm) WasmSystem.currentTimeMillis()
72+
else js.Date.now().toLong
7273

7374
private object NanoTime {
7475
val getHighPrecisionTime: js.Function0[scala.Double] = {
@@ -90,7 +91,8 @@ object System {
9091

9192
@inline
9293
def nanoTime(): scala.Long =
93-
(NanoTime.getHighPrecisionTime() * 1000000).toLong
94+
if (LinkingInfo.targetPureWasm) WasmSystem.nanoTime()
95+
else (NanoTime.getHighPrecisionTime() * 1000000).toLong
9496

9597
// arraycopy ----------------------------------------------------------------
9698

@@ -383,8 +385,8 @@ private final class JSConsoleBasedPrintStream(isErr: scala.Boolean)
383385
override def close(): Unit = ()
384386

385387
private def doWriteLine(line: String): Unit = {
386-
if (LinkingInfo.targetPureWasm) { // isWASI
387-
// TODO
388+
if (LinkingInfo.targetPureWasm) {
389+
WasmSystem.print(line)
388390
} else {
389391
import js.DynamicImplicits.truthValue
390392

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package java.lang
2+
10000 3+
import java.lang.wasi.clocks
4+
import java.lang.wasi.{random => wrandom}
5+
import java.lang.wasi.cli
6+
import java.lang.wasi.io
7+
import java.lang.wasi.io.Streams.StreamError
8+
9+
protected[lang] object WasmSystem {
10+
@noinline
11+
def print(s: String): Unit = {
12+
val stdout = cli.Stdout.getStdout()
13+
stdout.blockingWriteAndFlush((s + "\n").getBytes())
14+
// if (!result.isOk) {
15+
// val err = result.value.asInstanceOf[StreamError]
16+
// err match {
17+
// case StreamError.Closed =>
18+
// throw new RuntimeException("closed")
19+
// case failed: StreamError.LastOperationFailed =>
20+
// throw new RuntimeException(failed.value.toDebugString())
21+
// }
22+
// }
23+
stdout.close()
24+
}
25+
26+
@noinline
27+
def nanoTime(): scala.Long = {
28+
val d = clocks.WallClock.now()
29+
d.seconds * 1000000000 + d.nanoseconds
30+
}
31+
32+
@noinline
33+
def currentTimeMillis(): scala.Long = {
34+
val d = clocks.WallClock.now()
35+
d.seconds * 1000 + d.nanoseconds / 1000
36+
}
37+
38+
@noinline
39+
def random(): scala.Double = {
40+
val i = wrandom.Insecure.getInsecureRandomU64()
41+
// Maps a 64-bit unsigned integer i to a value within the [0.0, 1.0) range.
42+
// (i >>> 11) extracts the 53 most significant 53 bits [0, 2^53-1)
43+
// and (1.0 / (1L << 53)) is a scaling factor 2^-53.
44+
// by multiplying them, equally spaced values in the interval [0.0, 1.0)
45+
(i >>> 11) * (1.0 / (1L << 53))
46+
}
47+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package java.lang.wasi.cli
2+
3+
import scala.scalajs.component.annotation._
4+
5+
import wasi.io.Streams.OutputStream
6+
import scala.scalajs.{component => cm}
7+
8+
/** https://github.com/WebAssembly/WASI/blob/main/wasip2/cli/stdio.wit */
9+
object Stdout {
10+
@ComponentImport("wasi:cli/stdout@0.2.0", "get-stdout")
11+
def getStdout(): OutputStream = cm.native
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package java.lang.wasi.clocks
2+
3+
import scala.scalajs.component.annotation._
4+
import scala.scalajs.component.unsigned._
5+
import scala.scalajs.{component => cm}
6+
7+
/** https://github.com/WebAssembly/WASI/blob/main/wasip2/clocks/wall-clock.wit */
8+
object WallClock {
9+
10+
@ComponentImport("wasi:clocks/wall-clock@0.2.0", "now")
11+
def now(): Datetime = cm.native
12+
13+
@ComponentImport("wasi:clocks/wall-clock", "resolution")
14+
def resolution(): Datetime = cm.native
15+
16+
@ComponentRecord
17+
final class Datetime(val seconds: ULong, val nanoseconds: UInt)
18+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package java.lang.wasi.io
2+
3+
import scala.scalajs.component.annotation._
4+
import scala.scalajs.{component => cm}
5+
6+
/** https://github.com/WebAssembly/WASI/blob/main/wasip2/io/error.wit */
7+
object Error {
8+
@ComponentResourceImport("wasi:io/error", "error")
9+
trait Error {
10+
@ComponentResourceMethod("to-debug-string")
11+
def toDebugString(): String = cm.native
12+
}
13+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package java.lang.wasi.io
2+
3+
import scala.scalajs.{component => cm}
4+
import scala.scalajs.component.annotation._
5+
import scala.scalajs.component.unsigned._
6+
7+
import wasi.io.Error.{Error => WasiIOError}
8+
9+
/** https://github.com/WebAssembly/WASI/blob/main/wasip2/io/streams.wit */
10+
object Streams {
11+
12+
@ComponentResourceImport("wasi:io/streams@0.2.0", "output-stream")
13+
trait OutputStream {
14+
15+
@ComponentResourceMethod("blocking-write-and-flush")
16+
def blockingWriteAndFlush(contents: Array[UByte]): cm.Result[Unit, StreamError]
17+
18+
@ComponentResourceDrop
19+
def close(): Unit = cm.native
20+
}
21+
22+
sealed trait StreamError extends cm.Variant
23+
object StreamError {
24+
final class LastOperationFailed(val value: WasiIOError) extends StreamError {
25+
type T = WasiIOError
26+
val _index: Int = 0
27+
}
28+
29+
final object Closed extends StreamError {
30+
type T = Unit
31+
val value = ()
32+
val _index = 1
33+
}
34+
}
35+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package java.lang.wasi.random
2+
3+
import scala.scalajs.component.annotation._
4+
import scala.scalajs.component.unsigned._
5+
import scala.scalajs.{component => cm}
6+
7+
/** https://github.com/WebAssembly/WASI/blob/main/wasip2/random/insecure.wit */
8+
object Insecure {
9+
@ComponentImport("wasi:random/insecure", "get-insecure-random-u64")
10+
def getInsecureRandomU64(): ULong = cm.native
11+
}

0 commit comments

Comments
 (0)
0