Область поврежденной функции Nashorn (es6) - PullRequest
4 голосов
/ 05 мая 2020

В настоящее время я исследую следующую проблему в скриптовом движке 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 устарел и будет удален.)

...