From: RBRi <rb...@us...> - 2018-08-10 06:10:33
|
- **status**: accepted --> closed - **Comment**: Many, many thanks for all the details. Have aplied your suggested fix and it seem to work fine. Waiting for more reports (and will try to work on your remaining stuff soon). Again thanks RBRi --- ** [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:** Sun Aug 05, 2018 05:07 PM 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. |