В настоящее время я исследую следующую проблему в скриптовом движке Nashorn js и буду признателен за ваш вклад. Следующий фрагмент кода не выполняется (код в Kotlin):
fun main() {
val brokenScript = """
function fn() {
const object1 = { "name": "Pepa" };
print(object1.name);
const descriptor1 = Object.getOwnPropertyDescriptor(object1, 'name');
print(descriptor1.configurable);
print(eval("3+1"));
}
fn();
""".trimIndent()
NashornScriptEngineFactory()
.getScriptEngine("--no-deprecation-warning", "--language=es6", "--log=compiler:finest,fields,recompile:fine")
.let { (it as Compilable).compile(brokenScript) }
.also { script -> script.eval() }
}
Ошибка:
Exception in thread "main" javax.script.ScriptException: ReferenceError: "descriptor1" is not defined in <eval> at line number 8
at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:477)
at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:461)
at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine$3.eval(NashornScriptEngine.java:517)
at java.scripting/javax.script.CompiledScript.eval(CompiledScript.java:103)
at MainKt.main(Main.kt:19)
at MainKt.main(Main.kt)
Caused by: <eval>:8 ReferenceError: "descriptor1" is not defined
at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:319)
at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:291)
at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:278)
at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.AccessorProperty.checkUndeclared(AccessorProperty.java:571)
...
Наблюдения:
- проблема зависит от функции eval - помогает исключить ее из скрипта - также необходимо вложить в функцию - отлично работает на верхнем уровне
- проблема зависит от Функция Object.getOwnPropertyDescriptor - исключение ее из скрипта помогает
- проблема зависит от области видимости - изменение объявления переменной с области действия ( const / let ) на не заданную var помогает
- журнал вывода содержит
caught RewriteException [pp=3, type=object, value='Pepa')]
Текущая гипотеза:
Object.getOwnPropertyDescriptor функция вызывает UnwarrantedOptimismException , который заставляет функцию перекомпилировать. Объем перекомпилированного скрипта поврежден. Обычно область видимости управляется использованием функции eval , поэтому она может объявлять переменные - возможно, это неправильно решается во время перекомпиляции во время выполнения. Не удается получить доступ к переменным с ограниченной областью действия.
На какой результат я надеюсь? (В порядке предпочтения)
- он работает так же, как и при выполнении в узле - очевидно, * 1049 Проблема *
- определяется во время компиляции без отключения функций es6
- отключение функции eval предотвращает проблему - я пробовал это, удалив eval из объекта Bindings, но скрипт поврежден на этапе компиляции и измененные привязки передаются позже в
script.eval(bindings)
- поэтому скрипт по-прежнему терпит неудачу до достижения строки eval - (это на самом деле то, чего я пытаюсь избежать), обходя проблему путем отключения функций es6 (удаление - language = es6 - это приводит к сбою скрипта во время компиляции из-за использования переменных с ограниченной областью ( const / let )
(я знаю, что nashorn устарел и будет удален.)