Fix name clash in strict mode; replace eval with new Function

This commit is contained in:
Iaroslav Postovalov 2022-06-14 22:52:47 +07:00
parent 85a1e8b33f
commit b09127f090
No known key found for this signature in database
GPG Key ID: 46E15E4A31B3BCD7
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> { private class GeneratedExpression<T>(val executable: dynamic, val constants: Array<dynamic>) : Expression<T> {
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
override fun invoke(arguments: Map<Symbol, T>): T { override fun invoke(arguments: Map<Symbol, T>): T {
//val e = executable val e = executable
//val c = constants val c = constants
val a = js("{}") val a = js("{}")
arguments.forEach { (key, value) -> a[key.identity] = value } 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 instance: Expression<T> by lazy {
val node = Program( val node = Program(
sourceType = "script", sourceType = "script",
VariableDeclaration( ReturnStatement(bodyCallback())
kind = "var",
VariableDeclarator(
id = Identifier("executable"),
init = FunctionExpression(
params = arrayOf(Identifier("constants"), Identifier("arguments")),
body = BlockStatement(ReturnStatement(bodyCallback())),
),
),
),
) )
eval(generate(node)) val code = generate(node)
GeneratedExpression(js("executable"), constants.toTypedArray()) GeneratedExpression(js("new Function('constants', 'arguments_0', code)"), constants.toTypedArray())
} }
private val constants = mutableListOf<Any>() 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" -> value == null || jsTypeOf(value) == "number" || jsTypeOf(value) == "string" || jsTypeOf(value) == "boolean" ->
SimpleLiteral(value) 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( fun call(function: Function<T>, vararg args: BaseExpression): BaseExpression = SimpleCallExpression(
optional = false, 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. * 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 package space.kscience.kmath.internal.estree
internal fun Program(sourceType: String, vararg body: dynamic) = object : Program { 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 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 params = params
override var type = "FunctionExpression" override var type = "FunctionExpression"
override var id: Identifier? = id
override var body = body override var body = body
} }