Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@
path = third_party/madler/zlib
url = [email protected]:madler/zlib.git
ignore = dirty

shallow = true
[submodule "graalvm"]
path = third_party/oracle/graalvm/graal
url = [email protected]:oracle/graal.git
shallow = true
[submodule "graaljs"]
path = third_party/oracle/graalvm/graaljs
url = [email protected]:elide-dev/graaljs.git
shallow = true
12 changes: 12 additions & 0 deletions packages/cli/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -1963,3 +1963,15 @@ listOf(
}
}
}

val (jsGroup, jsName) = libs.graalvm.js.language.get().let {
it.group to it.name
}
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(module("${jsGroup}:${jsName}")).apply {
using(project(":packages:graalvm-js"))
because("Uses Elide's patched version of GraalJs")
}
}
}
59 changes: 44 additions & 15 deletions packages/engine/api/engine.api
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,50 @@ public final class elide/runtime/gvm/cfg/LanguageDefaults {
public final fun getDEFAULT_TIMEZONE ()Ljava/time/ZoneId;
}

public abstract interface class elide/runtime/gvm/loader/ModuleFactory {
public abstract fun load (Lelide/runtime/gvm/loader/ModuleInfo;)Ljava/lang/Object;
}

public final class elide/runtime/gvm/loader/ModuleInfo : java/lang/Record, java/lang/Comparable {
public static final field Companion Lelide/runtime/gvm/loader/ModuleInfo$Companion;
public synthetic fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun compareTo (Lelide/runtime/gvm/loader/ModuleInfo;)I
public synthetic fun compareTo (Ljava/lang/Object;)I
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/util/List;
public final fun dependencies ()Ljava/util/List;
public fun equals (Ljava/lang/Object;)Z
public static final fun find (Ljava/lang/String;)Lelide/runtime/gvm/loader/ModuleInfo;
public fun hashCode ()I
public final fun name ()Ljava/lang/String;
public static final fun of (Ljava/lang/String;[Ljava/lang/String;)Lelide/runtime/gvm/loader/ModuleInfo;
public fun toString ()Ljava/lang/String;
}

public final class elide/runtime/gvm/loader/ModuleInfo$Companion {
public final fun find (Ljava/lang/String;)Lelide/runtime/gvm/loader/ModuleInfo;
public final fun getAllModuleInfos ()Ljava/util/Map;
public final fun of (Ljava/lang/String;[Ljava/lang/String;)Lelide/runtime/gvm/loader/ModuleInfo;
}

public abstract interface class elide/runtime/gvm/loader/ModuleRegistrar {
public abstract fun deferred (Lelide/runtime/gvm/loader/ModuleInfo;Lelide/runtime/gvm/loader/ModuleFactory;)V
public abstract fun register (Lelide/runtime/gvm/loader/ModuleInfo;Ljava/lang/Object;)V
}

public final class elide/runtime/gvm/loader/ModuleRegistry : elide/runtime/gvm/loader/ModuleRegistrar, elide/runtime/gvm/loader/ModuleResolver {
public static final field INSTANCE Lelide/runtime/gvm/loader/ModuleRegistry;
public fun contains (Lelide/runtime/gvm/loader/ModuleInfo;)Z
public fun deferred (Lelide/runtime/gvm/loader/ModuleInfo;Lelide/runtime/gvm/loader/ModuleFactory;)V
public fun load (Lelide/runtime/gvm/loader/ModuleInfo;)Ljava/lang/Object;
public fun register (Lelide/runtime/gvm/loader/ModuleInfo;Ljava/lang/Object;)V
}

public abstract interface class elide/runtime/gvm/loader/ModuleResolver {
public abstract fun contains (Lelide/runtime/gvm/loader/ModuleInfo;)Z
public abstract fun load (Lelide/runtime/gvm/loader/ModuleInfo;)Ljava/lang/Object;
}

public abstract class elide/runtime/plugins/AbstractLanguageConfig {
public static final field Companion Lelide/runtime/plugins/AbstractLanguageConfig$Companion;
public fun <init> ()V
Expand Down Expand Up @@ -467,21 +511,6 @@ public final class elide/runtime/plugins/AbstractLanguagePlugin$LanguagePluginMa
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public abstract class elide/runtime/plugins/api/NativePlugin : elide/runtime/plugins/api/NativePluginAPI {
protected fun <init> (Ljava/lang/String;)V
protected fun apply ([Ljava/lang/String;)V
public fun context (Lorg/graalvm/polyglot/Engine;Lorg/graalvm/polyglot/Context$Builder;[Ljava/lang/String;)V
public fun getPluginId ()Ljava/lang/String;
public fun init ()V
public static fun initialize (Lelide/runtime/plugins/api/NativePlugin;)Lorg/graalvm/polyglot/Context$Builder;
}

public abstract interface class elide/runtime/plugins/api/NativePluginAPI {
public abstract fun context (Lorg/graalvm/polyglot/Engine;Lorg/graalvm/polyglot/Context$Builder;[Ljava/lang/String;)V
public abstract fun getPluginId ()Ljava/lang/String;
public abstract fun init ()V
}

public final class elide/runtime/plugins/bindings/Bindings {
public static final field Plugin Lelide/runtime/plugins/bindings/Bindings$Plugin;
public synthetic fun <init> (Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under the License.
*/
package elide.runtime.ruby;
@file:OptIn(DelicateElideApi::class)

import elide.runtime.plugins.api.NativePlugin;
package elide.runtime.gvm.loader

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

ElideRubyLanguage() {
super(ELIDE_RUBY);
}
/**
* ## Module Factory
*
* A factory which creates an instance of a synthesized module; loaded from a [ModuleResolver].
*/
public fun interface ModuleFactory {
/**
* Load a module from a [ModuleInfo].
*
* @param module The module to load.
* @return The loaded module.
*/
public fun load(module: ModuleInfo): Any
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2024 Elide Technologies, Inc.
*
* Licensed under the MIT license (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://opensource.org/license/mit/
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under the License.
*/
package elide.runtime.gvm.loader

import java.util.concurrent.ConcurrentSkipListMap

/**
* Assigned string name/ID for a code module.
*/
public typealias ModuleId = String

/**
* ## Module Info
*
* Describes information about a code module of some kind; the module is addressed by a simple [name].
*
* @property name The name of the module.
* @property dependencies The list of module names that this module depends on.
*/
@ConsistentCopyVisibility
@JvmRecord public data class ModuleInfo private constructor (
public val name: ModuleId,
public val dependencies: List<ModuleId> = emptyList(),
) : Comparable<ModuleInfo> {
override fun compareTo(other: ModuleInfo): Int = name.compareTo(other.name)

public companion object {
public val allModuleInfos: MutableMap<ModuleId, ModuleInfo> = ConcurrentSkipListMap<ModuleId, ModuleInfo>()

// Register a module info record.
@JvmStatic private fun register(name: String, vararg deps: String): ModuleInfo {
assert(name !in allModuleInfos) { "Module $name already registered" }
return ModuleInfo(
name = name,
dependencies = deps.toList(),
).also {
allModuleInfos[name] = it
}
}

// Obtain a module info record, registering if needed.
@JvmStatic public fun of(name: String, vararg deps: String): ModuleInfo = allModuleInfos.computeIfAbsent(name) {
register(
name = name,
deps = deps,
)
}

// Obtain a module info record, or return `null` if not found.
@JvmStatic public fun find(name: String): ModuleInfo? = allModuleInfos[name]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2024 Elide Technologies, Inc.
*
* Licensed under the MIT license (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://opensource.org/license/mit/
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under the License.
*/
package elide.runtime.gvm.loader

/**
* ## Module Registry
*/
public interface ModuleRegistrar {
/**
* Register a module with the module registry.
*
* @param module The module to register.
* @param impl An instance of the registered module.
*/
public fun register(module: ModuleInfo, impl: Any)

/**
* Register a module with the module registry.
*
* @param module The module to register.
* @param producer The factory to create the module.
*/
public fun deferred(module: ModuleInfo, producer: ModuleFactory)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 Elide Technologies, Inc.
*
* Licensed under the MIT license (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://opensource.org/license/mit/
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under the License.
*/

package elide.runtime.gvm.loader

/**
* ## Module Registry
*/
public object ModuleRegistry : ModuleRegistrar, ModuleResolver {
private val registered = sortedMapOf<ModuleInfo, Any>()
private val factories = sortedMapOf<ModuleInfo, ModuleFactory>()

override fun register(module: ModuleInfo, impl: Any) {
assert(module !in registered) { "Module already registered: $module" }
assert(module !in factories) { "Module already registered as factory: $module" }
factories[module] = ModuleFactory { _ -> impl }
}

override fun deferred(module: ModuleInfo, producer: ModuleFactory) {
factories[module] = producer
}

override operator fun contains(mod: ModuleInfo): Boolean = mod in factories

override fun load(info: ModuleInfo): Any = when (info) {
in registered -> registered[info]!!
in factories -> factories[info]!!.let { fac ->
fac.load(info).also {
registered[info] = it
}
}
else -> error("Module not registered: $info")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,22 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under the License.
*/
package elide.runtime.plugins.api;
package elide.runtime.gvm.loader

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Engine;

/** TBD. */
public interface NativePluginAPI {
public String getPluginId();

public void context(Engine engine, Context.Builder builder, String[] args);
/**
* ## Module Resolver
*/
public interface ModuleResolver {
/**
* Resolve a module by request.
*/
public operator fun contains(mod: ModuleInfo): Boolean

public void init();
/**
* Load a module from its [ModuleInfo].
*
* @param info The module info.
* @return The module implementation; expected to be a polyglot value or proxy-type object.
*/
public fun load(info: ModuleInfo): Any
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import elide.runtime.core.PolyglotContext
*/
@DelicateElideApi public abstract class AbstractLanguageConfig {
public companion object {
private const val EXPERIMENTAL_SECURE_INTERNALS = true
private const val EXPERIMENTAL_SECURE_INTERNALS = false
}

/** Mutable counterpart to [intrinsicBindings]. */
Expand Down
Loading
Loading