Skip to content

Commit

Permalink
fix: package of fixes for main Elide object
Browse files Browse the repository at this point in the history
- fix: native library init
- fix: deprecate native `TypeError` object
- fix: use of `ValueError` as native host object
- fix: use of entrypoint `facade.js`
- fix: typescript engine detection
- fix: initialization of cli args
- fix: server engine symbol at `Elide.http`
- fix: adopt buffer symbols properly
- fix: native kqueue server
- chore: update facade js
- chore: update `runtime` module
- chore: update `gvm` module
- chore: update `@types/node`

Signed-off-by: Sam Gammon <[email protected]>
  • Loading branch information
sgammon committed Jun 23, 2024
1 parent eeb53ca commit 0f0b3c0
Show file tree
Hide file tree
Showing 30 changed files with 321 additions and 144 deletions.
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"@mdx-js/esbuild": "3.0.1",
"@prettier/plugin-xml": "3.4.1",
"@types/google-protobuf": "3.15.12",
"@types/node": "20.14.5",
"@types/node": "20.14.6",
"@typescript-eslint/eslint-plugin": "7.13.1",
"@typescript-eslint/parser": "7.13.1",
"commitlint": "19.3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,17 +194,19 @@ import elide.runtime.plugins.bindings.Bindings
val script = AbstractLanguagePlugin::class.java.getResourceAsStream(source.path)
?: error("Failed to load embedded resource: $source")

context.evaluate(
this,
script.bufferedReader().use { it.readText() },
name = source.path.split("/").last(),
internals = true,
cached = true,
)
}
} catch (err: RuntimeException) {
if (System.getProperty("elide.strict") == "true") {
throw IllegalStateException("Embedded init evaluation failed. This is a bug in Elide.", err)
try {
context.evaluate(
this,
script.bufferedReader().use { it.readText() },
name = source.path.split("/").last(),
internals = true,
cached = true,
)
} catch (err: RuntimeException) {
if (System.getProperty("elide.strict") == "true") {
throw IllegalStateException("Embedded init evaluation failed. This is a bug in Elide.", err)
}
}
}
} finally {
context.leave()
Expand Down
37 changes: 25 additions & 12 deletions packages/graalvm/api/graalvm.api
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,17 @@ public synthetic class elide/runtime/gvm/internals/intrinsics/$BuiltinIntrinsics
public fun load ()Lio/micronaut/inject/BeanDefinition;
}

public synthetic class elide/runtime/gvm/internals/intrinsics/$ElideIntrinsic$Definition : io/micronaut/context/AbstractInitializableBeanDefinitionAndReference {
public static final field $ANNOTATION_METADATA Lio/micronaut/core/annotation/AnnotationMetadata;
public fun <init> ()V
protected fun <init> (Ljava/lang/Class;Lio/micronaut/context/AbstractInitializableBeanDefinition$MethodOrFieldReference;)V
public fun inject (Lio/micronaut/context/BeanResolutionContext;Lio/micronaut/context/BeanContext;Ljava/lang/Object;)Ljava/lang/Object;
public fun instantiate (Lio/micronaut/context/BeanResolutionContext;Lio/micronaut/context/BeanContext;)Ljava/lang/Object;
public fun isEnabled (Lio/micronaut/context/BeanContext;)Z
public fun isEnabled (Lio/micronaut/context/BeanContext;Lio/micronaut/context/BeanResolutionContext;)Z
public fun load ()Lio/micronaut/inject/BeanDefinition;
}

public synthetic class elide/runtime/gvm/internals/intrinsics/$ServiceIntrinsicsResolver$Definition : io/micronaut/context/AbstractInitializableBeanDefinitionAndReference {
public static final field $ANNOTATION_METADATA Lio/micronaut/core/annotation/AnnotationMetadata;
public fun <init> ()V
Expand All @@ -517,6 +528,15 @@ public synthetic class elide/runtime/gvm/internals/intrinsics/$ServiceIntrinsics
public fun load ()Lio/micronaut/inject/BeanDefinition;
}

public abstract interface class elide/runtime/gvm/internals/intrinsics/ElideAPI {
public abstract fun getProcess ()Lelide/runtime/intrinsics/js/node/ProcessAPI;
public abstract fun getVersion ()Ljava/lang/String;
}

