[JS IR BE] Run JS IR tests in V8 engine

This commit is contained in:
Roman Artemev
2019-03-04 19:59:14 +03:00
committed by romanart
parent 2ccd093099
commit 88d365328a
6 changed files with 113 additions and 26 deletions
+7
View File
@@ -42,6 +42,13 @@ dependencies {
testRuntime(project(":kotlin-preloader")) // it's required for ant tests
testRuntime(project(":compiler:backend-common"))
testRuntime(commonDep("org.fusesource.jansi", "jansi"))
when {
OperatingSystem.current().isWindows() -> testCompile("com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0")
OperatingSystem.current().isLinux() -> testCompile("com.eclipsesource.j2v8:j2v8_linux_x86_64:4.8.0")
OperatingSystem.current().isMacOsX() -> testCompile("com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0")
else -> logger.error("unsupported platform - can not compile com.eclipsesource.j2v8 dependency")
}
antLauncherJar(commonDep("org.apache.ant", "ant"))
antLauncherJar(files(toolsJar()))
@@ -131,7 +131,7 @@ abstract class BasicIrBoxTest(
// TODO: should we do anything special for module systems?
// TODO: return list of js from translateFiles and provide then to this function with other js files
NashornIrJsTestChecker().check(jsFiles, testModuleName, null, testFunction, expectedResult, withModuleSystem)
V8IrJsTestChecker.check(jsFiles, testModuleName, null, testFunction, expectedResult, withModuleSystem)
}
}
@@ -9,6 +9,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime
import org.jetbrains.kotlin.js.test.interop.GlobalRuntimeContext
import org.jetbrains.kotlin.js.test.interop.ScriptEngine
import org.jetbrains.kotlin.js.test.interop.ScriptEngineNashorn
import org.jetbrains.kotlin.js.test.interop.ScriptEngineV8
import org.junit.Assert
fun createScriptEngine(): ScriptEngine {
@@ -36,9 +37,36 @@ fun ScriptEngine.runTestFunction(
}
val testPackage = eval<Any>(script)
return callMethod(testPackage, testFunctionName)
return callMethod<String?>(testPackage, testFunctionName).also {
releaseObject(testPackage)
}
}
abstract class AbstractJsTestChecker {
fun check(
files: List<String>,
testModuleName: String?,
testPackageName: String?,
testFunctionName: String,
expectedResult: String,
withModuleSystem: Boolean
) {
val actualResult = run(files, testModuleName, testPackageName, testFunctionName, withModuleSystem)
Assert.assertEquals(expectedResult, actualResult)
}
private fun run(
files: List<String>,
testModuleName: String?,
testPackageName: String?,
testFunctionName: String,
withModuleSystem: Boolean
) = run(files) {
runTestFunction(testModuleName, testPackageName, testFunctionName, withModuleSystem)
}
protected abstract fun run(files: List<String>, f: ScriptEngine.() -> Any?): Any?
}
fun ScriptEngine.runAndRestoreContext(
globalObject: GlobalRuntimeContext = getGlobalContext(),
@@ -54,7 +82,7 @@ fun ScriptEngine.runAndRestoreContext(
}
}
abstract class AbstractNashornJsTestChecker {
abstract class AbstractNashornJsTestChecker: AbstractJsTestChecker() {
private var engineUsageCnt = 0
@@ -69,35 +97,13 @@ abstract class AbstractNashornJsTestChecker {
originalState = globalObject?.toMap()
}
fun check(
files: List<String>,
testModuleName: String?,
testPackageName: String?,
testFunctionName: String,
expectedResult: String,
withModuleSystem: Boolean
) {
val actualResult = run(files, testModuleName, testPackageName, testFunctionName, withModuleSystem)
Assert.assertEquals(expectedResult, actualResult)
}
fun run(files: List<String>) {
run(files) { null }
}
private fun run(
files: List<String>,
testModuleName: String?,
testPackageName: String?,
testFunctionName: String,
withModuleSystem: Boolean
) = run(files) {
runTestFunction(testModuleName, testPackageName, testFunctionName, withModuleSystem)
}
protected open fun beforeRun() {}
private fun run(
override fun run(
files: List<String>,
f: ScriptEngine.() -> Any?
): Any? {
@@ -158,4 +164,18 @@ class NashornIrJsTestChecker : AbstractNashornJsTestChecker() {
return engine
}
}
object V8IrJsTestChecker : AbstractJsTestChecker() {
override fun run(files: List<String>, f: ScriptEngine.() -> Any?): Any? {
val v8 = ScriptEngineV8()
return try {
files.forEach { v8.loadFile(it) }
v8.f()
} finally {
v8.release()
}
}
}
@@ -11,4 +11,6 @@ interface ScriptEngine {
fun evalVoid(script: String)
fun <T> callMethod(obj: Any, name: String, vararg args: Any?): T
fun loadFile(path: String)
fun release()
fun <T> releaseObject(t: T)
}
@@ -33,4 +33,7 @@ class ScriptEngineNashorn : ScriptEngine {
override fun loadFile(path: String) {
evalVoid("load('${path.replace('\\', '/')}');")
}
override fun release() {}
override fun <T> releaseObject(t: T) {}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.interop
import com.eclipsesource.v8.V8
import com.eclipsesource.v8.V8Array
import com.eclipsesource.v8.V8Object
import com.eclipsesource.v8.utils.V8ObjectUtils
import java.io.File
class ScriptEngineV8 : ScriptEngine {
override fun <T> releaseObject(t: T) {
(t as? V8Object)?.release()
}
override fun getGlobalContext(): GlobalRuntimeContext {
val v8result = eval<V8Object>("this")
val context = V8ObjectUtils.toMap(v8result) as GlobalRuntimeContext
return context.also { v8result.release() }
}
private val myRuntime: V8 = V8.createV8Runtime("global")
@Suppress("UNCHECKED_CAST")
override fun <T> eval(script: String): T {
return myRuntime.executeScript(script) as T
}
override fun evalVoid(script: String) {
return myRuntime.executeVoidScript(script)
}
@Suppress("UNCHECKED_CAST")
override fun <T> callMethod(obj: Any, name: String, vararg args: Any?): T {
if (obj !is V8Object) {
throw Exception("InteropV8 can deal only with V8Object")
}
val runtimeArray = V8Array(myRuntime)
val result = obj.executeFunction(name, runtimeArray) as T
runtimeArray.release()
return result
}
override fun loadFile(path: String) {
evalVoid(File(path).bufferedReader().use { it.readText() })
}
override fun release() {
myRuntime.release()
}
}