GithubHelp home page GithubHelp logo

dokar3 / quickjs-kt Goto Github PK

View Code? Open in Web Editor NEW
17.0 17.0 1.0 4.73 MB

A QuickJS binding for idiomatic Kotlin, with Async/DSL/ES Modules support.

License: Apache License 2.0

C 53.49% Makefile 8.00% Shell 24.65% M4 0.09% Assembly 0.09% JavaScript 0.71% Kotlin 11.71% CMake 0.63% Batchfile 0.01% TypeScript 0.63%
javascript kotlin kotlin-coroutines kotlin-multiplatform quickjs

quickjs-kt's People

Contributors

dokar3 avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

josemontiel

quickjs-kt's Issues

Undefined Symbol for arm64 on linking

Hi,

I have a Kotlin Multiplatform project that fails at the linking step when building for iOS (device or simulator).

Here is the stack in XCode when trying to build :

Stack Trace :

Undefined symbols for architecture arm64:
  "_JS_AtomToValue", referenced from:
      _quickjs_JS_AtomToValue_wrapper62 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_Call", referenced from:
      _quickjs_JS_Call_wrapper145 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_CallConstructor", referenced from:
      _quickjs_JS_CallConstructor_wrapper147 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_DefinePropertyGetSet", referenced from:
      _quickjs_JS_DefinePropertyGetSet_wrapper158 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_DefinePropertyValue", referenced from:
      _quickjs_JS_DefinePropertyValue_wrapper155 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_DefinePropertyValueStr", referenced from:
      _quickjs_JS_DefinePropertyValueStr_wrapper157 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_Eval", referenced from:
      _quickjs_JS_Eval_wrapper150 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_EvalFunction", referenced from:
      _quickjs_JS_EvalFunction_wrapper188 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_ExecutePendingJob", referenced from:
      _quickjs_JS_ExecutePendingJob_wrapper184 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_FreeAtom", referenced from:
      _quickjs_JS_FreeAtom_wrapper60 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_FreeCString", referenced from:
      _quickjs_JS_FreeCString_wrapper118 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_GetArrayBuffer", referenced from:
      _quickjs_JS_GetArrayBuffer_wrapper168 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_GetException", referenced from:
      _quickjs_JS_GetException_wrapper91 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_GetGlobalObject", referenced from:
      _quickjs_JS_GetGlobalObject_wrapper152 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_GetOwnPropertyNames", referenced from:
      _quickjs_JS_GetOwnPropertyNames_wrapper143 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_GetPropertyInternal", referenced from:
      _quickjs_JS_GetProperty_wrapper129 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_GetPropertyStr", referenced from:
      _quickjs_JS_GetPropertyStr_wrapper130 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_GetPropertyUint32", referenced from:
      _quickjs_JS_GetPropertyUint32_wrapper131 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_GetRuntime", referenced from:
      _quickjs_JS_GetRuntime_wrapper20 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_IsArray", referenced from:
      _quickjs_JS_IsArray_wrapper127 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_IsError", referenced from:
      _quickjs_JS_IsError_wrapper92 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_IsFunction", referenced from:
      _quickjs_JS_IsFunction_wrapper123 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_IsInstanceOf", referenced from:
      _quickjs_JS_IsInstanceOf_wrapper153 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_JSONStringify", referenced from:
      _quickjs_JS_JSONStringify_wrapper164 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewArray", referenced from:
      _quickjs_JS_NewArray_wrapper126 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewArrayBuffer", referenced from:
      _quickjs_JS_NewArrayBuffer_wrapper165 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewAtom", referenced from:
      _quickjs_JS_NewAtom_wrapper57 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewCFunctionData", referenced from:
      _quickjs_JS_NewCFunctionData_wrapper193 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewContext", referenced from:
      _quickjs_JS_NewContext_wrapper15 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewError", referenced from:
      _quickjs_JS_NewError_wrapper94 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewObject", referenced from:
      _quickjs_JS_NewObject_wrapper122 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewPromiseCapability", referenced from:
      _quickjs_JS_NewPromiseCapability_wrapper171 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewRuntime", referenced from:
      _quickjs_JS_NewRuntime_wrapper2 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_NewString", referenced from:
      _quickjs_JS_NewString_wrapper111 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_PromiseResult", referenced from:
      _quickjs_JS_PromiseResult_wrapper173 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_PromiseState", referenced from:
      _quickjs_JS_PromiseState_wrapper172 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_ReadObject", referenced from:
      _quickjs_JS_ReadObject_wrapper187 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_SetHostPromiseRejectionTracker", referenced from:
      _quickjs_JS_SetHostPromiseRejectionTracker_wrapper174 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_SetPropertyStr", referenced from:
      _quickjs_JS_SetPropertyStr_wrapper136 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_SetPropertyUint32", referenced from:
      _quickjs_JS_SetPropertyUint32_wrapper134 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_Throw", referenced from:
      _quickjs_JS_Throw_wrapper90 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_ToBool", referenced from:
      _quickjs_JS_ToBool_wrapper102 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_ToCStringLen2", referenced from:
      _quickjs_JS_ToCString_wrapper117 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_ToFloat64", referenced from:
      _quickjs_JS_ToFloat64_wrapper107 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_ToInt32", referenced from:
      _quickjs_JS_ToInt32_wrapper103 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_ToInt64", referenced from:
      _quickjs_JS_ToInt64_wrapper105 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_UpdateStackTop", referenced from:
      _quickjs_JS_UpdateStackTop_wrapper7 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_JS_WriteObject", referenced from:
      _quickjs_JS_WriteObject_wrapper185 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "___JS_FreeValue", referenced from:
      _quickjs_JS_FreeValue_wrapper97 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
  "_js_free", referenced from:
      _quickjs_js_free_wrapper47 in Shared[arm64][9](libquickjs-kt:quickjs-cinterop-quickjs-cache.a.o)
