Mercurial > people > rkennke > jdk9-shenandoah-final > nashorn
changeset 334:8f890b6bf6de
8015892: canBeUndefined too conservative for some use before declaration cases
Reviewed-by: attila, hannesw
author | lagergren |
---|---|
date | Mon, 10 Jun 2013 13:21:29 +0200 |
parents | 918a986b0478 |
children | a6f8ea57f048 |
files | src/jdk/nashorn/internal/codegen/Attr.java src/jdk/nashorn/internal/ir/Symbol.java test/script/basic/JDK-8015892.js test/script/basic/fib_wtf.js test/script/basic/fib_wtf.js.EXPECTED |
diffstat | 5 files changed, 176 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk/nashorn/internal/codegen/Attr.java Fri Jun 07 17:44:25 2013 +0200 +++ b/src/jdk/nashorn/internal/codegen/Attr.java Mon Jun 10 13:21:29 2013 +0200 @@ -202,18 +202,52 @@ private void acceptDeclarations(final FunctionNode functionNode, final Block body) { // This visitor will assign symbol to all declared variables, except function declarations (which are taken care // in a separate step above) and "var" declarations in for loop initializers. + // + // It also handles the case that a variable can be undefined, e.g + // if (cond) { + // x = x.y; + // } + // var x = 17; + // + // by making sure that no identifier has been found earlier in the body than the + // declaration - if such is the case the identifier is flagged as caBeUndefined to + // be safe if it turns into a local var. Otherwise corrupt bytecode results + body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { + private final Set<String> uses = new HashSet<>(); + private final Set<String> canBeUndefined = new HashSet<>(); + @Override public boolean enterFunctionNode(final FunctionNode nestedFn) { return false; } @Override + public Node leaveIdentNode(final IdentNode identNode) { + uses.add(identNode.getName()); + return identNode; + } + + @Override + public boolean enterVarNode(final VarNode varNode) { + final String name = varNode.getName().getName(); + //if this is used the var node symbol needs to be tagged as can be undefined + if (uses.contains(name)) { + canBeUndefined.add(name); + } + return true; + } + + @Override public Node leaveVarNode(final VarNode varNode) { // any declared symbols that aren't visited need to be typed as well, hence the list if (varNode.isStatement()) { final IdentNode ident = varNode.getName(); final Symbol symbol = defineSymbol(body, ident.getName(), IS_VAR); + if (canBeUndefined.contains(ident.getName())) { + symbol.setType(Type.OBJECT); + symbol.setCanBeUndefined(); + } functionNode.addDeclaredSymbol(symbol); if (varNode.isFunctionDeclaration()) { newType(symbol, FunctionNode.FUNCTION_TYPE);
--- a/src/jdk/nashorn/internal/ir/Symbol.java Fri Jun 07 17:44:25 2013 +0200 +++ b/src/jdk/nashorn/internal/ir/Symbol.java Mon Jun 10 13:21:29 2013 +0200 @@ -462,7 +462,7 @@ */ public void setCanBeUndefined() { assert type.isObject() : type; - if(!canBeUndefined()) { + if (!isParam() && !canBeUndefined()) {//parameters are never undefined assert !isShared(); flags |= CAN_BE_UNDEFINED; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8015892.js Mon Jun 10 13:21:29 2013 +0200 @@ -0,0 +1,38 @@ +/* + * 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-8015892.js : use before definition with valid declaration that turns into + * local var must be "canBeUndefined" + * + * @test + * @run + */ + +function doIt() { + if (something) { + x = x.obj; + } else { + var x = "x"; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/fib_wtf.js Mon Jun 10 13:21:29 2013 +0200 @@ -0,0 +1,38 @@ +/* + * 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. + */ + +/** + * fib_wtf - obfuscated fibonacci + * + * @test + * @run + */ + +function fib(_) { + for(_=[+[],++[[]][+[]],+[],_],_[++[++[++[[]][+[]]][+[]]][+[]]]=(((_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]]))&(((--[[]][+[]])>>>(++[[]][+[]]))))===(_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]])))?(_[++[++[[]][+[]]][+[]]]=++[[]][+[]],_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]])):+[];_[++[++[++[[]][+[]]][+[]]][+[]]]--;_[+[]]=(_[++[[]][+[]]]=_[++[++[[]][+[]]][+[]]]=_[+[]]+_[++[[]][+[]]])-_[+[]]); + return _[++[++[[]][+[]]][+[]]]; +} + +for (var x = -1; x <= 63; x++) { + print(fib(x)); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/fib_wtf.js.EXPECTED Mon Jun 10 13:21:29 2013 +0200 @@ -0,0 +1,65 @@ +0 +0 +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 +144 +233 +377 +610 +987 +1597 +2584 +4181 +6765 +10946 +17711 +28657 +46368 +75025 +121393 +196418 +317811 +514229 +832040 +1346269 +2178309 +3524578 +5702887 +9227465 +14930352 +24157817 +39088169 +63245986 +102334155 +165580141 +267914296 +433494437 +701408733 +1134903170 +1836311903 +2971215073 +4807526976 +7778742049 +12586269025 +20365011074 +32951280099 +53316291173 +86267571272 +139583862445 +225851433717 +365435296162 +591286729879 +956722026041 +1548008755920 +2504730781961 +4052739537881 +6557470319842