Skip to content

Commit fd0171f

Browse files
committed
JavaScriptEngine android implementation
1 parent 3c3a454 commit fd0171f

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest package="dev.icerock.moko.javascript" />
2+
<manifest package="dev.icerock.moko.javascript" />
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package dev.icerock.moko.javascript
6+
7+
import app.cash.quickjs.QuickJs
8+
import app.cash.quickjs.QuickJsException
9+
import kotlinx.serialization.SerializationException
10+
import kotlinx.serialization.json.Json
11+
import kotlinx.serialization.json.encodeToJsonElement
12+
13+
actual class JavaScriptEngine actual constructor(){
14+
private val quickJs: QuickJs = QuickJs.create()
15+
private val json: Json = Json.Default
16+
17+
@Volatile
18+
var isClosed = false
19+
private set
20+
21+
actual fun evaluate(
22+
context: Map<String, JsType>,
23+
script: String
24+
): JsType {
25+
if (isClosed) throw JavaScriptEvaluationException(message = "Engine already closed")
26+
27+
return try {
28+
internalEvaluate(context, script)
29+
} catch (exception: QuickJsException) {
30+
throw JavaScriptEvaluationException(exception)
31+
}
32+
}
33+
34+
actual fun close() {
35+
if (isClosed) return
36+
quickJs.close()
37+
isClosed = true
38+
}
39+
40+
private fun internalEvaluate(
41+
context: Map<String, JsType>,
42+
script: String
43+
): JsType {
44+
context.forEach { pair ->
45+
quickJs.set(pair.key, pair.value.javaClass, pair.value)
46+
}
47+
val result = quickJs.evaluate(script)
48+
return handleQuickJsResult(result)
49+
}
50+
51+
private fun handleQuickJsResult(result: Any?): JsType {
52+
if (result is String) {
53+
return try {
54+
JsType.Json(json.encodeToJsonElement(result))
55+
} catch (ex: SerializationException) {
56+
JsType.Str(result)
57+
}
58+
}
59+
60+
return when (result) {
61+
result == null -> JsType.Null
62+
is Boolean -> JsType.Bool(result)
63+
is Int -> JsType.IntNum(result)
64+
is Double -> JsType.DoubleNum(result)
65+
is Float -> JsType.DoubleNum(result.toDouble())
66+
else -> throw IllegalStateException("Impossible JavaScriptEngine handler state")
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)