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
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Jul 03 17:26:31 2013 +0530
+++ b/nashorn/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/nashorn/test/script/basic/JDK-8016667.js Wed Jul 03 17:26:31 2013 +0530
+++ b/nashorn/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/nashorn/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/nashorn/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/nashorn/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/nashorn/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/nashorn/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/nashorn/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();