Skip to content

Commit 97ba819

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-js): implement commonjs module loading support feat(graalvm-js): implement esm module loading support feat(graalvm-ts): move js realm patcher to `graalvm-js` module feat(graalvm-ts): use new delegated module facilities feat(graalvm): initialize javascript when plugin is added feat(graalvm): enable `node:assert` for injection feat(graalvm): enable `node:path` for injection feat(graalvm): enable `node:zlib` for injection feat(graalvm): enable `node:os` for injection chore: reintroduce graalvm/graaljs modules and pins chore: mark js realm patcher as deprecated test: add test scripts for node paths Signed-off-by: Sam Gammon <[email protected]>
1 parent 64d9c28 commit 97ba819

File tree

55 files changed

+2017
-310
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2017
-310
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 = [email protected]:madler/zlib.git
3333
ignore = dirty
34-
34+
shallow = true
35+
[submodule "graalvm"]
36+
path = third_party/oracle/graalvm/graal
37+
url = [email protected]:oracle/graal.git
38+
shallow = true
39+
[submodule "graaljs"]
40+
path = third_party/oracle/graalvm/graaljs
41+
url = [email protected]: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+
}

packages/engine/api/engine.api

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,50 @@ public final class elide/runtime/gvm/cfg/LanguageDefaults {
366366
public final fun getDEFAULT_TIMEZONE ()Ljava/time/ZoneId;
367367
}
368368