public final class elide/runtime/gvm/internals/intrinsics/ElideIntrinsicKt {
public static final fun installElideBuiltin (Ljava/lang/String;Ljava/lang/Object;)V
}

public final class elide/runtime/gvm/internals/intrinsics/js/JsProxy {
public static final field INSTANCE Lelide/runtime/gvm/internals/intrinsics/js/JsProxy;
public final fun build (Lkotlin/jvm/functions/Function1;)Lorg/graalvm/polyglot/proxy/ProxyObject;
Expand Down Expand Up @@ -2628,17 +2648,6 @@ public abstract interface class elide/runtime/intrinsics/js/URLSearchParams : el
public abstract fun sort ()V
}

public synthetic class elide/runtime/intrinsics/js/err/$TypeErrorIntrinsic$Definition : io/micronaut/context/AbstractInitializableBeanDefinitionAndReference {
public static final field $ANNOTATION_METADATA Lio/micronaut/core/annotation/AnnotationMetadata;
public fun <init> ()V
protected fun <init> (Ljava/lang/Class;Lio/micronaut/context/AbstractInitializableBeanDefinition$MethodOrFieldReference;)V
public fun inject (Lio/micronaut/context/BeanResolutionContext;Lio/micronaut/context/BeanContext;Ljava/lang/Object;)Ljava/lang/Object;
public fun instantiate (Lio/micronaut/context/BeanResolutionContext;Lio/micronaut/context/BeanContext;)Ljava/lang/Object;
public fun isEnabled (Lio/micronaut/context/BeanContext;)Z
public fun isEnabled (Lio/micronaut/context/BeanContext;Lio/micronaut/context/BeanResolutionContext;)Z
public fun load ()Lio/micronaut/inject/BeanDefinition;
}

