Merge SCI-MR-158: Fix name clash in strict mode; replace eval with new Function

This commit is contained in:
Alexander Nozik 2022-06-14 15:59:58 +00:00 committed by Space
commit a810790d8d
3 changed files with 15 additions and 20 deletions

View File

@ -36,7 +36,7 @@ public fun <T : Any> MST.compileToExpression(algebra: Algebra<T>): Expression<T>
)
}
return ESTreeBuilder<T> { visit(typed) }.instance
return ESTreeBuilder { visit(typed) }.instance
}
/**

View File

@ -14,37 +14,28 @@ internal class ESTreeBuilder<T>(val bodyCallback: ESTreeBuilder<T>.() -> BaseExp
private class GeneratedExpression<T>(val executable: dynamic, val constants: Array<dynamic>) : Expression<T> {
@Suppress("UNUSED_VARIABLE")
override fun invoke(arguments: Map<Symbol, T>): T {
//val e = executable
//val c = constants
val e = executable
val c = constants
val a = js("{}")
arguments.forEach { (key, value) -> a[key.identity] = value }
return executable.call(constants, a).unsafeCast<T>()
//return js("e(c, a)").unsafeCast<T>()
return js("e(c, a)").unsafeCast<T>()
}
}
@Suppress("UNUSED_VARIABLE")
val instance: Expression<T> by lazy {
val node = Program(
sourceType = "script",
VariableDeclaration(
kind = "var",
VariableDeclarator(
id = Identifier("executable"),
init = FunctionExpression(
params = arrayOf(Identifier("constants"), Identifier("arguments")),
body = BlockStatement(ReturnStatement(bodyCallback())),
),
),
),
ReturnStatement(bodyCallback())
)
eval(generate(node))
GeneratedExpression(js("executable"), constants.toTypedArray())
val code = generate(node)
GeneratedExpression(js("new Function('constants', 'arguments_0', code)"), constants.toTypedArray())
}
private val constants = mutableListOf<Any>()
fun constant(value: Any?) = when {
fun constant(value: Any?): BaseExpression = when {
value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" ->
SimpleLiteral(value)
@ -62,7 +53,8 @@ internal class ESTreeBuilder<T>(val bodyCallback: ESTreeBuilder<T>.() -> BaseExp
}
}
fun variable(name: Symbol): BaseExpression = call(getOrFail, Identifier("arguments"), SimpleLiteral(name.identity))
fun variable(name: Symbol): BaseExpression =
call(getOrFail, Identifier("arguments_0"), SimpleLiteral(name.identity))
fun call(function: Function<T>, vararg args: BaseExpression): BaseExpression = SimpleCallExpression(
optional = false,

View File

@ -3,6 +3,8 @@
* 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 space.kscience.kmath.internal.estree
internal fun Program(sourceType: String, vararg body: dynamic) = object : Program {
@ -28,9 +30,10 @@ internal fun Identifier(name: String) = object : Identifier {
override var name = name
}
internal fun FunctionExpression(params: Array<dynamic>, body: BlockStatement) = object : FunctionExpression {
internal fun FunctionExpression(id: Identifier?, params: Array<dynamic>, body: BlockStatement) = object : FunctionExpression {
override var params = params
override var type = "FunctionExpression"
override var id: Identifier? = id
override var body = body
}