Skip to content

Commit 264fbca

Browse files
committed
feat(graalvm): synthetic modules
feat(graalvm-js): add new `graalvm-js` module for graaljs integration feat(graalvm-js): initial structure and api for elide's import router feat(graalvm-ts): move js realm patcher to `graalvm-js` module feat(graalvm): initialize javascript when plugin is added chore: reintroduce graalvm/graaljs modules and pins Signed-off-by: Sam Gammon <sam@elide.dev>
1 parent 64d9c28 commit 264fbca

File tree

17 files changed

+182
-10
lines changed

17 files changed

+182
-10
lines changed

.gitmodules

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,12 @@
3131
path = third_party/madler/zlib
3232
url = git@github.com:madler/zlib.git
3333
ignore = dirty
34-
34+
shallow = true
35+
[submodule "graalvm"]
36+
path = third_party/oracle/graalvm/graal
37+
url = git@github.com:oracle/graal.git
38+
shallow = true
39+
[submodule "graaljs"]
40+
path = third_party/oracle/graalvm/graaljs
41+
url = git@github.com:elide-dev/graaljs.git
42+
shallow = true

packages/cli/build.gradle.kts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,3 +1963,15 @@ listOf(
19631963
}
19641964
}
19651965
}
1966+
1967+
val (jsGroup, jsName) = libs.graalvm.js.language.get().let {
1968+
it.group to it.name
1969+
}
1970+
configurations.all {
1971+
resolutionStrategy.dependencySubstitution {
1972+
substitute(module("${jsGroup}:${jsName}")).apply {
1973+
using(project(":packages:graalvm-js"))
1974+
because("Uses Elide's patched version of GraalJs")
1975+
}
1976+
}
1977+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public class elide/runtime/lang/javascript/JSRealmPatcher {
2+
public fun <init> ()V
3+
public static fun setModuleLoader (Lcom/oracle/truffle/js/runtime/JSRealm;Lcom/oracle/truffle/js/runtime/objects/JSModuleLoader;)V
4+
}
5+
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2024 Elide Technologies, Inc.
3+
*
4+
* Licensed under the MIT license (the "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
*
7+
* https://opensource.org/license/mit/
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11+
* License for the specific language governing permissions and limitations under the License.
12+
*/
13+
14+
import elide.internal.conventions.kotlin.KotlinTarget
15+
import elide.internal.conventions.publishing.publish
16+
17+
plugins {
18+
alias(libs.plugins.micronaut.graalvm)
19+
20+
kotlin("jvm")
21+
kotlin("kapt")
22+
kotlin("plugin.allopen")
23+
24+
alias(libs.plugins.elide.conventions)
25+
}
26+
27+
elide {
28+
publishing {
29+
id = "graalvm-js"
30+
name = "Elide JS integration package for GraalVM"
31+
description = "Integration package with GraalVM, Elide, and JS."
32+
33+
publish("jvm") {
34+
from(components["kotlin"])
35+
}
36+
}
37+
38+
kotlin {
39+
target = KotlinTarget.JVM
40+
explicitApi = true
41+
}
42+
}
43+
44+
val gvmJarsRoot = rootProject.layout.projectDirectory.dir("third_party/oracle")
45+
46+
val patchedLibs = files(
47+
gvmJarsRoot.file("graaljs.jar"),
48+
)
49+
50+
val patchedDependencies: Configuration by configurations.creating {
51+
isCanBeResolved = true
52+
}
53+
54+
dependencies {
55+
api(projects.packages.engine)
56+
api(patchedLibs)
57+
patchedDependencies(patchedLibs)
58+
}
59+
60+
configurations.all {
61+
libs.graalvm.js.language.get().let {
62+
exclude(group = it.group, module = it.name)
63+
}
64+
}

packages/graalvm-ts/src/main/java/elide/runtime/lang/typescript/JSRealmPatcher.java renamed to packages/graalvm-js/src/main/java/elide/runtime/lang/javascript/JSRealmPatcher.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 Elide Technologies, Inc.
2+
* Copyright (c) 2024-2025 Elide Technologies, Inc.
33
*
44
* Licensed under the MIT license (the "License"); you may not use this file except in compliance
55
* with the License. You may obtain a copy of the License at
@@ -10,18 +10,19 @@
1010
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1111
* License for the specific language governing permissions and limitations under the License.
1212
*/
13-
package elide.runtime.lang.typescript;
13+
package elide.runtime.lang.javascript;
1414

1515
import com.oracle.truffle.js.runtime.JSRealm;
16+
import com.oracle.truffle.js.runtime.objects.JSModuleLoader;
1617
import java.lang.reflect.Field;
1718

18-
class JSRealmPatcher {
19-
public static void setTSModuleLoader(JSRealm jsRealm, TypeScriptModuleLoader newModuleLoader) {
19+
public class JSRealmPatcher {
20+
public static void setModuleLoader(JSRealm jsRealm, JSModuleLoader newModuleLoader) {
2021
try {
2122
Field moduleLoaderField = JSRealm.class.getDeclaredField("moduleLoader");
2223
moduleLoaderField.setAccessible(true);
2324
Object moduleLoader = moduleLoaderField.get(jsRealm);
24-
if (!(moduleLoader instanceof TypeScriptModuleLoader)) {
25+
if (moduleLoader != newModuleLoader) {
2526
moduleLoaderField.set(jsRealm, newModuleLoader);
2627
}
2728
} catch (NoSuchFieldException | IllegalAccessException e) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package elide.runtime.lang.javascript
2+
3+
import com.oracle.truffle.js.runtime.JSEngine
4+
import com.oracle.truffle.js.runtime.JSModuleLoaderFactory
5+
import com.oracle.truffle.js.runtime.JSRealm
6+
import com.oracle.truffle.js.runtime.objects.JSModuleLoader
7+
import java.util.*
8+
import kotlinx.atomicfu.atomic
9+
10+
/**
11+
* ## Elide JavaScript Module Router
12+
*/
13+
public object ElideJsModuleRouter : JSModuleLoaderFactory {
14+
private val initialized = atomic(false)
15+
16+
@JvmStatic public fun install() {
17+
if (!initialized.getAndSet(true)) {
18+
JSEngine.setModuleLoaderFactory(this)
19+
}
20+
}
21+
22+
override fun createLoader(realm: JSRealm, defaultFactory: JSModuleLoaderFactory): Optional<JSModuleLoader> =
23+
defaultFactory.createLoader(
24+
realm,
25+
defaultFactory
26+
)
27+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package elide.runtime.lang.javascript
2+
3+
import kotlinx.atomicfu.atomic
4+
5+
/**
6+
* ## JavaScript Language Utilities
7+
*
8+
* Static utilities for internal engine use.
9+
*/
10+
public object JavaScriptLang {
11+
private val initialized = atomic(false)
12+
13+
public fun initialize() {
14+
if (initialized.compareAndSet(expect = false, update = true)) {
15+
ElideJsModuleRouter.install()
16+
}
17+
}
18+
}

packages/graalvm-ts/build.gradle.kts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,13 @@ elide {
4949
dependencies {
5050
kapt(libs.graalvm.truffle.processor)
5151
api(projects.packages.engine)
52+
api(projects.packages.graalvmJs)
53+
api(libs.graalvm.truffle.api)
5254
implementation(libs.commons.io)
5355
implementation(libs.kotlinx.coroutines.core)
5456
implementation(libs.graalvm.js.language)
57+
implementation(libs.graalvm.shadowed.icu4j)
58+
implementation(libs.graalvm.regex)
5559

5660
// Testing
5761
testImplementation(projects.packages.test)
@@ -71,3 +75,16 @@ tasks {
7175
systemProperty("elide.test", "true")
7276
}
7377
}
78+
79+
val (jsGroup, jsName) = libs.graalvm.js.language.get()
80+
.let {
81+
it.group to it.name
82+
}
83+
configurations.all {
84+
resolutionStrategy.dependencySubstitution {
85+
substitute(module("$jsGroup:$jsName")).apply {
86+
using(project(":packages:graalvm-js"))
87+
because("Uses Elide's patched version of GraalJs")
88+
}
89+
}
90+
}

packages/graalvm-ts/src/main/java/elide/runtime/lang/typescript/TypeScriptLanguage.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 Elide Technologies, Inc.
2+
* Copyright (c) 2024-2025 Elide Technologies, Inc.
33
*
44
* Licensed under the MIT license (the "License"); you may not use this file except in compliance
55
* with the License. You may obtain a copy of the License at
@@ -23,6 +23,7 @@
2323
import com.oracle.truffle.js.lang.JavaScriptLanguage;
2424
import com.oracle.truffle.js.runtime.JSEngine;
2525
import com.oracle.truffle.js.runtime.JSRealm;
26+
import elide.runtime.lang.javascript.JSRealmPatcher;
2627
import java.util.List;
2728
import java.util.concurrent.atomic.AtomicBoolean;
2829
import org.graalvm.polyglot.SandboxPolicy;
@@ -84,7 +85,7 @@ protected JSRealm createContext(Env currentEnv) {
8485
}
8586
var ctx = JSEngine.createJSContext(js, jsEnv);
8687
var realm = ctx.createRealm(jsEnv);
87-
JSRealmPatcher.setTSModuleLoader(realm, new TypeScriptModuleLoader(realm, tsCompiler));
88+
JSRealmPatcher.setModuleLoader(realm, new TypeScriptModuleLoader(realm, tsCompiler));
8889
return realm;
8990
}
9091

@@ -118,7 +119,7 @@ protected TSRootNode(TruffleLanguage<?> language, RootNode delegate) {
118119
@TruffleBoundary
119120
private void setModuleLoader() {
120121
JSRealm realm = JSRealm.get(delegate);
121-
JSRealmPatcher.setTSModuleLoader(realm, new TypeScriptModuleLoader(realm, tsCompiler));
122+
JSRealmPatcher.setModuleLoader(realm, new TypeScriptModuleLoader(realm, tsCompiler));
122123
}
123124

124125
@Override

packages/graalvm/build.gradle.kts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,3 +669,15 @@ if (enableBenchmarks) afterEvaluate {
669669
}.toString())
670670
}
671671
}
672+
673+
val (jsGroup, jsName) = libs.graalvm.js.language.get().let {
674+
it.group to it.name
675+
}
676+
configurations.all {
677+
resolutionStrategy.dependencySubstitution {
678+
substitute(module("${jsGroup}:${jsName}")).apply {
679+
using(project(":packages:graalvm-js"))
680+
because("Uses Elide's patched version of GraalJs")
681+
}
682+
}
683+
}

0 commit comments

Comments
 (0)