8143304: Random failures when script size exceeds token limits
Reviewed-by: sundar, attila, lagergren
This commit is contained in:
parent
4897df19a3
commit
bc8fbeee55
@ -3323,9 +3323,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
|
||||
if (needsScope) {
|
||||
method.loadCompilerConstant(SCOPE);
|
||||
}
|
||||
|
||||
if (needsScope) {
|
||||
loadExpressionUnbounded(init);
|
||||
// block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
|
||||
final int flags = getScopeCallSiteFlags(identSymbol) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
|
||||
|
@ -103,6 +103,9 @@ public abstract class AbstractParser {
|
||||
* @param lineOffset Offset from which lines should be counted
|
||||
*/
|
||||
protected AbstractParser(final Source source, final ErrorManager errors, final boolean strict, final int lineOffset) {
|
||||
if (source.getLength() > Token.LENGTH_MASK) {
|
||||
throw new RuntimeException("Source exceeds size limit of " + Token.LENGTH_MASK + " bytes");
|
||||
}
|
||||
this.source = source;
|
||||
this.errors = errors;
|
||||
this.k = -1;
|
||||
|
@ -213,7 +213,6 @@ public class Lexer extends Scanner {
|
||||
* function body. This is used with the feature where the parser is skipping nested function bodies to
|
||||
* avoid reading ahead unnecessarily when we skip the function bodies.
|
||||
*/
|
||||
|
||||
public Lexer(final Source source, final int start, final int len, final TokenStream stream, final boolean scripting, final boolean es6, final boolean pauseOnFunctionBody) {
|
||||
super(source.getContent(), 1, start, len);
|
||||
this.source = source;
|
||||
|
@ -30,11 +30,21 @@ import static jdk.nashorn.internal.parser.TokenKind.LITERAL;
|
||||
import jdk.nashorn.internal.runtime.Source;
|
||||
|
||||
/**
|
||||
* Basic parse/lex unit.
|
||||
*
|
||||
* A token is a 64 bit long value that represents a basic parse/lex unit.
|
||||
* This class provides static methods to manipulate lexer tokens.
|
||||
*/
|
||||
public class Token {
|
||||
|
||||
/**
|
||||
* We use 28 bits for the position and 28 bits for the length of the token.
|
||||
* This limits the maximal length of code we can handle to 2 ^ 28 - 1 bytes.
|
||||
*/
|
||||
public final static int LENGTH_MASK = 0xfffffff;
|
||||
|
||||
// The first 8 bits are used for the token type, followed by length and position
|
||||
private final static int LENGTH_SHIFT = 8;
|
||||
private final static int POSITION_SHIFT = 36;
|
||||
|
||||
private Token() {
|
||||
}
|
||||
|
||||
@ -46,8 +56,9 @@ public class Token {
|
||||
* @return Token descriptor.
|
||||
*/
|
||||
public static long toDesc(final TokenType type, final int position, final int length) {
|
||||
return (long)position << 32 |
|
||||
(long)length << 8 |
|
||||
assert position <= LENGTH_MASK && length <= LENGTH_MASK;
|
||||
return (long)position << POSITION_SHIFT |
|
||||
(long)length << LENGTH_SHIFT |
|
||||
type.ordinal();
|
||||
}
|
||||
|
||||
@ -57,7 +68,7 @@ public class Token {
|
||||
* @return Start position of the token in the source.
|
||||
*/
|
||||
public static int descPosition(final long token) {
|
||||
return (int)(token >>> 32);
|
||||
return (int)(token >>> POSITION_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +109,7 @@ public class Token {
|
||||
* @return Length of the token.
|
||||
*/
|
||||
public static int descLength(final long token) {
|
||||
return (int)token >>> 8;
|
||||
return (int)((token >>> LENGTH_SHIFT) & LENGTH_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
41
nashorn/test/script/basic/JDK-8059934.js
Normal file
41
nashorn/test/script/basic/JDK-8059934.js
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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-8059934: Random failures when script size exceeds token limits
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
// Make sure that we can successfully evaluate a 100 MB string.
|
||||
// We don't go beyond that as we'd likely hit heap size limits.
|
||||
var src = "var x = 'ok';";
|
||||
for (var i = 0; i < 1000000; i++) {
|
||||
src += " ";
|
||||
}
|
||||
src += "x;";
|
||||
|
||||
Assert.assertEquals(100000015, src.length);
|
||||
Assert.assertEquals("ok", eval(src));
|
||||
|
Loading…
Reference in New Issue
Block a user