Rhino 中 try/catch 中的 Eval 错误
好吧,我想我在 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');
当我在 OpenJDK 6 内置的 Rhino 中运行它时,我得到:
The value: 123
Error in second call: ReferenceError: "xyz" is not defined.
当我将 println 更改为 console.log 并在 Chrome 中运行它时,我更加确信这是一个错误,此时我得到 2 “值:123”日志,这正如我所期望的那样。
此外,我查找了 ECMAScript 标准 并得到这个:
10.4.2 输入评估代码
以下步骤执行时 控制进入执行上下文 对于评估代码:
- 如果没有调用上下文或者 eval 代码没有被执行 通过直接调用进行评估 (15.1.2.1.1) 到 eval 函数 然后,
- 像全局执行一样初始化执行上下文 使用 eval 代码作为 C 的上下文 10.4.1.1 中描述。
- 否则,
- 将 ThisBinding 设置为与 调用执行上下文。
- 将 LexicalEnvironment 设置为与 LexicalEnvironment 相同的值 调用执行上下文。
- 将 VariableEnvironment 设置为与 调用的变量环境 执行上下文。
- 如果 eval 代码是严格代码,则
- 令 strictVarEnv 为调用 NewDeclarativeEnvironment 的结果 传递 LexicalEnvironment 作为 论证。
- 将 LexicalEnvironment 设置为 strictVarEnv。
- 将 VariableEnvironment 设置为 strictVarEnv。
- 按照 10.5 中的描述执行声明绑定实例化 使用评估代码。
第一点是我的情况,或者“没有调用上下文”,所以这应该在全局上下文中进行评估,并且我的 xyz 变量应该可以正常工作。
我真的遇到了犀牛虫吗,还是我错过了什么?
Ok, I think I found a bug in Rhino. I am trying to dynamically eval code in the global scope, and it works fine if I just do eval.call(null, "code to eval"); All was well until I tried to capture exceptions. When I surround that code with try/catch, the code is not actually eval'ed in the global context.
To illustrate the bug:
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');
When I run this in the Rhino built into OpenJDK 6, I get:
The value: 123
Error in second call: ReferenceError: "xyz" is not defined.
I was more convinced of this being a bug when I changed the println's to console.log and ran it in Chrome, at which point I got 2 "The value: 123" logs, which is as I expect.
Furthermore, I looked up the ECMAScript standard and got this:
10.4.2 Entering Eval Code
The following steps are performed when
control enters the execution context
for eval code:
- If there is no calling context or if the eval code is not being
evaluated by a direct call
(15.1.2.1.1) to the eval function
then,
- Initialize the execution context as if it was a global execution
context using the eval code as C as
described in 10.4.1.1.- Else,
- Set the ThisBinding to the same value as the ThisBinding of the
calling execution context.- Set the LexicalEnvironment to the same value as the LexicalEnvironment
of the calling execution context.- Set the VariableEnvironment to the same value as the
VariableEnvironment of the calling
execution context.- If the eval code is strict code, then
- Let strictVarEnv be the result of calling NewDeclarativeEnvironment
passing the LexicalEnvironment as the
argument.- Set the LexicalEnvironment to strictVarEnv.
- Set the VariableEnvironment to strictVarEnv.
- Perform Declaration Binding Instantiation as described in 10.5
using the eval code.
The first point is my case, or "there is no calling context," so this should be eval'ed in the global context, and my xyz variable should work fine.
Have I truly hit a Rhino bug, or am I missing something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
JDK 中内置的 Rhino 代码确实非常非常旧,而且它有很多错误,这些错误在 Mozilla 的当前版本的软件中已经修复(很长一段时间)。
如果您正在开始一个新项目,我强烈建议您研究一下仅使用来自 Mozilla 的代码集成 Rhino 的情况,并相信 1.6 中的所有“ScriptEngine”内容都不存在(或者,可能的话,围绕 Mozilla 的东西实现您自己的 ScriptEngine 代码)。不要犯我犯过的同样的错误。两次。 :-(
The Rhino code built into the JDK is really, really old, and it has lots of bugs that have been fixed (for a long time) in the current release of the software from Mozilla.
If you're starting a new project, I would strongly recommend that you look into what it's like to integrate Rhino using only the from-Mozilla code, and just make believe that all the "ScriptEngine" stuff in 1.6 isn't there (or, possibly, implement your own ScriptEngine code around the Mozilla stuff). Don't make the same mistake I made. Twice. :-(