ld: symbol(s) not found for architecture arm64

Steps to reproduce :

  • Create a new kotlin multiplatform project from their wizard here
  • Add implementation of quickjs in the sourceSets in build.gradle.kts of the shared module
  • Call a quickJs method in Greeting.kt in commonMain in shared module
  • Open the XCode project in iosApp folder
  • Try to build

Any idea of where it comes from ?

Thanks for your help !

Kotlin/Native targets

Progress

  1. mingwX64 and linuxX64: #9
  2. linuxArm64, macosX64, macosArm64, iosX64, iosArm64 and iosSimulatorArm64: #16

Exception handling

Can you add a section to the README on how to properly handle js exceptions?

This does not work if an exception occurs in the js code. An error is thrown but this does not catch it:

                val result = try {
                    wrapper.evaluateJs(jscode)
                }
                catch (e: Exception) {
                    Logger.e { "Javascript error: $e" }
                    null
                }

throws this error:

Exception in thread "DefaultDispatcher-worker-10" java.lang.RuntimeException: Exception while trying to handle coroutine exception
	at kotlinx.coroutines.CoroutineExceptionHandlerKt.handlerException(CoroutineExceptionHandler.kt:33)
	at kotlinx.coroutines.internal.CoroutineExceptionHandlerImpl_commonKt.handleUncaughtCoroutineException(CoroutineExceptionHandlerImpl.common.kt:38)
	at kotlinx.coroutines.CoroutineExceptionHandlerKt.handleCoroutineException(CoroutineExceptionHandler.kt:28)
	at kotlinx.coroutines.StandaloneCoroutine.handleJobException(Builders.common.kt:190)
	at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:228)
	at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:907)
	at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:864)
	at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:829)
	at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:97)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at kotlinx.coroutines.internal.ScopeCoroutine.afterResume(Scopes.kt:28)
	at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:99)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:585)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:802)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:706)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:693)
	Suppressed: java.lang.Error: Error: test
    at dictionaryapi (main.js:5)
    at <anonymous> (main.js:12)
    at search (main.js)
    at <eval> (main.js:2)

		at com.dokar.quickjs.QuickJs.getEvaluateResult(Native Method)
		at com.dokar.quickjs.QuickJs.evalAndAwait(QuickJs.jni.kt:220)
		at com.dokar.quickjs.QuickJs.evaluateInternal(QuickJs.jni.kt:210)
...

This js code works as expected when I define my own host.log function, but it would be nicer if I could catch the error in kotlin:

                    try {
                      doStuff();
                    }
                    catch (err) {
                      host.log("caught js error: ", err);
                    }

thanks for all your quick updates!

suspend functions

Have you tried to use a suspend function via reflection, as shown below? I'm getting an error "parameter count mismatched"

class Http {
    suspend fun fetch(url: String) = "..."
}

quickJs {
    define<Http>("http", Http())

    evaluate<Any?>(
        """
        await http.fetch("https://www.example.com")
        """.trimIndent()
    )
}

Fix leaks

There are some leaks in the JS runtime after evaluation. They won't crash JS_FreeRuntime but need to be fixed.

Correct error handling for async functions

Currently, all jobs will get canceled if one throws an error, regardless of whether they have been caught in JavaScript.

The behavior needs to be implemented correctly.

Related to #12

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

bun
scripts/package.json
  • @types/bun ^1.0.5
github-actions
.github/workflows/benchmark.yaml
  • actions/checkout v4
  • actions/setup-java v4
  • jwlawson/actions-setup-cmake v2.0
  • goto-bus-stop/setup-zig v2
  • oven-sh/setup-bun v1
  • gradle/gradle-build-action v3.1.0
  • stefanzweifel/git-auto-commit-action v5
.github/workflows/build.yaml
  • actions/checkout v4
  • actions/setup-java v4
  • jwlawson/actions-setup-cmake v2.0
  • goto-bus-stop/setup-zig v2
  • oven-sh/setup-bun v1
  • gradle/gradle-build-action v3.1.0
