Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Commit

Permalink
Merge pull request #49 from satabin/dependencies/scala-2.13_fs2-2
Browse files Browse the repository at this point in the history
Bump dependency versions
  • Loading branch information
satabin authored Oct 3, 2019
2 parents 0a080db + 2876dd7 commit 8e646d4
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "2.0.0-RC7"
version = "2.0.0"
maxColumn = 120
danglingParentheses = false
align.openParenCallSite = true
Expand Down
20 changes: 16 additions & 4 deletions benchmarks/src/swam/MandelbrotPerformances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ import config._
import validation._
import formats.DefaultFormatters._

import cats.implicits._
import cats.effect.IO

import pureconfig._
import pureconfig.generic.auto._
import pureconfig.module.squants._
import pureconfig.module.catseffect._
Expand All @@ -34,6 +32,10 @@ import org.openjdk.jmh.infra.Blackhole

import java.nio.file.Paths
import java.util.concurrent.TimeUnit
import cats.effect.Blocker
import scala.concurrent.ExecutionContext
import java.util.concurrent.Executors
import pureconfig.ConfigSource

@BenchmarkMode(Array(Mode.AverageTime))
@OutputTimeUnit(TimeUnit.NANOSECONDS)
Expand All @@ -58,18 +60,28 @@ class MandelbrotPerformances {

private var mandelbrot: exports.EFunction4[Int, Double, Double, Double, Unit, IO] = _

private val executor = Executors.newCachedThreadPool()
private val blocker = Blocker.liftExecutionContext(ExecutionContext.fromExecutor(executor))

implicit val cs = IO.contextShift(ExecutionContext.global)

@Setup
def setup(): Unit = {
mandelbrot = (for {
v <- Validator[IO]
conf <- loadConfigF[IO, EngineConfiguration]("swam.runtime")
conf <- ConfigSource.default.at("swam.runtime").loadF[IO, EngineConfiguration]
e = Engine[IO](conf.copy(useLowLevelAsm = useLowLevelAsm), v)
m <- e.compile(Paths.get("../../../../benchmarks/resources/mandelbrot.wasm"))
m <- e.compile(Paths.get("../../../../benchmarks/resources/mandelbrot.wasm"), blocker)
i <- m.instantiate
f <- i.exports.typed.procedure4[Int, Double, Double, Double]("mandelbrot")
} yield f).unsafeRunSync()
}

@TearDown
def teardown(): Unit = {
executor.shutdown()
}

@Benchmark
def computeMandelbrot(bh: Blackhole): Unit = {
bh.consume(mandelbrot(iterations, x, y, d).unsafeRunSync())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ package high
import org.openjdk.jmh.infra._
import org.openjdk.jmh.annotations._

import cats._
import cats.implicits._

import scala.util.Random
Expand Down
15 changes: 9 additions & 6 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ val swamUrl = "https://github.com/satabin/swam"

val swamDeveloper = Developer("satabin", "Lucas Satabin", "https://github.com/satabin")

val pureconfigVersion = "0.11.1"
val fs2Version = "2.0.1"

val pureconfigVersion = "0.12.1"

trait SwamModule extends ScalaModule with ScalafmtModule with Headers {

def scalaVersion = "2.12.8"
def scalaVersion = "2.12.10"

def scalacOptions =
Seq("-feature", "-deprecation", "-unchecked", "-Ypartial-unification", "-Ypatmat-exhaust-depth", "off", "-Ywarn-unused:locals,imports")
Expand All @@ -48,7 +50,7 @@ trait SwamModule extends ScalaModule with ScalafmtModule with Headers {

trait ScoverageSwamModule extends SwamModule with ScoverageModule {

def scoverageVersion = "1.3.1"
def scoverageVersion = "1.4.0"

}

Expand All @@ -57,8 +59,9 @@ object core extends SwamModule with PublishModule {
def ivyDeps =
Agg(
ivy"com.beachape::enumeratum:1.5.13",
ivy"co.fs2::fs2-core:1.1.0-M2",
ivy"org.scodec::scodec-stream:1.2.1",
ivy"co.fs2::fs2-core:$fs2Version",
ivy"co.fs2::fs2-io:$fs2Version",
ivy"org.scodec::scodec-stream:2.0.0",
ivy"com.github.pureconfig::pureconfig-generic:$pureconfigVersion",
ivy"com.github.pureconfig::pureconfig-squants:$pureconfigVersion",
ivy"com.github.pureconfig::pureconfig-cats-effect:$pureconfigVersion",
Expand Down Expand Up @@ -90,7 +93,7 @@ object core extends SwamModule with PublishModule {
object text extends SwamModule with PublishModule {
def moduleDeps = Seq(core)

def ivyDeps = Agg(ivy"com.lihaoyi::fastparse:2.1.3", ivy"co.fs2::fs2-io:1.1.0-M2")
def ivyDeps = Agg(ivy"com.lihaoyi::fastparse:2.1.3", ivy"co.fs2::fs2-io:$fs2Version")

def publishVersion = swamVersion

Expand Down
30 changes: 25 additions & 5 deletions core/src/swam/ModuleLoader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,32 @@ import scala.language.higherKinds
*/
class ModuleLoader[F[_]](implicit F: Effect[F]) {

def readPath(path: Path): Stream[F, Section] =
readBytes(BitVector.fromChannel(new java.io.FileInputStream(path.toFile).getChannel))
def readPath(path: Path, blocker: Blocker, chunkSize: Int = 1024)(implicit cs: ContextShift[F]): Stream[F, Section] =
readBytes(io.file.readAll(path, blocker, chunkSize = chunkSize))

private val header = hex"0061736d01000000"

/** Reads a binary module from the given bytes. */
def readBytes(bytes: BitVector): Stream[F, Section] =
ModuleStream.decoder
.decode(bytes)
def readBytes(bytes: Stream[F, Byte]): Stream[F, Section] = {
def go(s: Stream[F, Byte]): Pull[F, Section, Unit] =
ModuleStream.decoder(s.chunks.map(_.toBitVector)).flatMap {
case Some(_) => Pull.raiseError(new BinaryException("unexpected end of input"))
case None => Pull.done
}

bytes.pull
.unconsN(8, allowFewer = false)
.flatMap {
case Some((headerBytes, tl)) =>
val bv = ByteVector(headerBytes.toArray)
if (bv == header)
Pull.pure(tl)
else
Pull.raiseError(new BinaryException(s"unexpected header ${bv.toHex(Bases.Alphabets.HexUppercase)}"))
case None => Pull.raiseError(new BinaryException("unexpected end of input"))
}
.flatMap(go(_))
.stream
}

}
21 changes: 2 additions & 19 deletions core/src/swam/binary/ModuleStream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,8 @@ package binary

import syntax._

import scodec.bits._
import scodec.stream._

import scodec._
import scodec.codecs._
import scodec.codecs.literals._

/** The module streams expose way to encode and decode WebAssembly modules in
* binary format.
* Section are streamed in the order they arrive, which may not be correct when
Expand All @@ -34,22 +29,10 @@ import scodec.codecs.literals._
*/
object ModuleStream {

private val header: Codec[Unit] =
("magic" | hex"0061736d") ~>
("version" | hex"01000000")

val sections: StreamCodec[Section] =
StreamCodec
.instance(encode.once(WasmCodec.section), decode.once(WasmCodec.section))
.many

val decoder: StreamDecoder[Section] =
for {
() <- decode.once(header)
section <- sections
} yield section
StreamDecoder.many(WasmCodec.section)

def encoder: StreamEncoder[Section] =
encode.emit(hex"0061736d01000000".bits) ++ sections
StreamEncoder.many(WasmCodec.section)

}
40 changes: 20 additions & 20 deletions core/src/swam/binary/WasmCodec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ import scodec.codecs._

object WasmCodec extends InstCodec {

protected val externalKind: Codec[ExternalKind] =
val externalKind: Codec[ExternalKind] =
mappedEnum(byte,
Map[ExternalKind, Byte](ExternalKind.Function -> 0,
ExternalKind.Table -> 1,
ExternalKind.Memory -> 2,
ExternalKind.Global -> 3))

protected val types: Codec[Vector[FuncType]] =
val types: Codec[Vector[FuncType]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, funcType))

protected val importEntry: Codec[String ~ String ~ Import] =
val importEntry: Codec[String ~ String ~ Import] =
(("module" | variableSizeBytes(varuint32, utf8)) ~
("field" | variableSizeBytes(varuint32, utf8))).flatZip {
case (module, field) =>
Expand All @@ -50,65 +50,65 @@ object WasmCodec extends InstCodec {
.|(ExternalKind.Global) { case Import.Global(_, _, tpe) => tpe }(Import.Global(module, field, _))(globalType)
}

protected val imports: Codec[Vector[Import]] =
val imports: Codec[Vector[Import]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, importEntry.xmap({
case (_, e) => e
}, { case e @ Import(mod, fld) => ((mod, fld), e) })))

protected val functions: Codec[Vector[Int]] =
val functions: Codec[Vector[Int]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, varuint32))

protected val tables: Codec[Vector[TableType]] =
val tables: Codec[Vector[TableType]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, tableType))

protected val mems: Codec[Vector[MemType]] =
val mems: Codec[Vector[MemType]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, memoryType))

protected val globalVariable: Codec[Global] =
val globalVariable: Codec[Global] =
(globalType :: expr).as[Global]

protected val globals: Codec[Vector[Global]] =
val globals: Codec[Vector[Global]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, globalVariable))

protected val elemSegment: Codec[Elem] =
val elemSegment: Codec[Elem] =
(("index" | varuint32) ::
("offset" | expr) ::
("elems" | vectorOfN(varuint32, varuint32))).as[Elem]

protected val elem: Codec[Vector[Elem]] =
val elem: Codec[Vector[Elem]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, elemSegment))

protected val dataSegment: Codec[Data] =
val dataSegment: Codec[Data] =
(("index" | varuint32) ::
("offset" | expr) ::
("data" | variableSizeBytes(varuint32, scodec.codecs.bits))).as[Data]

protected val data: Codec[Vector[Data]] =
val data: Codec[Vector[Data]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, dataSegment))

protected val start: Codec[FuncIdx] =
val start: Codec[FuncIdx] =
variableSizeBytes(varuint32, varuint32)

protected val localEntry: Codec[LocalEntry] =
val localEntry: Codec[LocalEntry] =
(varuint32 :: valType).as[LocalEntry]

protected val funcBody: Codec[FuncBody] =
val funcBody: Codec[FuncBody] =
variableSizeBytes(varuint32,
(("locals" | vectorOfN(varuint32, localEntry)) ::
("code" | expr)).as[FuncBody])

protected val code: Codec[Vector[FuncBody]] =
val code: Codec[Vector[FuncBody]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, funcBody))

protected val exportEntry: Codec[Export] =
val exportEntry: Codec[Export] =
(("field" | variableSizeBytes(varuint32, utf8)) ::
("kind" | externalKind) ::
("index" | varuint32)).as[Export]

protected val exports: Codec[Vector[Export]] =
val exports: Codec[Vector[Export]] =
variableSizeBytes(varuint32, vectorWithN(varuint32, exportEntry))

protected val custom: Codec[(String, BitVector)] =
val custom: Codec[(String, BitVector)] =
variableSizeBytes(varuint32,
(("name" | variableSizeBytes(varuint32, utf8)) ~
("payload" | scodec.codecs.bits)))
Expand Down
6 changes: 6 additions & 0 deletions core/src/swam/binary/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package swam

import fs2._

import scodec.bits._
import scodec._
import scodec.codecs._
Expand All @@ -24,8 +26,12 @@ import scala.annotation.tailrec

import scala.collection.immutable.VectorBuilder

import scala.language.higherKinds

package object binary {

type VarResut[F[_]] = (Long, Option[(ByteVector, Int, Stream[F, Byte])])

val noop: Codec[Unit] = new Codec[Unit] {
def decode(bits: BitVector): Attempt[DecodeResult[Unit]] =
Attempt.successful(DecodeResult((), bits))
Expand Down
8 changes: 3 additions & 5 deletions core/src/swam/decompilation/Decompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import util.pretty.Doc

import cats.effect._

import scodec.bits._

import fs2._

import java.nio.file.Path
Expand All @@ -40,15 +38,15 @@ abstract class Decompiler[F[_]](implicit F: Effect[F]) extends ModuleLoader[F] {
*
* The module is not validated so invalid modules can also be decompiled.
*/
def decompile(path: Path): F[Doc] =
decompile(readPath(path))
def decompilePath(path: Path, blocker: Blocker, chunkSize: Int = 1024)(implicit cs: ContextShift[F]): F[Doc] =
decompile(readPath(path, blocker, chunkSize))

/** Returns a pretty-printed [[swam.util.pretty.Doc Doc]] resulting from decompiling
* the module at the given bytes.
*
* The module is not validated so invalid modules can also be decompiled.
*/
def decompile(bytes: BitVector): F[Doc] =
def decompileBytes(bytes: Stream[F, Byte]): F[Doc] =
decompile(readBytes(bytes))

/** Returns a pretty-printed [[swam.util.pretty.Doc Doc]] resulting from decompiling
Expand Down
7 changes: 5 additions & 2 deletions core/src/swam/opcodes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,11 @@ object OpCode {
final val F64ReinterpretI64 = 0xbf

def withValueOpt(i: Int): Option[OpCode] =
if (all.contains(i))
Some(i)
unapply(i.toByte)

def unapply(b: Byte): Option[OpCode] =
if (all.contains(b))
Some(b)
else
None

Expand Down
3 changes: 2 additions & 1 deletion core/src/swam/validation/Validator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import cats._
import cats.effect._
import cats.implicits._

import pureconfig._
import pureconfig.generic.auto._
import pureconfig.module.squants._
import pureconfig.module.catseffect._
Expand Down Expand Up @@ -52,6 +53,6 @@ object Validator {

def apply[F[_]: Sync]: F[Validator[F]] =
for {
conf <- loadConfigF[F, ValidationConfiguration]("swam.validation")
conf <- ConfigSource.default.at("swam.validation").loadF[F, ValidationConfiguration]
} yield apply[F](conf)
}
Loading

0 comments on commit 8e646d4

Please sign in to comment.