369+
public abstract interface class elide/runtime/gvm/loader/ModuleFactory {
370+
public abstract fun load (Lelide/runtime/gvm/loader/ModuleInfo;)Ljava/lang/Object;
371+
}
372+
373+
public final class elide/runtime/gvm/loader/ModuleInfo : java/lang/Record, java/lang/Comparable {
374+
public static final field Companion Lelide/runtime/gvm/loader/ModuleInfo$Companion;
375+
public synthetic fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
376+
public fun compareTo (Lelide/runtime/gvm/loader/ModuleInfo;)I
377+
public synthetic fun compareTo (Ljava/lang/Object;)I
378+
public final fun component1 ()Ljava/lang/String;
379+
public final fun component2 ()Ljava/util/List;
380+
public final fun dependencies ()Ljava/util/List;
381+
public fun equals (Ljava/lang/Object;)Z
382+
public static final fun find (Ljava/lang/String;)Lelide/runtime/gvm/loader/ModuleInfo;
383+
public fun hashCode ()I
384+
public final fun name ()Ljava/lang/String;
385+
public static final fun of (Ljava/lang/String;[Ljava/lang/String;)Lelide/runtime/gvm/loader/ModuleInfo;
386+
public fun toString ()Ljava/lang/String;
387+
}
388+
389+
public final class elide/runtime/gvm/loader/ModuleInfo$Companion {
390+
public final fun find (Ljava/lang/String;)Lelide/runtime/gvm/loader/ModuleInfo;
391+
public final fun getAllModuleInfos ()Ljava/util/Map;
392+
public final fun of (Ljava/lang/String;[Ljava/lang/String;)Lelide/runtime/gvm/loader/ModuleInfo;
393+
}
394+
395+
public abstract interface class elide/runtime/gvm/loader/ModuleRegistrar {
396+
public abstract fun deferred (Lelide/runtime/gvm/loader/ModuleInfo;Lelide/runtime/gvm/loader/ModuleFactory;)V
397+
public abstract fun register (Lelide/runtime/gvm/loader/ModuleInfo;Ljava/lang/Object;)V
398+
}
399+
400+
public final class elide/runtime/gvm/loader/ModuleRegistry : elide/runtime/gvm/loader/ModuleRegistrar, elide/runtime/gvm/loader/ModuleResolver {
401+
public static final field INSTANCE Lelide/runtime/gvm/loader/ModuleRegistry;
402+
public fun contains (Lelide/runtime/gvm/loader/ModuleInfo;)Z
403+
public fun deferred (Lelide/runtime/gvm/loader/ModuleInfo;Lelide/runtime/gvm/loader/ModuleFactory;)V
404+
public fun load (Lelide/runtime/gvm/loader/ModuleInfo;)Ljava/lang/Object;
405+
public fun register (Lelide/runtime/gvm/loader/ModuleInfo;Ljava/lang/Object;)V
406+
}
407+
408+
public abstract interface class elide/runtime/gvm/loader/ModuleResolver {
409+
public abstract fun contains (Lelide/runtime/gvm/loader/ModuleInfo;)Z
410+
public abstract fun load (Lelide/runtime/gvm/loader/ModuleInfo;)Ljava/lang/Object;
411+
}
412+
369413
public abstract class elide/runtime/plugins/AbstractLanguageConfig {
370414
public static final field Companion Lelide/runtime/plugins/AbstractLanguageConfig$Companion;
371415
public fun <init> ()V
@@ -467,21 +511,6 @@ public final class elide/runtime/plugins/AbstractLanguagePlugin$LanguagePluginMa
467511
public final fun serializer ()Lkotlinx/serialization/KSerializer;
468512
}
469513

470-
public abstract class elide/runtime/plugins/api/NativePlugin : elide/runtime/plugins/api/NativePluginAPI {
471-
protected fun <init> (Ljava/lang/String;)V
472-
protected fun apply ([Ljava/lang/String;)V
473-
public fun context (Lorg/graalvm/polyglot/Engine;Lorg/graalvm/polyglot/Context$Builder;[Ljava/lang/String;)V
474-
public fun getPluginId ()Ljava/lang/String;
475-
public fun init ()V
476-
public static fun initialize (Lelide/runtime/plugins/api/NativePlugin;)Lorg/graalvm/polyglot/Context$Builder;
477-
}
478-
479-
public abstract interface class elide/runtime/plugins/api/NativePluginAPI {
480-
public abstract fun context (Lorg/graalvm/polyglot/Engine;Lorg/graalvm/polyglot/Context$Builder;[Ljava/lang/String;)V
481-
public abstract fun getPluginId ()Ljava/lang/String;
482-
public abstract fun init ()V
483-
}
484-
485514
public final class elide/runtime/plugins/bindings/Bindings {
486515
public static final field Plugin Lelide/runtime/plugins/bindings/Bindings$Plugin;
487516
public synthetic fun <init> (Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V

packages/engine/src/main/java/elide/runtime/plugins/api/NativePlugin.java

Lines changed: 0 additions & 55 deletions
This file was deleted.

packages/graalvm-rb/src/main/java/elide/runtime/ruby/ElideRubyLanguage.java renamed to packages/engine/src/main/kotlin/elide/runtime/gvm/loader/ModuleFactory.kt

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,23 @@
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.ruby;
13+
@file:OptIn(DelicateElideApi::class)
1414

15-
import elide.runtime.plugins.api.NativePlugin;
15+
package elide.runtime.gvm.loader
1616

17-
/** TBD. */
18-
public class ElideRubyLanguage extends NativePlugin {
19-
private static final String ELIDE_RUBY = "ruby";
17+
import elide.runtime.core.DelicateElideApi
2018

21-
ElideRubyLanguage() {
22-
super(ELIDE_RUBY);
23-
}
19+
/**
20+
* ## Module Factory
21+
*
22+
* A factory which creates an instance of a synthesized module; loaded from a [ModuleResolver].
23+
*/
24+
public fun interface ModuleFactory {
25+
/**
26+
* Load a module from a [ModuleInfo].
27+
*
28+
* @param module The module to load.
29+
* @return The loaded module.
30+
*/
31+
public fun load(module: ModuleInfo): Any
2432
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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+
package elide.runtime.gvm.loader
14+
15+
import java.util.concurrent.ConcurrentSkipListMap
16+
17+
/**
18+
* Assigned string name/ID for a code module.
19+
*/
20+
public typealias ModuleId = String
21+
22+
/**
23+
* ## Module Info
24+
*
25+
* Describes information about a code module of some kind; the module is addressed by a simple [name].
26+
*
27+
* @property name The name of the module.
28+
* @property dependencies The list of module names that this module depends on.
29+
*/
30+
@ConsistentCopyVisibility
31+
@JvmRecord public data class ModuleInfo private constructor (
32+
public val name: ModuleId,
33+
public val dependencies: List<ModuleId> = emptyList(),
34+
) : Comparable<ModuleInfo> {
35+
override fun compareTo(other: ModuleInfo): Int = name.compareTo(other.name)
36+
37+
public companion object {
38+
public val allModuleInfos: MutableMap<ModuleId, ModuleInfo> = ConcurrentSkipListMap<ModuleId, ModuleInfo>()
39+
40+
// Register a module info record.
41+
@JvmStatic private fun register(name: String, vararg deps: String): ModuleInfo {
42+
assert(name !in allModuleInfos) { "Module $name already registered" }
43+
return ModuleInfo(
44+
name = name,
45+
dependencies = deps.toList(),
46+
).also {
47+
allModuleInfos[name] = it
48+
}
49+
}
50+
51+
// Obtain a module info record, registering if needed.
52+
@JvmStatic public fun of(name: String, vararg deps: String): ModuleInfo = allModuleInfos.computeIfAbsent(name) {
53+
register(
54+
name = name,
55+
deps = deps,
56+
)
57+
}
58+
59+
// Obtain a module info record, or return `null` if not found.
60+
@JvmStatic public fun find(name: String): ModuleInfo? = allModuleInfos[name]
61+
}
62+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
package elide.runtime.gvm.loader
14+
15+
/**
16+
* ## Module Registry
17+
*/
18+
public interface ModuleRegistrar {
19+
/**
20+
* Register a module with the module registry.
21+
*
22+
* @param module The module to register.
23+
* @param impl An instance of the registered module.
24+
*/
25+
public fun register(module: ModuleInfo, impl: Any)
26+
27+
/**
28+
* Register a module with the module registry.
29+
*
30+
* @param module The module to register.
31+
* @param producer The factory to create the module.
32+
*/
33+
public fun deferred(module: ModuleInfo, producer: ModuleFactory)
34+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
package elide.runtime.gvm.loader
15+
16+
/**
17+
* ## Module Registry
18+
*/
19+
public object ModuleRegistry : ModuleRegistrar, ModuleResolver {
20+
private val registered = sortedMapOf<ModuleInfo, Any>()
21+
private val factories = sortedMapOf<ModuleInfo, ModuleFactory>()
22+
23+
override fun register(module: ModuleInfo, impl: Any) {
24+
assert(module !in registered) { "Module already registered: $module" }
25+
assert(module !in factories) { "Module already registered as factory: $module" }
26+
factories[module] = ModuleFactory { _ -> impl }
27+
}
28+
29+
override fun deferred(module: ModuleInfo, producer: ModuleFactory) {
30+
factories[module] = producer
31+
}
32+
33+
override operator fun contains(mod: ModuleInfo): Boolean = mod in factories
34+
35+
override fun load(info: ModuleInfo): Any = when (info) {
36+
in registered -> registered[info]!!
37+
in factories -> factories[info]!!.let { fac ->
38+
fac.load(info).also {
39+
registered[info] = it
40+
}
41+
}
42+
else -> error("Module not registered: $info")
43+
}
44+
}

packages/engine/src/main/java/elide/runtime/plugins/api/NativePluginAPI.java renamed to packages/engine/src/main/kotlin/elide/runtime/gvm/loader/ModuleResolver.kt

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,22 @@
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.plugins.api;
13+
package elide.runtime.gvm.loader
1414

15-
import org.graalvm.polyglot.Context;
16-
import org.graalvm.polyglot.Engine;
17-
18-
/** TBD. */
19-
public interface NativePluginAPI {
20-
public String getPluginId();
21-
22-
public void context(Engine engine, Context.Builder builder, String[] args);
15+
/**
16+
* ## Module Resolver
17+
*/
18+
public interface ModuleResolver {
19+
/**
20+
* Resolve a module by request.
21+
*/
22+
public operator fun contains(mod: ModuleInfo): Boolean
2323

24-
public void init();
24+
/**
25+
* Load a module from its [ModuleInfo].
26+
*
27+
* @param info The module info.
28+
* @return The module implementation; expected to be a polyglot value or proxy-type object.
29+
*/
30+
public fun load(info: ModuleInfo): Any
2531
}

packages/engine/src/main/kotlin/elide/runtime/plugins/AbstractLanguageConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import elide.runtime.core.PolyglotContext
2727
*/
2828
@DelicateElideApi public abstract class AbstractLanguageConfig {
2929
public companion object {
30-
private const val EXPERIMENTAL_SECURE_INTERNALS = true
30+
private const val EXPERIMENTAL_SECURE_INTERNALS = false
3131
}
3232

3333
/** Mutable counterpart to [intrinsicBindings]. */

0 commit comments

Comments
 (0)