changeset 412:961cffae0828

8019811: Static calls - self referential functions needed a return type conversion if they were specialized, as they can't use the same mechanism as indy calls Reviewed-by: sundar, jlaskey
author lagergren
date Wed, 03 Jul 2013 15:46:03 +0200
parents eb1437d16ab4
children fcb484c43348 be2087629eb9
files src/jdk/nashorn/internal/codegen/CodeGenerator.java test/script/basic/JDK-8016667.js test/script/basic/JDK-8019808.js test/script/basic/JDK-8019810.js test/script/basic/JDK-8019810.js.EXPECTED test/script/basic/JDK-8019811.js test/script/basic/JDK-8019817.js test/script/currently-failing/JDK-8019809.js
diffstat 8 files changed, 228 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Jul 03 17:26:31 2013 +0530
+++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Jul 03 15:46:03 2013 +0200
@@ -578,6 +578,7 @@
         final Node         function        = callNode.getFunction();
         final Block        currentBlock    = lc.getCurrentBlock();
         final CodeGeneratorLexicalContext codegenLexicalContext = lc;
+        final Type         callNodeType    = callNode.getType();
 
         function.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
 
@@ -593,7 +594,7 @@
                 }
                 loadArgs(args);
                 final Type[] paramTypes = method.getTypesFromStack(args.size());
-                final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNode.getType(), paramTypes, scopeCallFlags);
+                final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNodeType, paramTypes, scopeCallFlags);
                 return scopeCall.generateInvoke(method);
             }
 
@@ -602,7 +603,7 @@
                 method.convert(Type.OBJECT); // foo() makes no sense if foo == 3
                 // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
                 method.loadNull(); //the 'this'
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), flags);
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
             }
 
             private void evalCall(final IdentNode node, final int flags) {
@@ -634,14 +635,14 @@
 
                 // direct call to Global.directEval
                 globalDirectEval();
-                method.convert(callNode.getType());
+                method.convert(callNodeType);
                 method._goto(eval_done);
 
                 method.label(not_eval);
                 // This is some scope 'eval' or global eval replaced by user
                 // but not the built-in ECMAScript 'eval' function call
                 method.loadNull();
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), flags);
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
 
                 method.label(eval_done);
             }
@@ -666,7 +667,7 @@
                     } else {
                         sharedScopeCall(node, flags);
                     }
-                    assert method.peekType().equals(callNode.getType()) : method.peekType() + "!=" + callNode.getType();
+                    assert method.peekType().equals(callNodeType) : method.peekType() + "!=" + callNode.getType();
                 } else {
                     enterDefault(node);
                 }
@@ -681,8 +682,8 @@
                 method.dup();
                 method.dynamicGet(node.getType(), node.getProperty().getName(), getCallSiteFlags(), true);
                 method.swap();
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags());
-                assert method.peekType().equals(callNode.getType());
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags());
+                assert method.peekType().equals(callNodeType);
 
                 return false;
             }
@@ -707,6 +708,7 @@
                 assert callee.getCompileUnit() != null : "no compile unit for " + callee.getName() + " " + Debug.id(callee) + " " + callNode;
                 method.invokestatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature);
                 assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType();
+                method.convert(callNodeType);
                 return false;
             }
 
@@ -722,7 +724,7 @@
                 }
                 method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
                 method.swap();
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags());
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags());
                 assert method.peekType().equals(callNode.getType());
 
                 return false;
@@ -734,7 +736,7 @@
                 load(function);
                 method.convert(Type.OBJECT); //TODO, e.g. booleans can be used as functions
                 method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
-                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
+                method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
                 assert method.peekType().equals(callNode.getType());
 
                 return false;
--- a/test/script/basic/JDK-8016667.js	Wed Jul 03 17:26:31 2013 +0530
+++ b/test/script/basic/JDK-8016667.js	Wed Jul 03 15:46:03 2013 +0200
@@ -32,3 +32,23 @@
     var friends = 1;
     (joe = friends) == null;
 } 
+
+//JDK-8019476 duplicate case of this
+Function("with(\nnull == (this % {}))( /x/g );"); 
+
+function f() {
+    with(null == (this % {}))(/x/g);
+}
+
+Function("return (null != [,,] <= this);"); 
+
+function f2() {
+    return (null != [,,] <= this);
+}
+
+Function("/*infloop*/L:for(var x; ([+(function (window)[,,])(function(q) { return q; }, -0)].some(new Function)); [11,12,13,14].some) {/*infloop*/do {;return this; } while(x); }"); 
+
+function f3() {
+    /*infloop*/L:for(var x; ([+(function (window)[,,])(function(q) { return q; }, -0)].some(new Function)); [11,12,13,14].some) {/*infloop*/do {;return this; } while(x); }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8019808.js	Wed Jul 03 15:46:03 2013 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8019808: Switch on empty array breaks codegen
+ *
+ * @test
+ * @run
+ */
+
+Function("switch([]) { case 7: }"); 
+
+function f() {
+    switch([]) {
+    case 7:
+    }
+}
+
+f();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8019810.js	Wed Jul 03 15:46:03 2013 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8019810: Assertion error in attr in function body
+ *
+ * @test
+ * @run
+ */
+
+Function("return (void ({ set each (x2)y }));");
+
+function f() {
+    return (void ({ set each (x2)y }));
+}
+print(f());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8019810.js.EXPECTED	Wed Jul 03 15:46:03 2013 +0200
@@ -0,0 +1,1 @@
+undefined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8019811.js	Wed Jul 03 15:46:03 2013 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8019811: Number coercion for return values of static calls was broken
+ *
+ * @test
+ * @run
+ */
+
+function f(x) {
+    var window = 17;
+    return function (x) { 
+	return true 
+    } (x) >> window;
+}
+
+Function("L:if((function x ()3)() + arguments++) {return; } else if (new gc()) while(((x2.prop = functional)) && 0){ }"); 
+
+Function("var x = x -= '' "); 
+
+Function("switch((Math.pow ? x = 1.2e3 : 3)) { default: return; }") 
+
+Function("x = 0.1, x\ntrue\n~this");
+
+Function("with((function (x)x2)() ^ this){return; }");
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8019817.js	Wed Jul 03 15:46:03 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8019817: More number coercion issues
+ *
+ * @test
+ * @run
+ */
+var y = 17.17;
+
+Function("return y % function(q) { return q; }();"); 
+
+function f() {
+    return y % function(q) { return q; }();
+}
+f();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/currently-failing/JDK-8019809.js	Wed Jul 03 15:46:03 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8019809: Break return combo that generates erroneous bytecode
+ *
+ * @test
+ * @run
+ */
+
+//Function("L: {break L;return; }"); 
+
+function f() {
+    L: { break L; return; }
+}
+
+f();