From a12dcb262c959c8b64ff02908fba08c804b8113b Mon Sep 17 00:00:00 2001 From: Dario Valdespino Date: Mon, 27 Nov 2023 17:30:19 -0500 Subject: [PATCH] feat(cli): interactive java support. Signed-off-by: Dario Valdespino --- packages/cli/build.gradle.kts | 3 ++- .../kotlin/elide/tool/cli/GuestLanguage.kt | 11 +++++++++ .../tool/cli/cmd/repl/ToolShellCommand.kt | 24 +++++++++++-------- .../java/shell/GuestExecutionProvider.kt | 2 +- .../kotlin/elide/runtime/plugins/jvm/Jvm.kt | 5 +++- .../elide/runtime/plugins/jvm/JvmConfig.kt | 8 +++++++ 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/packages/cli/build.gradle.kts b/packages/cli/build.gradle.kts index 60cc41cc7e..f4d8e6a8e7 100644 --- a/packages/cli/build.gradle.kts +++ b/packages/cli/build.gradle.kts @@ -298,10 +298,11 @@ dependencies { } runtimeIf(enableEspresso, projects.packages.graalvmJvm) + runtimeIf(enableEspresso, projects.packages.graalvmJava) + runtimeIf(enableEspresso, projects.packages.graalvmKt) runtimeIf(enableLlvm, projects.packages.graalvmLlvm) runtimeIf(enablePython, projects.packages.graalvmPy) runtimeIf(enableRuby, projects.packages.graalvmRb) - runtimeIf(enableEspresso, projects.packages.graalvmKt) runtimeIf(enableWasm, projects.packages.graalvmWasm) api(libs.picocli) diff --git a/packages/cli/src/main/kotlin/elide/tool/cli/GuestLanguage.kt b/packages/cli/src/main/kotlin/elide/tool/cli/GuestLanguage.kt index 3b3388234e..d4f58a4464 100644 --- a/packages/cli/src/main/kotlin/elide/tool/cli/GuestLanguage.kt +++ b/packages/cli/src/main/kotlin/elide/tool/cli/GuestLanguage.kt @@ -69,6 +69,16 @@ enum class GuestLanguage ( formalName = "JVM", experimental = true, unimplemented = true, + extensions = listOf("class"), + mimeTypes = emptyList(), + ), + + /** Interactive nested Java. */ + JAVA ( + id = "java", + formalName = "JVM", + experimental = true, + unimplemented = true, extensions = listOf("java"), mimeTypes = emptyList(), ), @@ -139,6 +149,7 @@ enum class GuestLanguage ( // JVM extension guests KOTLIN.id -> KOTLIN + JAVA.id -> JAVA GROOVY.id -> GROOVY else -> null } diff --git a/packages/cli/src/main/kotlin/elide/tool/cli/cmd/repl/ToolShellCommand.kt b/packages/cli/src/main/kotlin/elide/tool/cli/cmd/repl/ToolShellCommand.kt index cb00979bf5..c70432f712 100644 --- a/packages/cli/src/main/kotlin/elide/tool/cli/cmd/repl/ToolShellCommand.kt +++ b/packages/cli/src/main/kotlin/elide/tool/cli/cmd/repl/ToolShellCommand.kt @@ -77,8 +77,6 @@ import elide.runtime.plugins.env.EnvConfig.EnvVar import elide.runtime.plugins.env.EnvConfig.EnvVariableSource.* import elide.runtime.plugins.env.environment import elide.runtime.plugins.js.JavaScript -import elide.runtime.plugins.jvm.Jvm -import elide.runtime.plugins.kotlin.Kotlin import elide.runtime.plugins.vfs.vfs import elide.tool.cli.* import elide.tool.cli.GuestLanguage.* @@ -1550,22 +1548,28 @@ import elide.tool.project.ProjectManager logging.debug("Configuring Python VM") installIntrinsics(intrinsics, GraalVMGuest.PYTHON, versionProp) } -// install(elide.runtime.plugins.ruby.Ruby) { -// logging.debug("Configuring Ruby VM") -// installIntrinsics(intrinsics, GraalVMGuest.RUBY, versionProp) -// } + install(elide.runtime.plugins.ruby.Ruby) { + logging.debug("Configuring Ruby VM") + installIntrinsics(intrinsics, GraalVMGuest.RUBY, versionProp) + } (language ?: LanguageSelector()).resolve().forEach { lang -> when (lang) { // Secondary Engines: JVM - JVM -> install(Jvm) { - logging.debug("Configuring JVM") - installIntrinsics(intrinsics, GraalVMGuest.JVM, versionProp) + JVM -> { + install(elide.runtime.plugins.jvm.Jvm) { + logging.debug("Configuring JVM") + multithreading = false + } + + install(elide.runtime.plugins.java.Java) { + logging.debug("Configuring Java") + } } GROOVY -> logging.warn("Groovy runtime plugin is not yet implemented") - KOTLIN -> install(Kotlin) { + KOTLIN -> install(elide.runtime.plugins.kotlin.Kotlin) { val classpathDir = workdir.cacheDirectory() .resolve("elide-kotlin-runtime") .absolutePath diff --git a/packages/graalvm-java/src/main/kotlin/elide/runtime/plugins/java/shell/GuestExecutionProvider.kt b/packages/graalvm-java/src/main/kotlin/elide/runtime/plugins/java/shell/GuestExecutionProvider.kt index 3e2bf5a86d..ce9b1b396b 100644 --- a/packages/graalvm-java/src/main/kotlin/elide/runtime/plugins/java/shell/GuestExecutionProvider.kt +++ b/packages/graalvm-java/src/main/kotlin/elide/runtime/plugins/java/shell/GuestExecutionProvider.kt @@ -52,7 +52,7 @@ import elide.runtime.plugins.jvm.interop.guestClass private val byteArray by context.guestClass("[B") // cached guest exception classes - private val executionControlException by context.spiClass("ExecutionControlException") + private val executionControlException by context.executionControlClass("ExecutionControlException") private val classInstallException by context.executionControlClass("ClassInstallException") private val notImplementedException by context.executionControlClass("NotImplementedException") private val engineTerminationException by context.executionControlClass("EngineTerminationException") diff --git a/packages/graalvm-jvm/src/main/kotlin/elide/runtime/plugins/jvm/Jvm.kt b/packages/graalvm-jvm/src/main/kotlin/elide/runtime/plugins/jvm/Jvm.kt index 12c7643089..0bbfc32a26 100644 --- a/packages/graalvm-jvm/src/main/kotlin/elide/runtime/plugins/jvm/Jvm.kt +++ b/packages/graalvm-jvm/src/main/kotlin/elide/runtime/plugins/jvm/Jvm.kt @@ -22,6 +22,7 @@ import elide.runtime.core.PolyglotContext import elide.runtime.core.PolyglotContextBuilder import elide.runtime.core.extensions.disableOptions import elide.runtime.core.extensions.enableOptions +import elide.runtime.core.extensions.setOption import elide.runtime.plugins.AbstractLanguagePlugin /** @@ -48,7 +49,6 @@ import elide.runtime.plugins.AbstractLanguagePlugin "java.CHA", "java.HotSwapAPI", "java.InlineMethodHandle", - "java.MultiThreaded", "java.Polyglot", "java.SoftExit", "java.SplitMethodHandles", @@ -62,6 +62,9 @@ import elide.runtime.plugins.AbstractLanguagePlugin // guest classpath builder.option("java.Classpath", config.collectClasspath()) + + // threading + builder.setOption("java.MultiThreaded", config.multithreading) } public companion object Plugin : AbstractLanguagePlugin() { diff --git a/packages/graalvm-jvm/src/main/kotlin/elide/runtime/plugins/jvm/JvmConfig.kt b/packages/graalvm-jvm/src/main/kotlin/elide/runtime/plugins/jvm/JvmConfig.kt index d7fdde81c0..0356a36ea0 100644 --- a/packages/graalvm-jvm/src/main/kotlin/elide/runtime/plugins/jvm/JvmConfig.kt +++ b/packages/graalvm-jvm/src/main/kotlin/elide/runtime/plugins/jvm/JvmConfig.kt @@ -28,6 +28,14 @@ import elide.runtime.plugins.AbstractLanguageConfig /** Collection of classpath entries passed to Espresso. */ private val classpathEntries: MutableList = mutableListOf() + /** + * Toggle support for multiple threads in the guest context. + * + * When using a context where [Jvm] is installed along other languages that don't support threading, this option + * should be disabled to avoid integration issues. + */ + public var multithreading: Boolean = true + /** Returns a string representation of the classpath to be used by the guest Espresso JVM. */ internal fun collectClasspath(): String { return classpathEntries.joinToString(CLASSPATH_ENTRY_SEPARATOR)