提交 5eb9cc9c 编写于 作者: L lagergren

8015892: canBeUndefined too conservative for some use before declaration cases

Reviewed-by: attila, hannesw
上级 fc80bd4d
......@@ -202,18 +202,52 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
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);
......
......@@ -462,7 +462,7 @@ public final class Symbol implements Comparable<Symbol> {
*/
public void setCanBeUndefined() {
assert type.isObject() : type;
if(!canBeUndefined()) {
if (!isParam() && !canBeUndefined()) {//parameters are never undefined
assert !isShared();
flags |= CAN_BE_UNDEFINED;
}
......
/*
* 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";
}
}
/*
* 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));
}
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册