Skip to content

Commit 168bc1c

Browse files
committed
fix error on android with multiple evaluate calls
1 parent ced1f7a commit 168bc1c

File tree

2 files changed

+67
-17
lines changed

2 files changed

+67
-17
lines changed

javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,27 @@ import kotlinx.serialization.json.JsonObject
1515
actual class JavaScriptEngine actual constructor() {
1616
private val quickJs: QuickJs = QuickJs.create()
1717
private val json: Json = Json.Default
18+
private val jsContext: ContextProviderDynamic = ContextProviderDynamic()
1819

1920
private var contextObjects: Map<String, JsType> = emptyMap()
2021

2122
@Volatile
2223
var isClosed = false
2324
private set
2425

26+
init {
27+
quickJs.set("mokoJsContext", ContextProvider::class.java, jsContext)
28+
quickJs.evaluate(
29+
"""
30+
function mokoJavaScriptProcessResult(result) {
31+
if (typeof result === 'object') return JSON.stringify(result);
32+
else if (typeof result === 'array') return JSON.stringify(result);
33+
else return result;
34+
}
35+
""".trimIndent()
36+
)
37+
}
38+
2539
actual fun setContextObjects(vararg context: Pair<String, JsType>) {
2640
this.contextObjects = mapOf(*context)
2741
}
@@ -47,11 +61,8 @@ actual class JavaScriptEngine actual constructor() {
4761
script: String
4862
): JsType {
4963
val scriptContext: Map<String, JsType> = contextObjects + context
50-
val jsContext: ContextProvider = ContextProviderImpl(
51-
context = scriptContext,
52-
script = script
53-
)
54-
quickJs.set("mokoJsContext", ContextProvider::class.java, jsContext)
64+
jsContext.activeScript = script
65+
jsContext.context = scriptContext
5566

5667
val scriptWithContext: String = buildString {
5768
scriptContext.forEach { (name, jsType) ->
@@ -69,11 +80,7 @@ actual class JavaScriptEngine actual constructor() {
6980
)
7081
append(";\n")
7182
}
72-
append("const script = mokoJsContext.getScript();\n")
73-
append("const result = eval(script);\n")
74-
append("if (typeof result === 'object') JSON.stringify(result);\n")
75-
append("else if (typeof result === 'array') JSON.stringify(result);\n")
76-
append("else result;")
83+
append("mokoJavaScriptProcessResult(eval(mokoJsContext.getScript()));")
7784
}
7885
val result: Any? = quickJs.evaluate(scriptWithContext)
7986
return handleQuickJsResult(result)
@@ -111,10 +118,10 @@ private interface ContextProvider {
111118
fun getScript(): String
112119
}
113120

114-
private class ContextProviderImpl(
115-
private val context: Map<String, JsType>,
116-
private val script: String
117-
) : ContextProvider {
121+
private class ContextProviderDynamic : ContextProvider {
122+
var context: Map<String, JsType> = emptyMap()
123+
var activeScript: String = ""
124+
118125
override fun getBool(name: String): Boolean {
119126
return context[name]!!.boolValue()
120127
}
@@ -132,7 +139,5 @@ private class ContextProviderImpl(
132139
}
133140
}
134141

135-
override fun getScript(): String {
136-
return this.script
137-
}
142+
override fun getScript(): String = activeScript
138143
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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 kotlin.test.AfterTest
8+
import kotlin.test.BeforeTest
9+
import kotlin.test.Test
10+
import kotlin.test.assertEquals
11+
12+
class JavaScriptEngineReuseTests {
13+
private lateinit var javaScriptEngine: JavaScriptEngine
14+
15+
@BeforeTest
16+
fun init() {
17+
javaScriptEngine = JavaScriptEngine()
18+
}
19+
20+
@AfterTest
21+
fun dispose() {
22+
javaScriptEngine.close()
23+
}
24+
25+
@Test
26+
fun reuseContextTest() {
27+
javaScriptEngine.evaluate(
28+
context = emptyMap(),
29+
"""
30+
var firstVal = "hello";
31+
""".trimIndent()
32+
)
33+
val result = javaScriptEngine.evaluate(
34+
context = mapOf("secondVal" to JsType.Str("world")),
35+
"""
36+
firstVal + " " + secondVal
37+
""".trimIndent()
38+
)
39+
40+
assertEquals(
41+
expected = JsType.Str("hello world"),
42+
actual = result
43+
)
44+
}
45+
}

0 commit comments

Comments
 (0)