.github/workflows/publish.yaml
  • actions/checkout v4
  • actions/setup-java v4
  • jwlawson/actions-setup-cmake v2.0
  • goto-bus-stop/setup-zig v2
  • oven-sh/setup-bun v1
  • gradle/gradle-build-action v3.1.0
gradle
buildSrc/src/main/kotlin/com/dokar/quickjs/Platform.kt
buildSrc/src/main/kotlin/com/dokar/quickjs/applyQuickJsNativeBuildTasks.kt
buildSrc/src/main/kotlin/com/dokar/quickjs/buildQuickJsNativeLibrary.kt
buildSrc/src/main/kotlin/com/dokar/quickjs/disableUnsupportedPlatformTasks.kt
gradle.properties
settings.gradle.kts
build.gradle.kts
benchmark/build.gradle.kts
buildSrc/settings.gradle.kts
buildSrc/build.gradle.kts
gradle/libs.versions.toml
  • androidx.core:core-ktx 1.12.0
  • junit:junit 4.13.2
  • androidx.test.ext:junit 1.1.5
  • androidx.activity:activity-compose 1.8.2
  • androidx.compose.ui:ui-tooling 1.6.4
  • androidx.compose.ui:ui-tooling-preview 1.6.4
  • org.jetbrains.kotlin:kotlin-test 1.9.22
  • org.jetbrains.kotlin:kotlin-test-junit 1.9.22
  • org.jetbrains.kotlinx:kotlinx-coroutines-core 1.8.0
  • org.jetbrains.kotlinx:kotlinx-coroutines-test 1.8.0
  • org.jetbrains.kotlinx:kotlinx-benchmark-runtime 0.4.10
  • com.github.ajalt.clikt:clikt 4.2.2
  • io.ktor:ktor-client-core 3.0.0-beta-1
  • io.ktor:ktor-client-cio 3.0.0-beta-1
  • com.android.application 8.3.1
  • com.android.library 8.3.1
  • org.jetbrains.compose 1.6.0
  • org.jetbrains.kotlin.multiplatform 1.9.22
  • org.jetbrains.kotlin.jvm 1.9.22
  • org.jetbrains.kotlin.android 1.9.22
  • org.jetbrains.kotlinx.benchmark 0.4.10
  • org.jetbrains.kotlin.plugin.allopen 1.9.22
  • com.vanniktech.maven.publish 0.28.0
quickjs/gradle.properties
quickjs/build.gradle.kts
samples/js-eval/build.gradle.kts
samples/openai/build.gradle.kts
samples/repl/build.gradle.kts
  • com.github.johnrengelman.shadow 8.1.1
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.7

  • Check this box to trigger a request for Renovate to run again on this repository

Proper way to detect circular references

Currently, the detection of circular references not working on deep-level circular references:

// Not able to detect in this case
val set = mutableSetOf<Any?>()
val array = arrayOf(set)
set.add(array)

Need to re-implement the detection code.

Repeatable (but not 100% consistent) error in _platform_strcmp

                    val js = """
                        var response = await kml.requestJson('https://icanhazdadjoke.com/');
                        let parsed = JSON.parse(response);
                        parsed.joke;
                    """.trimIndent()

                    val joke = quickJs {
                        define("kml") {
                            asyncFunction("requestJson") { args ->
                                delay(500)
                                """
                                    {"id":"bxXLeqzP7wc","joke":"Americans can't switch from pounds to kilograms overnight. That would cause mass confusion.","status":200}
                                """.trimIndent()
                            }
                        }
                        evaluate<Any?>(js)?.toString()
                    }

Causes this error. Not every time but frequently:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000188e4aa9c, pid=63005, tid=90371
#
# JRE version: OpenJDK Runtime Environment (17.0.7) (build 17.0.7+0-17.0.7b1000.6-10550314)
# Java VM: OpenJDK 64-Bit Server VM (17.0.7+0-17.0.7b1000.6-10550314, mixed mode, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-aarch64)
# Problematic frame:
# C  [libsystem_platform.dylib+0xa9c]  _platform_strcmp+0xc
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
JNI global refs:
JNI global refs: 161, weak refs: 11

JNI global refs memory usage: 2099, weak refs: 833

OOME stack traces (most recent first):
Classloader memory used:
Loader jdk.internal.loader.ClassLoaders$AppClassLoader                                 : 3926K
Loader bootstrap                                                                       : 2694K
Loader jdk.internal.loader.ClassLoaders$PlatformClassLoader                            : 18987B
Loader jdk.internal.reflect.DelegatingClassLoader                                      : 4278B

# An error report file with more information is saved as:
# /Users/dmelton/Developer/doug/kmlauncher/compose-multiplatform/composeApp/hs_err_pid63005.log
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

I removed any actual networking, but simulated by that delay(500)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.