mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +00:00
Rewrite library, set up native image
This commit is contained in:
parent
e3670f8bee
commit
e56f5df835
15
build.sbt
15
build.sbt
@ -214,8 +214,21 @@ lazy val compiler = crossProject(JVMPlatform, JSPlatform)
|
|||||||
|
|
||||||
lazy val `compiler-native-lib` = project
|
lazy val `compiler-native-lib` = project
|
||||||
.in(file("compiler-native-lib"))
|
.in(file("compiler-native-lib"))
|
||||||
|
.enablePlugins(GraalVMNativeImagePlugin)
|
||||||
.settings(commons: _*)
|
.settings(commons: _*)
|
||||||
.dependsOn(compiler.jvm, io.jvm, transform.jvm, `backend-air`.jvm)
|
.settings(
|
||||||
|
Compile / mainClass := Some("aqua.compiler.Library"),
|
||||||
|
graalVMNativeImageOptions ++= Seq(
|
||||||
|
"--verbose",
|
||||||
|
"--no-fallback",
|
||||||
|
// Uncomment next lines to use llvm backend
|
||||||
|
// and obtain bitcode files
|
||||||
|
// "-H:CompilerBackend=llvm",
|
||||||
|
// "-H:TempDirectory=temp", // Directory with bc files
|
||||||
|
"--shared" // Produce shared library
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.dependsOn(`aqua-api`.jvm)
|
||||||
|
|
||||||
lazy val backend = crossProject(JVMPlatform, JSPlatform)
|
lazy val backend = crossProject(JVMPlatform, JSPlatform)
|
||||||
.withoutSuffixFor(JVMPlatform)
|
.withoutSuffixFor(JVMPlatform)
|
||||||
|
@ -1,81 +1,59 @@
|
|||||||
package aqua.compiler
|
package aqua.compiler
|
||||||
|
|
||||||
import aqua.AquaIO
|
|
||||||
import org.graalvm.nativeimage.IsolateThread
|
import org.graalvm.nativeimage.IsolateThread
|
||||||
import org.graalvm.nativeimage.c.function.CEntryPoint
|
import org.graalvm.nativeimage.c.function.CEntryPoint
|
||||||
import org.graalvm.nativeimage.c.`type`.CCharPointer
|
import org.graalvm.nativeimage.c.`type`.{CCharPointer, CCharPointerPointer, CTypeConversion}
|
||||||
import org.graalvm.nativeimage.c.`type`.CTypeConversion
|
|
||||||
import aqua.io.AquaFileError
|
import scala.annotation.static
|
||||||
import aqua.files.{AquaFileSources, FileModuleId}
|
|
||||||
import cats.{Applicative, Functor, Monad}
|
|
||||||
import cats.data.{Chain, ValidatedNec}
|
|
||||||
import cats.data.Validated.Valid
|
|
||||||
import cats.data.Validated.validNec
|
|
||||||
import cats.effect.IO
|
|
||||||
import fs2.io.file.{Files, Path}
|
|
||||||
import cats.implicits.*
|
|
||||||
import aqua.SpanParser
|
|
||||||
import aqua.model.transform.TransformConfig
|
|
||||||
import aqua.model.AquaContext
|
|
||||||
import aqua.model.transform.Transform
|
|
||||||
import aqua.backend.Backend
|
|
||||||
import aqua.backend.AirFunction
|
|
||||||
import aqua.backend.Generated
|
|
||||||
import aqua.res.AquaRes
|
|
||||||
import aqua.parser.lift.FileSpan
|
|
||||||
import aqua.backend.air.AirBackend
|
|
||||||
import aqua.files.AquaFilesIO.summon
|
|
||||||
import cats.effect.unsafe.implicits.global
|
import cats.effect.unsafe.implicits.global
|
||||||
|
|
||||||
|
import aqua.api.{APICompilation, AquaAPIConfig}
|
||||||
|
import aqua.backend.api.APIBackend
|
||||||
|
|
||||||
|
// This is neede for @static to work in object
|
||||||
|
class Library {}
|
||||||
|
|
||||||
object Library {
|
object Library {
|
||||||
|
|
||||||
|
@CEntryPoint(name = "compile")
|
||||||
private final val path = Path("")
|
@static
|
||||||
|
def compile(
|
||||||
private class RawAquaSource[F[_] : AquaIO : Monad : Files](input: String, imports: List[String]) extends AquaFileSources[F](path, imports.map(Path.apply)):
|
thread: IsolateThread,
|
||||||
override def sources: F[ValidatedNec[AquaFileError, Chain[(FileModuleId, String)]]] = {
|
codePointer: CCharPointer,
|
||||||
Applicative[F].pure(Valid(Chain.one((FileModuleId(path), input))))
|
resultPointer: CCharPointerPointer,
|
||||||
}
|
errorsPointer: CCharPointerPointer
|
||||||
|
): Int = {
|
||||||
|
|
||||||
private class LocalBackendTransform(transformConfig: TransformConfig) extends Backend.Transform:
|
|
||||||
override def transform(ex: AquaContext): AquaRes =
|
|
||||||
Transform.contextRes(ex, transformConfig)
|
|
||||||
|
|
||||||
override def generate(aqua: AquaRes): Seq[Generated] = AirBackend.generate(aqua)
|
|
||||||
|
|
||||||
|
|
||||||
private class LocalAirValidator[F[_] : Applicative]() extends AirValidator[F]:
|
|
||||||
|
|
||||||
override def init(): F[Unit] = Applicative[F].pure(())
|
|
||||||
|
|
||||||
override def validate(airs: List[AirFunction]): F[ValidatedNec[String, Unit]] =
|
|
||||||
Applicative[F].pure(validNec(()))
|
|
||||||
|
|
||||||
private def compileF[F[_] : AquaIO : Monad : Files](input: String, imports: List[String]): F[ValidatedNec[AquaError[FileModuleId, AquaFileError, FileSpan.F], Chain[AquaCompiled[FileModuleId]]]] = for {
|
|
||||||
sources <- new RawAquaSource[F](input, imports).pure
|
|
||||||
transformConfig <- TransformConfig().pure
|
|
||||||
backendTransform <- new LocalBackendTransform(transformConfig).pure
|
|
||||||
validator <- new LocalAirValidator[F]().pure
|
|
||||||
result <- CompilerAPI
|
|
||||||
.compile[F, AquaFileError, FileModuleId, FileSpan.F](
|
|
||||||
sources,
|
|
||||||
SpanParser.parser,
|
|
||||||
validator,
|
|
||||||
backendTransform,
|
|
||||||
AquaCompilerConf(transformConfig.constantsList))
|
|
||||||
} yield result
|
|
||||||
|
|
||||||
@CEntryPoint(name = "compile") def compile(thread: IsolateThread, codePointer: CCharPointer): Int = {
|
|
||||||
val code = CTypeConversion.toJavaString(codePointer)
|
val code = CTypeConversion.toJavaString(codePointer)
|
||||||
|
|
||||||
val program = compileF[IO](code, List.empty)
|
val result = APICompilation
|
||||||
val result = program.unsafeRunSync()
|
.compileString(
|
||||||
|
code,
|
||||||
|
imports = Nil,
|
||||||
|
aquaConfig = AquaAPIConfig(),
|
||||||
|
backend = APIBackend
|
||||||
|
)
|
||||||
|
.unsafeRunSync()
|
||||||
|
|
||||||
if (result.isValid) {
|
result.fold(
|
||||||
0
|
errors =>
|
||||||
} else {
|
errors.toChain.toList.zipWithIndex.foreach { case (error, i) =>
|
||||||
1
|
errorsPointer.write(i, CTypeConversion.toCString(error).get())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
|
||||||
|
,
|
||||||
|
compiled =>
|
||||||
|
compiled.toList.flatMap(_.compiled).flatMap(_.air).map(_.air).zipWithIndex.foreach {
|
||||||
|
case (air, i) => resultPointer.write(i, CTypeConversion.toCString(code).get())
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Without main native-image refuses to work
|
||||||
|
@static
|
||||||
|
def main(args: Array[String]): Unit = ()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user