From: RBRi <rb...@us...> - 2018-08-10 06:11:22
|
BTW: will inform on twitter if a new SNASPHOT build is available --- ** [bugs:#1980] [corejs] Quirky handling of named function expression** **Status:** closed **Group:** Latest SVN **Created:** Sun Aug 05, 2018 12:28 PM UTC by Atsushi Nakagawa **Last Updated:** Fri Aug 10, 2018 06:10 AM UTC **Owner:** RBRi **Attachments:** - [test1.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test1.html) (194 Bytes; text/html) - [test2.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test2.html) (275 Bytes; text/html) - [test3.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test3.html) (227 Bytes; text/html) - [test4.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test4.html) (182 Bytes; text/html) - [test5.html](https://sourceforge.net/p/htmlunit/bugs/1980/attachment/test5.html) (1.2 kB; text/html) Attached are five tests for testing various aspects of **[named function expressions](https://stackoverflow.com/questions/15336347)** in htmlunit. As at 2.32, support for them are *quirky*, leading to subtly misinterpreted JS that are hard to debug. For example, the following code from `test1.html` incorrectly throws a `ScriptException: ReferenceError: Assignment to undefined "abc" in strict mode` on the second line. ```javascript 'use strict'; var abc = 1; var foo = function abc() {} ``` This code from `test2.html` should print `a` followed by `b`. Instead `b` is printed twice. (Unfortunatley, code like this is all too common for minimized scripts.) ```javascript var a = function () { var x = (function x () { console.log("a") }) return function () { x() } }() var b = function () { var x = (function x () { console.log("b") }) return function () { x() } }() a() b() ``` ### Test cases Five tests `test1.html` to `test5.html` are attached. Expectations are as follows: `test1.html`: ```java final String[] expected = { "INFO: outer abc = 1.0", "INFO: inner abc = (function abc() { console.log(\"inner abc = \", abc); })", }; ``` `test2.html`: ```java final String[] expected = { "INFO: a", "INFO: b", }; ``` `test3.html`: ```java final String[] expected = { "INFO: a", }; ``` `test4.html`: ```java final String[] expected = { "INFO: (function func() { console.log(func); })", "INFO: outer", }; ``` `test5.html`: ```java final String[] expected = { "INFO: f1", "INFO: f2", "INFO: f3", "INFO: !f4", "INFO: f5", "INFO: !f6", "INFO: !f7", "INFO: !f8", "INFO: f10", "INFO: f11", "INFO: f12", "INFO: f10", // Chrome/FF: !f10 "INFO: f11", "INFO: f12", "INFO: f13", }; ``` ### Possible fix While rhino far surpasses my coding ability, asashour [seems to have](https://github.com/HtmlUnit/htmlunit-rhino-fork/commit/afadfd48770eace84c70f503efef66c5767c9a3b) already added the [necessary building block](https://github.com/HtmlUnit/htmlunit-rhino-fork/blob/e7ce0f761305d876f99a323a27214f064c5fb4f3/src/org/mozilla/javascript/InterpreterData.java#L98) for this. The following is the code I'm using to further this for a fix: ```diff --- a/src/main/java/net/sourceforge/htmlunit/corejs/javascript/CodeGenerator.java +++ b/src/main/java/net/sourceforge/htmlunit/corejs/javascript/CodeGenerator.java @@ -6,12 +6,12 @@ package net.sourceforge.htmlunit.corejs.javascript; -import net.sourceforge.htmlunit.corejs.javascript.ast.AstNode; -import net.sourceforge.htmlunit.corejs.javascript.ast.FunctionCall; +import net.sourceforge.htmlunit.corejs.javascript.ast.AstRoot; +import net.sourceforge.htmlunit.corejs.javascript.ast.Block; import net.sourceforge.htmlunit.corejs.javascript.ast.FunctionNode; import net.sourceforge.htmlunit.corejs.javascript.ast.Jump; +import net.sourceforge.htmlunit.corejs.javascript.ast.Scope; import net.sourceforge.htmlunit.corejs.javascript.ast.ScriptNode; -import net.sourceforge.htmlunit.corejs.javascript.ast.UnaryExpression; import net.sourceforge.htmlunit.corejs.javascript.ast.VariableInitializer; /** @@ -197,11 +197,10 @@ private void generateNestedFunctions() gen.itsData = new InterpreterData(itsData); gen.generateFunctionICode(); array[i] = gen.itsData; - if (fn.getParent() instanceof FunctionCall) { - AstNode grandParent = fn.getParent().getParent(); - if (grandParent instanceof UnaryExpression && grandParent.getType() == Token.NOT) { - gen.itsData.declaredAsFunctionExpression = true; - } + if (!(fn.getParent() instanceof AstRoot || + fn.getParent() instanceof Scope || + fn.getParent() instanceof Block)) { + gen.itsData.declaredAsFunctionExpression = true; } } itsData.itsNestedFunctions = array; ``` --- Sent from sourceforge.net because htm...@li... is subscribed to https://sourceforge.net/p/htmlunit/bugs/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/htmlunit/admin/bugs/options. Or, if this is a mailing list, you can unsubscribe from the mailing list. |