This commit is contained in:
Horis
2024-01-28 17:09:25 +08:00
parent b9d6616ca6
commit e3aa72b315
22 changed files with 350 additions and 160 deletions
@@ -25,6 +25,7 @@
package com.script.rhino
import com.script.*
import kotlinx.coroutines.withContext
import org.mozilla.javascript.*
import org.mozilla.javascript.Function
import java.io.IOException
@@ -32,6 +33,8 @@ import java.io.Reader
import java.io.StringReader
import java.lang.reflect.Method
import java.security.*
import kotlin.coroutines.Continuation
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
/**
* Implementation of `ScriptEngine` using the Mozilla Rhino
@@ -80,6 +83,54 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
return unwrapReturnValue(ret)
}
@Throws(ContinuationPending::class)
override suspend fun evalSuspend(reader: Reader, scope: Scriptable): Any? {
val cx = Context.enter()
var ret: Any?
withContext(ContextElement()) {
try {
var filename = this@RhinoScriptEngine["javax.script.filename"] as? String
filename = filename ?: "<Unknown source>"
val script = cx.compileReader(reader, filename, 1, null)
try {
ret = cx.executeScriptWithContinuations(script, scope)
} catch (e: ContinuationPending) {
var pending = e
while (true) {
try {
@Suppress("UNCHECKED_CAST")
val suspendFunction =
pending.applicationState as Function1<Continuation<Any?>, Any?>
val functionResult = suspendCoroutineUninterceptedOrReturn { cout ->
suspendFunction.invoke(cout)
}
val continuation = pending.continuation
ret = cx.resumeContinuation(continuation, scope, functionResult)
break
} catch (e: ContinuationPending) {
pending = e
}
}
}
} catch (re: RhinoException) {
val line = if (re.lineNumber() == 0) -1 else re.lineNumber()
val msg: String = if (re is JavaScriptException) {
re.value.toString()
} else {
re.toString()
}
val se = ScriptException(msg, re.sourceName(), line)
se.initCause(re)
throw se
} catch (var14: IOException) {
throw ScriptException(var14)
} finally {
Context.exit()
}
}
return unwrapReturnValue(ret)
}
override fun createBindings(): Bindings {
return SimpleBindings()
}
@@ -227,7 +278,7 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
thisObj: Scriptable?,
args: Array<Any>
): Any? {
var accContext: AccessControlContext? = null
@@ -253,7 +304,7 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
thisObj: Scriptable?,
args: Array<Any>
): Any? {
return super.doTopCall(callable, cx, scope, thisObj, args)