Ошибка Eval в Rhino внутри try / catch - PullRequest
2 голосов
/ 04 июня 2011

Хорошо, я думаю, что нашел ошибку в Rhino. Я пытаюсь динамически вывести код в глобальной области видимости, и он отлично работает, если я просто сделаю eval.call (null, "code to eval"); Все было хорошо, пока я не попытался зафиксировать исключения. Когда я окружаю этот код командой try / catch, код фактически не оценивается в глобальном контексте.

Для иллюстрации ошибки:

function works(str) {
  eval.call(null, str);
}

function doesntWork(str, count) {
  try {
    eval.call(null, str);
  } catch (e) {
    println('Error in ' + count + ' call: ' + e);
  }
}

works('var abc = 123;');
works('println("The value: " + abc);');
doesntWork('var xyz = 123;', 'first');
doesntWork('println("The value: " + xyz);', 'second');

Когда я запускаю это в Rhino, встроенном в OpenJDK 6, я получаю:

The value: 123
Error in second call: ReferenceError: "xyz" is not defined.

Я был более убежден в том, что это ошибка, когда я изменил println на console.log и запустил его в Chrome, после чего я получил 2 журнала «Значение: 123», что, как я и ожидал.

Кроме того, я посмотрел стандарт ECMAScript и получил:

10.4.2 Ввод кода Eval *

Следующие шаги выполняются, когда управление входит в контекст выполнения для электронного кода:

  1. Если нет вызывающего контекста или не используется код eval оценивается прямым звонком (15.1.2.1.1) к функции eval затем,
    1. Инициализировать контекст выполнения, как если бы это было глобальное выполнение контекст, используя eval-код как C как описано в 10.4.1.1.
  2. прочее,
    1. Установите для ThisBinding то же значение, что и для ThisBinding вызывающий контекст выполнения.
    2. Установите для LexicalEnvironment то же значение, что и для LexicalEnvironment контекста выполнения вызова.
    3. Установите для VariableEnvironment то же значение, что и для VariableEnvironment вызывающего контекст выполнения.
  3. Если eval-код является строгим, то
    1. Пусть strictVarEnv будет результатом вызова NewDeclarativeEnvironment прохождение LexicalEnvironment как аргумент.
    2. Установите для LexicalEnvironment значение strictVarEnv.
    3. Установите для VariableEnvironment значение strictVarEnv.
  4. Выполните декларирование привязки, как описано в 10.5 используя eval-код.

Первый пункт - это мой случай, или «нет контекста вызова», так что это должно быть оценено в глобальном контексте, и моя переменная xyz должна работать нормально.

Действительно ли я столкнулся с ошибкой Rhino или я что-то упустил?

1 Ответ

2 голосов
/ 04 июня 2011

Код Rhino, встроенный в JDK, действительно очень старый, и в нем много ошибок, которые были исправлены (надолго) в текущем выпуске программного обеспечения от Mozilla.

Если вы начинаете новый проект, я настоятельно рекомендую вам посмотреть, как это интегрировать Rhino, используя только код from-Mozilla, и просто поверить, что все вещи "ScriptEngine" в 1.6 там (или, возможно, реализовать свой собственный код ScriptEngine вокруг вещей Mozilla). Не делай ту же ошибку, что и я. Дважды. : - (

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...