public synthetic class elide/runtime/intrinsics/js/err/$ValueErrorIntrinsic$Definition : io/micronaut/context/AbstractInitializableBeanDefinitionAndReference {
public static final field $ANNOTATION_METADATA Lio/micronaut/core/annotation/AnnotationMetadata;
public fun <init> ()V
Expand Down Expand Up @@ -2707,8 +2716,10 @@ public abstract interface class elide/runtime/intrinsics/js/err/Stacktrace {

public class elide/runtime/intrinsics/js/err/TypeError : elide/runtime/intrinsics/js/err/Error, elide/runtime/intrinsics/js/err/AbstractJsException, org/graalvm/polyglot/proxy/ProxyObject {
public static final field Factory Lelide/runtime/intrinsics/js/err/TypeError$Factory;
public fun <init> ()V
public fun <init> (Ljava/lang/String;)V
protected fun <init> (Ljava/lang/String;Lelide/runtime/intrinsics/js/err/Error;)V
public synthetic fun <init> (Ljava/lang/String;Lelide/runtime/intrinsics/js/err/Error;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lorg/graalvm/polyglot/Value;)V
public fun getCause ()Lelide/runtime/intrinsics/js/err/Error;
public synthetic fun getCause ()Ljava/lang/Throwable;
public fun getMember (Ljava/lang/String;)Ljava/lang/Object;
Expand All @@ -2731,8 +2742,10 @@ public final class elide/runtime/intrinsics/js/err/TypeError$Factory : elide/run

public class elide/runtime/intrinsics/js/err/ValueError : elide/runtime/intrinsics/js/err/Error, elide/runtime/intrinsics/js/err/AbstractJsException, org/graalvm/polyglot/proxy/ProxyObject {
public static final field Factory Lelide/runtime/intrinsics/js/err/ValueError$Factory;
public fun <init> ()V
protected fun <init> (Ljava/lang/String;Lelide/runtime/intrinsics/js/err/Error;)V
public synthetic fun <init> (Ljava/lang/String;Lelide/runtime/intrinsics/js/err/Error;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lorg/graalvm/polyglot/Value;)V
public fun getCause ()Lelide/runtime/intrinsics/js/err/Error;
public synthetic fun getCause ()Ljava/lang/Throwable;
public fun getMember (Ljava/lang/String;)Ljava/lang/Object;
Expand Down
2 changes: 2 additions & 0 deletions packages/graalvm/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<ID>ForbiddenComment:NodePathTest.kt$NodePathTest$// @TODO: adopting `ProxyObject` means this object will no longer show up as a host object.</ID>
<ID>ForbiddenComment:NodePathTest.kt$NodePathTest$// @TODO: this was the first use of the `assert` module; the order of expected/actual args is probably wrong</ID>
<ID>ForbiddenComment:NodePathTest.kt$NodePathTest$// @TODO: this will need normalization for non-unix test runs</ID>
<ID>ForbiddenComment:TypeError.kt$// @TODO: deprecate and replace with type mapping</ID>
<ID>ImplicitDefaultLocale:NodeOperatingSystem.kt$NodeOperatingSystem.BaseOS$String.format( "%d.%d.%d.%d", (bits and 0x0000000000ff000000L) shr 24, (bits and 0x0000000000ff0000L) shr 16, (bits and 0x0000000000ff00L) shr 8, bits and 0xffL, )</ID>
<ID>IteratorNotThrowingNoSuchElementException:FetchHeadersIntrinsic.kt$FetchHeadersIntrinsic$&lt;no name provided> : Iterator</ID>
<ID>IteratorNotThrowingNoSuchElementException:JsIterator.kt$JsIterator&lt;T> : IteratorProxyIteratorProxyIterable</ID>
Expand Down Expand Up @@ -138,6 +139,7 @@
<ID>UnusedParameter:SqliteQueryRenderer.kt$SqliteQueryRenderer$soFar: Int = -1</ID>
<ID>UnusedParameter:SqliteQueryRenderer.kt$SqliteQueryRenderer$subject: String</ID>
<ID>UnusedParameter:VfsPlugin.kt$Vfs$@Suppress("unused_parameter") builder: PolyglotEngineBuilder</ID>
<ID>UnusedPrivateMember:HttpServerAgent.kt$HttpServerAgent.Companion$private fun resolveLanguage(source: Source): GuestLanguage</ID>
<ID>UnusedPrivateProperty:AbstractJsIntrinsicTest.kt$AbstractJsIntrinsicTest$private val testInject: Boolean = true</ID>
<ID>UnusedPrivateProperty:NativeTransportFeature.kt$NativeTransportFeature.Companion$private val iouringImpls = arrayOf( "io.netty.incubator.channel.uring.Native", "io.netty.incubator.channel.uring.LinuxSocket", "io.netty.incubator.channel.uring.NativeStaticallyReferencedJniMethods", )</ID>
</CurrentIssues>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import org.graalvm.polyglot.HostAccess as PolyglotHostAccess
/** Create a new [GraalVMContext], triggering lifecycle events to allow customization. */
private fun createContext(cfg: Builder.() -> Unit, finalizer: Builder.() -> Context = { build() }): GraalVMContext {
val contextHostAccess = PolyglotHostAccess.newBuilder(PolyglotHostAccess.ALL)
.allowImplementations(Proxy::class.java)
.allowImplementationsAnnotatedBy(PolyglotHostAccess.Implementable::class.java)
.allowAccessAnnotatedBy(PolyglotHostAccess.Export::class.java)
.allowArrayAccess(true)
.allowBufferAccess(true)
Expand Down Expand Up @@ -221,6 +221,9 @@ import org.graalvm.polyglot.HostAccess as PolyglotHostAccess
/** Whether internal symbols should be withheld from guest code. */
private val shouldDropInternals = System.getProperty("elide.internals") != "true"

/** Whether to enable output/input stream access by guest languages (by default). */
private val enableStreams = System.getProperty("elide.js.vm.enableStreams", "false")

/** Whether the runtime is built as a native image. */
private val isNativeImage = ImageInfo.inImageCode()

Expand Down Expand Up @@ -252,7 +255,7 @@ import org.graalvm.polyglot.HostAccess as PolyglotHostAccess
allowExperimentalOptions(true)

// stub streams
if (System.getProperty("elide.js.vm.enableStreams", "false") != "true") {
if (enableStreams != "true") {
`in`(StubbedInputStream)
out(StubbedOutputStream)
err(StubbedOutputStream)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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.internals.intrinsics

import elide.annotations.API
import elide.runtime.intrinsics.js.node.ProcessAPI
import elide.vm.annotations.Polyglot

/**
* # Elide API
*/
@API public interface ElideAPI {
/**
*
*/
@get:Polyglot public val process: ProcessAPI

/**
*
*/
@get:Polyglot public val version: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* 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.
*/
@file:OptIn(DelicateElideApi::class)

package elide.runtime.gvm.internals.intrinsics

import org.graalvm.polyglot.Value
import org.graalvm.polyglot.proxy.ProxyObject
import java.util.LinkedList
import elide.annotations.Singleton
import elide.runtime.core.DelicateElideApi
import elide.runtime.gvm.GuestLanguage
import elide.runtime.gvm.internals.intrinsics.js.AbstractJsIntrinsic
import elide.runtime.gvm.internals.intrinsics.js.JsSymbol.JsSymbols.asPublicJsSymbol
import elide.runtime.gvm.internals.node.process.NodeProcess
import elide.runtime.intrinsics.GuestIntrinsic.MutableIntrinsicBindings
import elide.runtime.intrinsics.js.node.ProcessAPI
import elide.vm.annotations.Polyglot

// Symbol where the main Elide API is installed for guest use.
private const val ELIDE_SYMBOL = "Elide"

// Stubbed version of Elide.
private const val ELIDE_VERSION_STUBBED = "stubbed"

// Properties and methods made available for guest use.
private val BASE_ELIDE_PROPS_AND_METHODS = arrayOf(
"process",
"version",
)

public fun installElideBuiltin(name: String, value: Any) {
ElideIntrinsic.install(name, value)
}

@Intrinsic(ELIDE_SYMBOL, internal = false) @Singleton internal class ElideIntrinsic :
ElideAPI,
ProxyObject,
AbstractJsIntrinsic() {
companion object {
private val SINGLETON = ElideIntrinsic()

internal fun install(name: String, value: Any) {
SINGLETON.install(name, value)
}
}

// All properties and methods for guest use, including deferred properties.
private val deferredPropsAndMethods = LinkedList<String>()

// Mapped property values for deferred properties
private val mappedDeferredValue = HashMap<String, Any>()

override fun install(bindings: MutableIntrinsicBindings) {
bindings[ELIDE_SYMBOL.asPublicJsSymbol()] = SINGLETON
}

internal fun install(name: String, value: Any) {
deferredPropsAndMethods.add(name)
mappedDeferredValue[name] = value
}

override fun supports(language: GuestLanguage): Boolean = language.engine == "js"

@get:Polyglot override val process: ProcessAPI get() = NodeProcess.obtain()
@get:Polyglot override val version: String get() = ELIDE_VERSION_STUBBED

override fun getMemberKeys(): Array<String> = BASE_ELIDE_PROPS_AND_METHODS + deferredPropsAndMethods.toTypedArray()
override fun hasMember(key: String?): Boolean = key in BASE_ELIDE_PROPS_AND_METHODS || key in deferredPropsAndMethods

override fun putMember(key: String?, value: Value?) {
// no-op from guest code
}

override fun getMember(key: String?): Any? = when (key) {
"process" -> process
"version" -> version
else -> mappedDeferredValue[key]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import elide.runtime.core.DelicateElideApi
import elide.runtime.gvm.internals.intrinsics.Intrinsic
import elide.runtime.gvm.internals.intrinsics.js.AbstractNodeBuiltinModule
import elide.runtime.gvm.internals.intrinsics.js.JsSymbol.JsSymbols.asJsSymbol
import elide.runtime.gvm.internals.intrinsics.js.JsSymbol.JsSymbols.asPublicJsSymbol
import elide.runtime.intrinsics.GuestIntrinsic.MutableIntrinsicBindings
import elide.runtime.intrinsics.js.node.BufferAPI

Expand All @@ -32,10 +33,10 @@ private const val BUFFER_MODULE_SYMBOL_ROOT = "node_buffer"
private const val BUFFER_MODULE_SYMBOL = "${BUFFER_MODULE_SYMBOL_ROOT}_module"

/** Symbol at which the [NodeBlob] class is installed. */
private const val BLOB_SYMBOL = "${BUFFER_MODULE_SYMBOL_ROOT}_Blob"
private const val BLOB_SYMBOL = "Blob"

/** Symbol at which the [NodeBlob] class is installed. */
private const val FILE_SYMBOL = "${BUFFER_MODULE_SYMBOL_ROOT}_File"
private const val FILE_SYMBOL = "File"

// Installs the Node `buffer` built-in module.
@Intrinsic internal class NodeBufferModule : AbstractNodeBuiltinModule() {
Expand All @@ -44,8 +45,8 @@ private const val FILE_SYMBOL = "${BUFFER_MODULE_SYMBOL_ROOT}_File"
@OptIn(DelicateElideApi::class)
override fun install(bindings: MutableIntrinsicBindings) {
bindings[BUFFER_MODULE_SYMBOL.asJsSymbol()] = facade
bindings[BLOB_SYMBOL.asJsSymbol()] = NodeBlob::class.java
bindings[FILE_SYMBOL.asJsSymbol()] = NodeFile::class.java
bindings[BLOB_SYMBOL.asPublicJsSymbol()] = NodeBlob::class.java
bindings[FILE_SYMBOL.asPublicJsSymbol()] = NodeFile::class.java
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,22 @@ import org.graalvm.polyglot.proxy.ProxyInstantiable
import org.graalvm.polyglot.proxy.ProxyObject
import java.io.PrintWriter
import java.io.StringWriter
import elide.annotations.Singleton
import elide.runtime.core.DelicateElideApi
import elide.runtime.gvm.internals.intrinsics.Intrinsic
import elide.runtime.gvm.internals.intrinsics.js.AbstractJsIntrinsic
import elide.runtime.gvm.internals.intrinsics.js.JsSymbol.JsSymbols.asPublicJsSymbol
import elide.runtime.intrinsics.GuestIntrinsic.MutableIntrinsicBindings
import elide.vm.annotations.Polyglot

// Public symbol for a `TypeError`.
private const val TYPE_ERROR_SYMBOL = "NativeTypeError"

// Members and properties of a `TypeError`.
private val TYPE_ERROR_MEMBERS_AND_PROPS = arrayOf(
"name",
"message",
"stack",
)

// @TODO: deprecate and replace with type mapping
// Installs `TypeError` into the environment.
@Intrinsic @Singleton internal class TypeErrorIntrinsic : AbstractJsIntrinsic() {
@OptIn(DelicateElideApi::class)
override fun install(bindings: MutableIntrinsicBindings) {
bindings[TYPE_ERROR_SYMBOL.asPublicJsSymbol()] = TypeError.Factory
}
}
//@Intrinsic @Singleton internal class TypeErrorIntrinsic : AbstractJsIntrinsic() {
// override fun install(bindings: MutableIntrinsicBindings) {
// bindings[TYPE_ERROR_SYMBOL.asJsSymbol()] = TypeError::class.java
// }
//}

/**
* # JavaScript: Type Error
Expand All @@ -61,12 +52,20 @@ private val TYPE_ERROR_MEMBERS_AND_PROPS = arrayOf(
* @see AbstractJsException for the host base interface type of all JavaScript exceptions.
* @see Error for the top-most guest-exposed base class for all JavaScript errors.
*/
@Implementable
public open class TypeError protected constructor (
@get:Polyglot override val message: String,
@get:Polyglot override val cause: Error? = null,
@get:Polyglot override val cause: Error?,
) : ProxyObject, AbstractJsException, Error() {

// String-only constructor.
public constructor(message: String?): this(message ?: "An error occurred", null)

// Guest-value-only constructor.
public constructor(value: Value?): this(value?.asString() ?: "An error occurred", null)

// Empty constructor.
public constructor(): this("An error occurred", null)

@get:Polyglot override val name: String get() = "TypeError"
override fun getMemberKeys(): Array<String> = TYPE_ERROR_MEMBERS_AND_PROPS
override fun hasMember(key: String?): Boolean = key != null && key in TYPE_ERROR_MEMBERS_AND_PROPS
Expand Down
Loading

0 comments on commit 0f0b3c0

Please sign in to comment.