Rearrange scripting host classes, so the runner part is independent from the compiler

This commit is contained in:
Ilya Chernikov
2019-04-05 15:24:36 +02:00
parent a6f0bd6677
commit c896b4873b
12 changed files with 315 additions and 250 deletions
@@ -10,6 +10,7 @@ import kotlin.script.experimental.host.ScriptingHostConfiguration
import kotlin.script.experimental.host.createCompilationConfigurationFromTemplate
import kotlin.script.experimental.host.BasicScriptingHost
import kotlin.script.experimental.host.createEvaluationConfigurationFromTemplate
import kotlin.script.experimental.jvm.BasicJvmScriptEvaluator
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
open class BasicJvmScriptingHost(
@@ -0,0 +1,21 @@
/*
* 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 kotlin.script.experimental.jvmhost.impl
import java.io.Serializable
import kotlin.script.experimental.jvm.impl.KJvmCompiledModule
class KJvmCompiledModuleInMemory(val compilerOutputFiles: Map<String, ByteArray>) : KJvmCompiledModule,
Serializable {
override fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader =
CompiledScriptClassLoader(baseClassLoader, compilerOutputFiles)
companion object {
@JvmStatic
private val serialVersionUID = 0L
}
}
@@ -1,76 +0,0 @@
/*
* Copyright 2010-2018 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 kotlin.script.experimental.jvmhost.impl
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
import kotlin.reflect.KClass
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvmhost.getOrCreateActualClassloader
class KJvmCompiledScript<out ScriptBase : Any>(
sourceLocationId: String?,
compilationConfiguration: ScriptCompilationConfiguration,
private var scriptClassFQName: String,
otherScripts: List<CompiledScript<*>> = emptyList(),
internal var compiledModule: KJvmCompiledModule
) : CompiledScript<ScriptBase>, Serializable {
private var _sourceLocationId: String? = sourceLocationId
override val sourceLocationId: String?
get() = _sourceLocationId
private var _compilationConfiguration: ScriptCompilationConfiguration? = compilationConfiguration
override val compilationConfiguration: ScriptCompilationConfiguration
get() = _compilationConfiguration!!
private var _otherScripts: List<CompiledScript<*>> = otherScripts
override val otherScripts: List<CompiledScript<*>>
get() = _otherScripts
override suspend fun getClass(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<KClass<*>> = try {
// ensuring proper defaults are used
val actualEvaluationConfiguration = scriptEvaluationConfiguration ?: ScriptEvaluationConfiguration()
val classLoader = getOrCreateActualClassloader(actualEvaluationConfiguration)
val clazz = classLoader.loadClass(scriptClassFQName).kotlin
clazz.asSuccess()
} catch (e: Throwable) {
ResultWithDiagnostics.Failure(
ScriptDiagnostic(
"Unable to instantiate class $scriptClassFQName",
sourcePath = sourceLocationId,
exception = e
)
)
}
private fun writeObject(outputStream: ObjectOutputStream) {
outputStream.writeObject(compilationConfiguration)
outputStream.writeObject(sourceLocationId)
outputStream.writeObject(otherScripts)
outputStream.writeObject(compiledModule)
outputStream.writeObject(scriptClassFQName)
}
@Suppress("UNCHECKED_CAST")
private fun readObject(inputStream: ObjectInputStream) {
_compilationConfiguration = inputStream.readObject() as ScriptCompilationConfiguration
_sourceLocationId = inputStream.readObject() as String?
_otherScripts = inputStream.readObject() as List<CompiledScript<*>>
compiledModule = inputStream.readObject() as KJvmCompiledModuleInMemory
scriptClassFQName = inputStream.readObject() as String
}
companion object {
@JvmStatic
private val serialVersionUID = 2L
}
}
@@ -62,6 +62,7 @@ import kotlin.script.experimental.host.getMergedScriptText
import kotlin.script.experimental.host.getScriptingClass
import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvm.impl.BridgeDependenciesResolver
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
import kotlin.script.experimental.jvm.jdkHome
import kotlin.script.experimental.jvm.jvm
import kotlin.script.experimental.jvm.util.KotlinJars
@@ -1,159 +0,0 @@
/*
* Copyright 2010-2018 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.
*/
@file:Suppress("unused")
package kotlin.script.experimental.jvmhost
import java.net.URLClassLoader
import kotlin.reflect.KClass
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvmhost.impl.KJvmCompiledScript
import kotlin.script.experimental.util.PropertiesCollection
interface JvmScriptEvaluationConfigurationKeys
open class JvmScriptEvaluationConfigurationBuilder : PropertiesCollection.Builder(), JvmScriptEvaluationConfigurationKeys {
companion object : JvmScriptEvaluationConfigurationBuilder()
}
/**
* The base classloader to use for script classes loading
*/
val JvmScriptEvaluationConfigurationKeys.baseClassLoader by PropertiesCollection.key<ClassLoader?>(Thread.currentThread().contextClassLoader)
/**
* Load script dependencies before evaluation, true by default
* If false, it is assumed that the all dependencies will be provided via baseClassLoader
*/
val JvmScriptEvaluationConfigurationKeys.loadDependencies by PropertiesCollection.key<Boolean>(true)
internal val JvmScriptEvaluationConfigurationKeys.actualClassLoader by PropertiesCollection.key<ClassLoader?>()
internal val JvmScriptEvaluationConfigurationKeys.scriptsInstancesSharingMap by PropertiesCollection.key<MutableMap<KClass<*>, EvaluationResult>>()
val ScriptEvaluationConfigurationKeys.jvm get() = JvmScriptEvaluationConfigurationBuilder()
class JvmScriptEvaluationContext(
val classLoader: ClassLoader,
val scriptsInstancesSharingMap: MutableMap<KClass<*>, EvaluationResult>?
)
open class BasicJvmScriptEvaluator : ScriptEvaluator {
override suspend operator fun invoke(
compiledScript: CompiledScript<*>,
scriptEvaluationConfiguration: ScriptEvaluationConfiguration
): ResultWithDiagnostics<EvaluationResult> = try {
val configuration = getConfigurationWithClassloader(compiledScript, scriptEvaluationConfiguration)
compiledScript.getClass(configuration).onSuccess { scriptClass ->
// in the future, when (if) we'll stop to compile everything into constructor
// run as SAM
// return res
val sharedScripts = configuration[ScriptEvaluationConfiguration.jvm.scriptsInstancesSharingMap]
sharedScripts?.get(scriptClass)?.asSuccess()
?: compiledScript.otherScripts.mapSuccess {
invoke(it, configuration)
}.onSuccess { importedScriptsEvalResults ->
val refinedEvalConfiguration =
configuration[ScriptEvaluationConfiguration.refineConfigurationBeforeEvaluate]
?.handler?.invoke(ScriptEvaluationConfigurationRefinementContext(compiledScript, configuration))
?.onFailure {
return@invoke ResultWithDiagnostics.Failure(it.reports)
}
?.resultOrNull()
?: configuration
scriptClass.evalWithConfigAndOtherScriptsResults(refinedEvalConfiguration, importedScriptsEvalResults).let {
sharedScripts?.put(scriptClass, it)
ResultWithDiagnostics.Success(it)
}
}
}
} catch (e: Throwable) {
ResultWithDiagnostics.Failure(e.asDiagnostics("Error evaluating script", path = compiledScript.sourceLocationId))
}
private fun getConfigurationWithClassloader(
script: CompiledScript<*>, baseConfiguration: ScriptEvaluationConfiguration
): ScriptEvaluationConfiguration =
if (baseConfiguration.containsKey(ScriptEvaluationConfiguration.jvm.actualClassLoader))
baseConfiguration
else {
val jvmScript = (script as? KJvmCompiledScript<*>)
?: throw IllegalArgumentException("Unexpected compiled script type: $script")
val classloader = jvmScript.getOrCreateActualClassloader(baseConfiguration)
ScriptEvaluationConfiguration(baseConfiguration) {
ScriptEvaluationConfiguration.jvm.actualClassLoader(classloader)
if (baseConfiguration[ScriptEvaluationConfiguration.scriptsInstancesSharing] == true) {
ScriptEvaluationConfiguration.jvm.scriptsInstancesSharingMap(mutableMapOf())
}
}
}
private fun KClass<*>.evalWithConfigAndOtherScriptsResults(
refinedEvalConfiguration: ScriptEvaluationConfiguration,
importedScriptsEvalResults: List<EvaluationResult>
): EvaluationResult {
val args = ArrayList<Any?>()
refinedEvalConfiguration[ScriptEvaluationConfiguration.constructorArgs]?.let {
args.addAll(it)
}
refinedEvalConfiguration[ScriptEvaluationConfiguration.implicitReceivers]?.let {
args.addAll(it)
}
refinedEvalConfiguration[ScriptEvaluationConfiguration.providedProperties]?.forEach {
args.add(it.value)
}
importedScriptsEvalResults.forEach {
args.add((it.returnValue as ResultValue.Value).scriptInstance)
}
val ctor = java.constructors.single()
val instance = ctor.newInstance(*args.toArray())
return EvaluationResult(ResultValue.Value("", instance, "", instance), refinedEvalConfiguration)
}
}
internal fun KJvmCompiledScript<*>.getOrCreateActualClassloader(evaluationConfiguration: ScriptEvaluationConfiguration): ClassLoader =
evaluationConfiguration[ScriptEvaluationConfiguration.jvm.actualClassLoader] ?: run {
val baseClassLoader = evaluationConfiguration[ScriptEvaluationConfiguration.jvm.baseClassLoader]
val classLoaderWithDeps =
if (evaluationConfiguration[ScriptEvaluationConfiguration.jvm.loadDependencies] == false) baseClassLoader
else makeClassLoaderFromDependencies(baseClassLoader)
compiledModule.createClassLoader(classLoaderWithDeps)
}
private fun CompiledScript<*>.makeClassLoaderFromDependencies(baseClassLoader: ClassLoader?): ClassLoader? {
val processedScripts = mutableSetOf<CompiledScript<*>>()
fun seq(res: Sequence<CompiledScript<*>>, script: CompiledScript<*>): Sequence<CompiledScript<*>> {
if (processedScripts.contains(script)) return res
processedScripts.add(script)
return script.otherScripts.asSequence().fold(res + script, ::seq)
}
val dependencies = seq(emptySequence(), this).flatMap { script ->
script.compilationConfiguration[ScriptCompilationConfiguration.dependencies]
?.asSequence()
?.flatMap { dep ->
(dep as? JvmDependency)?.classpath?.asSequence()?.map { it.toURI().toURL() } ?: emptySequence()
}
?: emptySequence()
}.distinct()
// TODO: previous dependencies and classloaders should be taken into account here
return if (dependencies.none()) baseClassLoader
else URLClassLoader(dependencies.toList().toTypedArray(), baseClassLoader)
}
@@ -13,7 +13,7 @@ import java.util.jar.Manifest
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvmhost.impl.KJvmCompiledModuleInMemory
import kotlin.script.experimental.jvmhost.impl.KJvmCompiledScript
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
// TODO: generate execution code (main)
@@ -0,0 +1,32 @@
/*
* Copyright 2010-2018 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.
*/
@file:Suppress("unused")
package kotlin.script.experimental.jvmhost
import kotlin.script.experimental.api.ScriptEvaluationConfiguration
import kotlin.script.experimental.api.ScriptEvaluationConfigurationKeys
import kotlin.script.experimental.jvm.baseClassLoader
import kotlin.script.experimental.jvm.jvm
import kotlin.script.experimental.util.PropertiesCollection
@Deprecated("use the same definitions from kotlin.script.experimental.jvm package", level = DeprecationLevel.WARNING)
interface JvmScriptEvaluationConfigurationKeys
@Deprecated("use the same definitions from kotlin.script.experimental.jvm package", level = DeprecationLevel.WARNING)
open class JvmScriptEvaluationConfigurationBuilder : PropertiesCollection.Builder(), JvmScriptEvaluationConfigurationKeys {
companion object : JvmScriptEvaluationConfigurationBuilder()
}
@Deprecated("use the same definitions from kotlin.script.experimental.jvm package", level = DeprecationLevel.ERROR)
val JvmScriptEvaluationConfigurationKeys.baseClassLoader get() = ScriptEvaluationConfiguration.jvm.baseClassLoader
@Deprecated("use the same definitions from kotlin.script.experimental.jvm package", level = DeprecationLevel.ERROR)
val ScriptEvaluationConfigurationKeys.jvm get() = ScriptEvaluationConfiguration.jvm
@Deprecated("use the same definitions from kotlin.script.experimental.jvm package", level = DeprecationLevel.ERROR)
open class BasicJvmScriptEvaluator : kotlin.script.experimental.jvm.BasicJvmScriptEvaluator()
@@ -18,10 +18,11 @@ import kotlin.script.experimental.api.*
import kotlin.script.experimental.host.BasicScriptingHost
import kotlin.script.experimental.host.FileScriptSource
import kotlin.script.experimental.host.toScriptSource
import kotlin.script.experimental.jvm.BasicJvmScriptEvaluator
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
import kotlin.script.experimental.jvmhost.*
import kotlin.script.experimental.jvmhost.impl.CompiledScriptClassLoader
import kotlin.script.experimental.jvmhost.impl.KJvmCompiledScript
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
import kotlin.script.templates.standard.SimpleScriptTemplate
class ScriptingHostTest : TestCase() {
@@ -0,0 +1,91 @@
/*
* 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 kotlin.script.experimental.jvm
import kotlin.reflect.KClass
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.impl.getConfigurationWithClassloader
import kotlin.script.experimental.jvm.impl.sharedScripts
open class BasicJvmScriptEvaluator : ScriptEvaluator {
override suspend operator fun invoke(
compiledScript: CompiledScript<*>,
scriptEvaluationConfiguration: ScriptEvaluationConfiguration
): ResultWithDiagnostics<EvaluationResult> = try {
val configuration = getConfigurationWithClassloader(compiledScript, scriptEvaluationConfiguration)
compiledScript.getClass(configuration).onSuccess { scriptClass ->
// in the future, when (if) we'll stop to compile everything into constructor
// run as SAM
// return res
val sharedScripts = configuration.sharedScripts
sharedScripts?.get(scriptClass)?.asSuccess()
?: compiledScript.otherScripts.mapSuccess {
invoke(it, configuration)
}.onSuccess { importedScriptsEvalResults ->
val refinedEvalConfiguration =
configuration[ScriptEvaluationConfiguration.refineConfigurationBeforeEvaluate]
?.handler?.invoke(
ScriptEvaluationConfigurationRefinementContext(
compiledScript,
configuration
)
)
?.onFailure {
return@invoke ResultWithDiagnostics.Failure(it.reports)
}
?.resultOrNull()
?: configuration
scriptClass.evalWithConfigAndOtherScriptsResults(refinedEvalConfiguration, importedScriptsEvalResults).let {
sharedScripts?.put(scriptClass, it)
ResultWithDiagnostics.Success(it)
}
}
}
} catch (e: Throwable) {
ResultWithDiagnostics.Failure(
e.asDiagnostics(
"Error evaluating script",
path = compiledScript.sourceLocationId
)
)
}
private fun KClass<*>.evalWithConfigAndOtherScriptsResults(
refinedEvalConfiguration: ScriptEvaluationConfiguration,
importedScriptsEvalResults: List<EvaluationResult>
): EvaluationResult {
val args = ArrayList<Any?>()
refinedEvalConfiguration[ScriptEvaluationConfiguration.constructorArgs]?.let {
args.addAll(it)
}
refinedEvalConfiguration[ScriptEvaluationConfiguration.implicitReceivers]?.let {
args.addAll(it)
}
refinedEvalConfiguration[ScriptEvaluationConfiguration.providedProperties]?.forEach {
args.add(it.value)
}
importedScriptsEvalResults.forEach {
args.add((it.returnValue as ResultValue.Value).scriptInstance)
}
val ctor = java.constructors.single()
val instance = ctor.newInstance(*args.toArray())
return EvaluationResult(
ResultValue.Value("", instance, "", instance),
refinedEvalConfiguration
)
}
}
@@ -3,27 +3,15 @@
* that can be found in the license/LICENSE.txt file.
*/
package kotlin.script.experimental.jvmhost.impl
package kotlin.script.experimental.jvm.impl
import java.io.File
import java.io.Serializable
import java.net.URLClassLoader
interface KJvmCompiledModule {
fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader
}
class KJvmCompiledModuleInMemory(val compilerOutputFiles: Map<String, ByteArray>) : KJvmCompiledModule, Serializable {
override fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader =
CompiledScriptClassLoader(baseClassLoader, compilerOutputFiles)
companion object {
@JvmStatic
private val serialVersionUID = 0L
}
}
class KJvmCompiledModuleFromClassPath(val classpath: Collection<File>) : KJvmCompiledModule {
override fun createClassLoader(baseClassLoader: ClassLoader?): ClassLoader =
@@ -0,0 +1,129 @@
/*
* 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 kotlin.script.experimental.jvm.impl
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
import java.net.URLClassLoader
import kotlin.reflect.KClass
import kotlin.script.experimental.api.*
import kotlin.script.experimental.jvm.*
import kotlin.script.experimental.jvm.actualClassLoader
class KJvmCompiledScript<out ScriptBase : Any>(
sourceLocationId: String?,
compilationConfiguration: ScriptCompilationConfiguration,
private var scriptClassFQName: String,
otherScripts: List<CompiledScript<*>> = emptyList(),
var compiledModule: KJvmCompiledModule
) : CompiledScript<ScriptBase>, Serializable {
private var _sourceLocationId: String? = sourceLocationId
override val sourceLocationId: String?
get() = _sourceLocationId
private var _compilationConfiguration: ScriptCompilationConfiguration? = compilationConfiguration
override val compilationConfiguration: ScriptCompilationConfiguration
get() = _compilationConfiguration!!
private var _otherScripts: List<CompiledScript<*>> = otherScripts
override val otherScripts: List<CompiledScript<*>>
get() = _otherScripts
override suspend fun getClass(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics<KClass<*>> = try {
// ensuring proper defaults are used
val actualEvaluationConfiguration = scriptEvaluationConfiguration ?: ScriptEvaluationConfiguration()
val classLoader = getOrCreateActualClassloader(actualEvaluationConfiguration)
val clazz = classLoader.loadClass(scriptClassFQName).kotlin
clazz.asSuccess()
} catch (e: Throwable) {
ResultWithDiagnostics.Failure(
ScriptDiagnostic(
"Unable to instantiate class $scriptClassFQName",
sourcePath = sourceLocationId,
exception = e
)
)
}
private fun writeObject(outputStream: ObjectOutputStream) {
outputStream.writeObject(compilationConfiguration)
outputStream.writeObject(sourceLocationId)
outputStream.writeObject(otherScripts)
outputStream.writeObject(compiledModule)
outputStream.writeObject(scriptClassFQName)
}
@Suppress("UNCHECKED_CAST")
private fun readObject(inputStream: ObjectInputStream) {
_compilationConfiguration = inputStream.readObject() as ScriptCompilationConfiguration
_sourceLocationId = inputStream.readObject() as String?
_otherScripts = inputStream.readObject() as List<CompiledScript<*>>
compiledModule = inputStream.readObject() as KJvmCompiledModule
scriptClassFQName = inputStream.readObject() as String
}
companion object {
@JvmStatic
private val serialVersionUID = 2L
}
}
fun KJvmCompiledScript<*>.getOrCreateActualClassloader(evaluationConfiguration: ScriptEvaluationConfiguration): ClassLoader =
evaluationConfiguration[ScriptEvaluationConfiguration.jvm.actualClassLoader] ?: run {
val baseClassLoader = evaluationConfiguration[ScriptEvaluationConfiguration.jvm.baseClassLoader]
val classLoaderWithDeps =
if (evaluationConfiguration[ScriptEvaluationConfiguration.jvm.loadDependencies] == false) baseClassLoader
else makeClassLoaderFromDependencies(baseClassLoader)
compiledModule.createClassLoader(classLoaderWithDeps)
}
fun getConfigurationWithClassloader(
script: CompiledScript<*>, baseConfiguration: ScriptEvaluationConfiguration
): ScriptEvaluationConfiguration =
if (baseConfiguration.containsKey(ScriptEvaluationConfiguration.jvm.actualClassLoader))
baseConfiguration
else {
val jvmScript = (script as? KJvmCompiledScript<*>)
?: throw IllegalArgumentException("Unexpected compiled script type: $script")
val classloader = jvmScript.getOrCreateActualClassloader(baseConfiguration)
ScriptEvaluationConfiguration(baseConfiguration) {
ScriptEvaluationConfiguration.jvm.actualClassLoader(classloader)
if (baseConfiguration[ScriptEvaluationConfiguration.scriptsInstancesSharing] == true) {
ScriptEvaluationConfiguration.jvm.scriptsInstancesSharingMap(mutableMapOf())
}
}
}
val ScriptEvaluationConfiguration.sharedScripts get() = get(ScriptEvaluationConfiguration.jvm.scriptsInstancesSharingMap)
private fun CompiledScript<*>.makeClassLoaderFromDependencies(baseClassLoader: ClassLoader?): ClassLoader? {
val processedScripts = mutableSetOf<CompiledScript<*>>()
fun seq(res: Sequence<CompiledScript<*>>, script: CompiledScript<*>): Sequence<CompiledScript<*>> {
if (processedScripts.contains(script)) return res
processedScripts.add(script)
return script.otherScripts.asSequence().fold(res + script, ::seq)
}
val dependencies = seq(emptySequence(), this).flatMap { script ->
script.compilationConfiguration[ScriptCompilationConfiguration.dependencies]
?.asSequence()
?.flatMap { dep ->
(dep as? JvmDependency)?.classpath?.asSequence()?.map { it.toURI().toURL() } ?: emptySequence()
}
?: emptySequence()
}.distinct()
// TODO: previous dependencies and classloaders should be taken into account here
return if (dependencies.none()) baseClassLoader
else URLClassLoader(dependencies.toList().toTypedArray(), baseClassLoader)
}
@@ -0,0 +1,36 @@
/*
* 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.
*/
@file:Suppress("unused")
package kotlin.script.experimental.jvm
import kotlin.reflect.KClass
import kotlin.script.experimental.api.*
import kotlin.script.experimental.util.PropertiesCollection
interface JvmScriptEvaluationConfigurationKeys
open class JvmScriptEvaluationConfigurationBuilder : PropertiesCollection.Builder(), JvmScriptEvaluationConfigurationKeys {
companion object : JvmScriptEvaluationConfigurationBuilder()
}
/**
* The base classloader to use for script classes loading
*/
val JvmScriptEvaluationConfigurationKeys.baseClassLoader by PropertiesCollection.key<ClassLoader?>(Thread.currentThread().contextClassLoader)
/**
* Load script dependencies before evaluation, true by default
* If false, it is assumed that the all dependencies will be provided via baseClassLoader
*/
val JvmScriptEvaluationConfigurationKeys.loadDependencies by PropertiesCollection.key<Boolean>(true)
internal val JvmScriptEvaluationConfigurationKeys.actualClassLoader by PropertiesCollection.key<ClassLoader?>()
internal val JvmScriptEvaluationConfigurationKeys.scriptsInstancesSharingMap by PropertiesCollection.key<MutableMap<KClass<*>, EvaluationResult>>()
val ScriptEvaluationConfigurationKeys.jvm get() = JvmScriptEvaluationConfigurationBuilder()