From 53756a7a9b1be2d8936e686fbf48108d10e726c1 Mon Sep 17 00:00:00 2001 From: sundar Date: Wed, 18 Sep 2013 13:06:17 +0530 Subject: 8024972: for (LeftHandSideExpression in Expression) crashes the compiler Reviewed-by: lagergren, hannesw --- .../nashorn/internal/codegen/CodeGenerator.java | 1 - test/script/basic/JDK-8024972.js | 43 ++++++++++++++++++++++ test/script/basic/JDK-8024972.js.EXPECTED | 6 +++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/script/basic/JDK-8024972.js create mode 100644 test/script/basic/JDK-8024972.js.EXPECTED diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 809b2ec2..6307e2f9 100644 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -852,7 +852,6 @@ final class CodeGenerator extends NodeOperatorVisitor"+ arr[obj.x]); +} + +var abc = { foo: 'bar', hello: 'world' }; +for (obj.x in abc) { + print(obj.x + "->" + abc[obj.x]); +} + +for (obj.x in 0) {} diff --git a/test/script/basic/JDK-8024972.js.EXPECTED b/test/script/basic/JDK-8024972.js.EXPECTED new file mode 100644 index 00000000..aa4692fb --- /dev/null +++ b/test/script/basic/JDK-8024972.js.EXPECTED @@ -0,0 +1,6 @@ +0->2 +1->45 +2->-1 +3->445 +foo->bar +hello->world -- cgit v1.2.3 From 28dcd656aa85b84f4e29875d65918939b1e1e3b2 Mon Sep 17 00:00:00 2001 From: sundar Date: Wed, 18 Sep 2013 16:36:25 +0530 Subject: 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException Reviewed-by: jlaskey, hannesw --- .../nashorn/api/scripting/NashornScriptEngine.java | 69 +++++++++++++--------- src/jdk/nashorn/internal/runtime/Source.java | 2 +- test/script/trusted/JDK-8008305.js | 2 +- .../nashorn/api/scripting/ScriptEngineTest.java | 13 ++++ 4 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 45eddd11..4629665f 100644 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -185,21 +185,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C @Override public Object eval(final Reader reader, final ScriptContext ctxt) throws ScriptException { - try { - if (reader instanceof URLReader) { - final URL url = ((URLReader)reader).getURL(); - final Charset cs = ((URLReader)reader).getCharset(); - return evalImpl(compileImpl(new Source(url.toString(), url, cs), ctxt), ctxt); - } - return evalImpl(Source.readFully(reader), ctxt); - } catch (final IOException e) { - throw new ScriptException(e); - } + return evalImpl(makeSource(reader, ctxt), ctxt); } @Override public Object eval(final String script, final ScriptContext ctxt) throws ScriptException { - return evalImpl(script.toCharArray(), ctxt); + return evalImpl(makeSource(script, ctxt), ctxt); } @Override @@ -221,16 +212,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C @Override public CompiledScript compile(final Reader reader) throws ScriptException { - try { - return asCompiledScript(compileImpl(Source.readFully(reader), context)); - } catch (final IOException e) { - throw new ScriptException(e); - } + return asCompiledScript(makeSource(reader, context)); } @Override public CompiledScript compile(final String str) throws ScriptException { - return asCompiledScript(compileImpl(str.toCharArray(), context)); + return asCompiledScript(makeSource(str, context)); } // Invocable methods @@ -292,6 +279,29 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // Implementation only below this point + private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException { + try { + if (reader instanceof URLReader) { + final URL url = ((URLReader)reader).getURL(); + final Charset cs = ((URLReader)reader).getCharset(); + return new Source(url.toString(), url, cs); + } else { + return new Source(getScriptName(ctxt), Source.readFully(reader)); + } + } catch (final IOException ioExp) { + throw new ScriptException(ioExp); + } + } + + private static Source makeSource(final String src, final ScriptContext ctxt) { + return new Source(getScriptName(ctxt), src); + } + + private static String getScriptName(final ScriptContext ctxt) { + final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); + return (val != null) ? val.toString() : ""; + } + private T getInterfaceInner(final Object thiz, final Class clazz) { if (clazz == null || !clazz.isInterface()) { throw new IllegalArgumentException(getMessage("interface.class.expected")); @@ -429,7 +439,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // current ScriptContext exposed as "context" // "context" is non-writable from script - but script engine still // needs to set it and so save the context Property object - contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, null); + contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, ctxt); // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property // in the Global of a Context we just created - both the Context and the Global were just created and can not be @@ -509,8 +519,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("interface.on.non.script.object")); } - private Object evalImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException { - return evalImpl(compileImpl(buf, ctxt), ctxt); + private Object evalImpl(final Source src, final ScriptContext ctxt) throws ScriptException { + return evalImpl(compileImpl(src, ctxt), ctxt); } private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException { @@ -561,11 +571,20 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } } - private CompiledScript asCompiledScript(final ScriptFunction script) { + private CompiledScript asCompiledScript(final Source source) throws ScriptException { + final ScriptFunction func = compileImpl(source, context); return new CompiledScript() { @Override public Object eval(final ScriptContext ctxt) throws ScriptException { - return evalImpl(script, ctxt); + final ScriptObject global = getNashornGlobalFrom(ctxt); + // Are we running the script in the correct global? + if (func.getScope() == global) { + return evalImpl(func, ctxt, global); + } else { + // ScriptContext with a different global. Compile again! + // Note that we may still hit per-global compilation cache. + return evalImpl(compileImpl(source, ctxt), ctxt, global); + } } @Override public ScriptEngine getEngine() { @@ -574,12 +593,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C }; } - private ScriptFunction compileImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException { - final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); - final String fileName = (val != null) ? val.toString() : ""; - return compileImpl(new Source(fileName, buf), ctxt); - } - private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException { return compileImpl(source, getNashornGlobalFrom(ctxt)); } diff --git a/src/jdk/nashorn/internal/runtime/Source.java b/src/jdk/nashorn/internal/runtime/Source.java index 7e3c8684..9273e7a8 100644 --- a/src/jdk/nashorn/internal/runtime/Source.java +++ b/src/jdk/nashorn/internal/runtime/Source.java @@ -169,7 +169,7 @@ public final class Source { final Source src = (Source)obj; // Only compare content as a last resort measure - return length == src.length && Objects.equals(name, src.name) && Arrays.equals(content, src.content); + return length == src.length && Objects.equals(url, src.url) && Objects.equals(name, src.name) && Arrays.equals(content, src.content); } @Override diff --git a/test/script/trusted/JDK-8008305.js b/test/script/trusted/JDK-8008305.js index e4d052cb..d57b5208 100644 --- a/test/script/trusted/JDK-8008305.js +++ b/test/script/trusted/JDK-8008305.js @@ -54,6 +54,6 @@ try { fail("Expected SecurityException from script!"); } catch (e) { if (! (e instanceof SecurityException)) { - faile("Expected SecurityException, but got " + e); + fail("Expected SecurityException, but got " + e); } } diff --git a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java index 416669fb..99207de0 100644 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java @@ -37,10 +37,12 @@ import java.lang.reflect.Method; import java.util.concurrent.Callable; import javax.script.Compilable; import javax.script.CompiledScript; +import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; import javax.script.ScriptException; +import javax.script.SimpleScriptContext; import org.testng.annotations.Test; /** @@ -230,6 +232,17 @@ public class ScriptEngineTest { } } + @Test + public void compileAndEvalInDiffContextTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine = m.getEngineByName("js"); + final Compilable compilable = (Compilable) engine; + final CompiledScript compiledScript = compilable.compile("foo"); + final ScriptContext ctxt = new SimpleScriptContext(); + ctxt.setAttribute("foo", "hello", ScriptContext.ENGINE_SCOPE); + assertEquals(compiledScript.eval(ctxt), "hello"); + } + @Test public void accessGlobalTest() { final ScriptEngineManager m = new ScriptEngineManager(); -- cgit v1.2.3 From 2f75e564a4a73d4a04ff816644257db5ad7736e6 Mon Sep 17 00:00:00 2001 From: sundar Date: Thu, 19 Sep 2013 13:34:01 +0530 Subject: 8025048: true as case label results in ClassCastException Reviewed-by: lagergren --- src/jdk/nashorn/internal/codegen/Attr.java | 6 +++-- test/script/basic/JDK-8025048-2.js | 36 ++++++++++++++++++++++++++++++ test/script/basic/JDK-8025048.js | 36 ++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 test/script/basic/JDK-8025048-2.js create mode 100644 test/script/basic/JDK-8025048.js diff --git a/src/jdk/nashorn/internal/codegen/Attr.java b/src/jdk/nashorn/internal/codegen/Attr.java index 813d3fc9..55355c3e 100644 --- a/src/jdk/nashorn/internal/codegen/Attr.java +++ b/src/jdk/nashorn/internal/codegen/Attr.java @@ -807,9 +807,11 @@ final class Attr extends NodeOperatorVisitor { type = Type.OBJECT; } - type = Type.widest(type, newCaseNode.getTest().getType()); - if (type.isBoolean()) { + final Type newCaseType = newCaseNode.getTest().getType(); + if (newCaseType.isBoolean()) { type = Type.OBJECT; //booleans and integers aren't assignment compatible + } else { + type = Type.widest(type, newCaseType); } } diff --git a/test/script/basic/JDK-8025048-2.js b/test/script/basic/JDK-8025048-2.js new file mode 100644 index 00000000..c11816ba --- /dev/null +++ b/test/script/basic/JDK-8025048-2.js @@ -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-8025048: true as case label results in ClassCastException + * + * @test + * @run + */ + +function func(x) { + switch(x) { + case 8: break; case false: + } +} + diff --git a/test/script/basic/JDK-8025048.js b/test/script/basic/JDK-8025048.js new file mode 100644 index 00000000..75838a98 --- /dev/null +++ b/test/script/basic/JDK-8025048.js @@ -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-8025048: true as case label results in ClassCastException + * + * @test + * @run + */ + +function func(x) { + switch(x) { + case 8: break; case true: + } +} + -- cgit v1.2.3 From 78be1c71a19ad710a528b995e02b0735269800cb Mon Sep 17 00:00:00 2001 From: hannesw Date: Thu, 19 Sep 2013 15:39:01 +0200 Subject: 8023154: compileAllTests fails with: 2 tests failed to compile Reviewed-by: sundar, jlaskey --- make/build-benchmark.xml | 8 ++++---- make/build.xml | 14 ++++++++------ make/project.properties | 7 ++++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/make/build-benchmark.xml b/make/build-benchmark.xml index f1ce180a..8f2296b0 100644 --- a/make/build-benchmark.xml +++ b/make/build-benchmark.xml @@ -329,7 +329,7 @@ fork="true" dir="."> - + @@ -357,7 +357,7 @@ classpath="${run.test.classpath}" fork="true" dir="."> - + @@ -391,7 +391,7 @@ fork="true" dir="."> - + @@ -415,7 +415,7 @@ classpath="${run.test.classpath}" fork="true" dir="."> - + diff --git a/make/build.xml b/make/build.xml index 73644a6b..4bc1a398 100644 --- a/make/build.xml +++ b/make/build.xml @@ -66,6 +66,8 @@ + + @@ -320,7 +322,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -336,7 +338,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -352,7 +354,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -369,7 +371,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -387,7 +389,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { description="Run the shell with a sample script"> - + @@ -397,7 +399,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { description="Debug the shell with a sample script"> - + diff --git a/make/project.properties b/make/project.properties index 5523f6cb..e6eea02e 100644 --- a/make/project.properties +++ b/make/project.properties @@ -216,13 +216,14 @@ run.test.classpath=\ src.dir=src test.src.dir=test/src +# -Xmx is used for all tests, -Xms only for octane benchmark run.test.xmx=3G run.test.xms=2G run.test.user.language=tr run.test.user.country=TR -run.test.jvmargs.common=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError +run.test.jvmargs.common=-server -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError #-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M # -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods @@ -231,12 +232,12 @@ run.test.jvmargs.common=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -Dfil run.test.jvmargs.main=${run.test.jvmargs.common} -ea #-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M -run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.common} +run.test.jvmargs.octane.main=${run.test.jvmargs.common} run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy # VM options for script tests with @fork option -test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} ${run.test.jvmsecurityargs} +test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} # path of rhino.jar for benchmarks rhino.jar= -- cgit v1.2.3 From 10c99144276815d60438241ab420e2f94cd031de Mon Sep 17 00:00:00 2001 From: sundar Date: Thu, 19 Sep 2013 21:20:47 +0530 Subject: 8025080: Object literal getter, setter function with number format property name results in ClassFormatError Reviewed-by: lagergren, hannesw --- src/jdk/nashorn/internal/ir/debug/JSONWriter.java | 3 +- src/jdk/nashorn/internal/parser/Parser.java | 5 ++- test/script/basic/JDK-8025080.js | 43 ++++++++++++++++++++++ test/script/basic/JDK-8025080.js.EXPECTED | 4 ++ test/script/basic/parser/objectLitExpr.js.EXPECTED | 10 +---- 5 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 test/script/basic/JDK-8025080.js create mode 100644 test/script/basic/JDK-8025080.js.EXPECTED diff --git a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index dabc7e36..4702057a 100644 --- a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -410,7 +410,8 @@ public final class JSONWriter extends NodeVisitor { comma(); property("id"); - if (functionNode.isAnonymous()) { + final FunctionNode.Kind kind = functionNode.getKind(); + if (functionNode.isAnonymous() || kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) { nullValue(); } else { functionNode.getIdent().accept(this); diff --git a/src/jdk/nashorn/internal/parser/Parser.java b/src/jdk/nashorn/internal/parser/Parser.java index d0519171..9663401f 100644 --- a/src/jdk/nashorn/internal/parser/Parser.java +++ b/src/jdk/nashorn/internal/parser/Parser.java @@ -59,6 +59,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import jdk.internal.dynalink.support.NameCodec; import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.ir.AccessNode; @@ -2108,7 +2109,7 @@ loop: case "get": final PropertyKey getIdent = propertyName(); final String getterName = getIdent.getPropertyName(); - final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + getterName); + final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + NameCodec.encode(getterName)); expect(LPAREN); expect(RPAREN); functionNode = functionBody(getSetToken, getNameNode, new ArrayList(), FunctionNode.Kind.GETTER); @@ -2117,7 +2118,7 @@ loop: case "set": final PropertyKey setIdent = propertyName(); final String setterName = setIdent.getPropertyName(); - final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + setterName); + final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + NameCodec.encode(setterName)); expect(LPAREN); final IdentNode argIdent = getIdent(); verifyStrictIdent(argIdent, "setter argument"); diff --git a/test/script/basic/JDK-8025080.js b/test/script/basic/JDK-8025080.js new file mode 100644 index 00000000..1ea46efa --- /dev/null +++ b/test/script/basic/JDK-8025080.js @@ -0,0 +1,43 @@ +/* + * 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-8025080: Object literal getter, setter function with number format property name results in ClassFormatError + * + * @test + * @run + */ + +var obj = { + get 1e81() { print("1e81 getter"); }, + set 1e81(x) { print("1e81 setter"); }, + get 3.14e-2() { print("3.14e-2 getter");}, + set 3.14e-2(x) { print("3.14e-2 setter"); } +}; + +obj[1e81]; +obj[1e81] = 23; + +obj[3.14e-2]; +obj[3.14e-2] = 42; + diff --git a/test/script/basic/JDK-8025080.js.EXPECTED b/test/script/basic/JDK-8025080.js.EXPECTED new file mode 100644 index 00000000..e19e8ae9 --- /dev/null +++ b/test/script/basic/JDK-8025080.js.EXPECTED @@ -0,0 +1,4 @@ +1e81 getter +1e81 setter +3.14e-2 getter +3.14e-2 setter diff --git a/test/script/basic/parser/objectLitExpr.js.EXPECTED b/test/script/basic/parser/objectLitExpr.js.EXPECTED index 067c506a..7968d9a4 100644 --- a/test/script/basic/parser/objectLitExpr.js.EXPECTED +++ b/test/script/basic/parser/objectLitExpr.js.EXPECTED @@ -126,10 +126,7 @@ }, "value": { "type": "FunctionExpression", - "id": { - "type": "Identifier", - "name": "get x" - }, + "id": null, "params": [], "defaults": [], "rest": null, @@ -157,10 +154,7 @@ }, "value": { "type": "FunctionExpression", - "id": { - "type": "Identifier", - "name": "get y" - }, + "id": null, "params": [], "defaults": [], "rest": null, -- cgit v1.2.3 From 2590f54f476175426fc68d27ff8ee18edaa2aa8d Mon Sep 17 00:00:00 2001 From: sundar Date: Thu, 19 Sep 2013 23:48:37 +0530 Subject: 8025090: 'while' statement with 'test' using var before being declared in body results in VerifyError Reviewed-by: jlaskey --- src/jdk/nashorn/internal/ir/WhileNode.java | 9 ++++---- test/script/basic/JDK-8025090.js | 35 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 test/script/basic/JDK-8025090.js diff --git a/src/jdk/nashorn/internal/ir/WhileNode.java b/src/jdk/nashorn/internal/ir/WhileNode.java index 3c0046c0..97e7ca54 100644 --- a/src/jdk/nashorn/internal/ir/WhileNode.java +++ b/src/jdk/nashorn/internal/ir/WhileNode.java @@ -79,13 +79,12 @@ public final class WhileNode extends LoopNode { if (visitor.enterWhileNode(this)) { if (isDoWhile()) { return visitor.leaveWhileNode( - setTest(lc, (Expression)test.accept(visitor)). - setBody(lc, (Block)body.accept(visitor))); + setBody(lc, (Block)body.accept(visitor)). + setTest(lc, (Expression)test.accept(visitor))); } return visitor.leaveWhileNode( - setBody(lc, (Block)body.accept(visitor)). - setTest(lc, (Expression)test.accept(visitor))); - + setTest(lc, (Expression)test.accept(visitor)). + setBody(lc, (Block)body.accept(visitor))); } return this; } diff --git a/test/script/basic/JDK-8025090.js b/test/script/basic/JDK-8025090.js new file mode 100644 index 00000000..8e42099c --- /dev/null +++ b/test/script/basic/JDK-8025090.js @@ -0,0 +1,35 @@ +/* + * 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-8025090: 'while' statement with 'test' using var before being declared in body results in VerifyError + * + * @test + * @run + */ + +// The following used to result in VerifyError +function f() { + while (x += 2) { var x = 44 } +} + -- cgit v1.2.3 From b40f57ef7df5c580fa9c43652067407b9ad8013f Mon Sep 17 00:00:00 2001 From: sundar Date: Fri, 20 Sep 2013 12:56:07 +0530 Subject: 8025111: undefined or null 'with' expression in empty with block should throw TypeError Reviewed-by: lagergren, hannesw --- .../nashorn/internal/codegen/CodeGenerator.java | 9 +++- test/script/basic/JDK-8025111.js | 48 ++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 test/script/basic/JDK-8025111.js diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 6307e2f9..d16a1e5b 100644 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -2174,8 +2174,9 @@ final class CodeGenerator extends NodeOperatorVisitor Date: Fri, 20 Sep 2013 12:11:08 +0200 Subject: 8022587: ClassCache is not optimal and leaks Source instances Reviewed-by: lagergren, attila --- src/jdk/nashorn/internal/objects/Global.java | 45 +++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/jdk/nashorn/internal/objects/Global.java b/src/jdk/nashorn/internal/objects/Global.java index b7a902b7..161909bb 100644 --- a/src/jdk/nashorn/internal/objects/Global.java +++ b/src/jdk/nashorn/internal/objects/Global.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.reflect.Field; import java.util.Arrays; @@ -691,17 +692,41 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { * Cache for compiled script classes. */ @SuppressWarnings("serial") - private static class ClassCache extends LinkedHashMap>> { + private static class ClassCache extends LinkedHashMap { private final int size; + private final ReferenceQueue> queue; ClassCache(int size) { super(size, 0.75f, true); this.size = size; + this.queue = new ReferenceQueue<>(); + } + + void cache(final Source source, final Class clazz) { + put(source, new ClassReference(clazz, queue, source)); } @Override - protected boolean removeEldestEntry(final Map.Entry>> eldest) { - return size() >= size; + protected boolean removeEldestEntry(final Map.Entry eldest) { + return size() > size; + } + + @Override + public ClassReference get(Object key) { + for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) { + remove(ref.source); + } + return super.get(key); + } + + } + + private static class ClassReference extends SoftReference> { + private final Source source; + + ClassReference(final Class clazz, final ReferenceQueue> queue, final Source source) { + super(clazz, queue); + this.source = source; } } @@ -709,22 +734,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { @Override public Class findCachedClass(final Source source) { assert classCache != null : "Class cache used without being initialized"; - SoftReference> ref = classCache.get(source); - if (ref != null) { - final Class clazz = ref.get(); - if (clazz == null) { - classCache.remove(source); - } - return clazz; - } - - return null; + ClassReference ref = classCache.get(source); + return ref != null ? ref.get() : null; } @Override public void cacheClass(final Source source, final Class clazz) { assert classCache != null : "Class cache used without being initialized"; - classCache.put(source, new SoftReference>(clazz)); + classCache.cache(source, clazz); } private static T getLazilyCreatedValue(final Object key, final Callable creator, final Map map) { -- cgit v1.2.3 From 7f7fc695c7c23b1c6ea1cebaf31af4729cfa67d2 Mon Sep 17 00:00:00 2001 From: sundar Date: Fri, 20 Sep 2013 20:55:43 +0530 Subject: 8025147: Trailing comma is not allowed in JSONArray and JSONObject Reviewed-by: hannesw, jlaskey --- src/jdk/nashorn/internal/parser/JSONParser.java | 8 +++++ .../internal/runtime/resources/Messages.properties | 1 + test/script/basic/JDK-8025147.js | 41 ++++++++++++++++++++++ test/script/basic/JDK-8025147.js.EXPECTED | 6 ++++ 4 files changed, 56 insertions(+) create mode 100644 test/script/basic/JDK-8025147.js create mode 100644 test/script/basic/JDK-8025147.js.EXPECTED diff --git a/src/jdk/nashorn/internal/parser/JSONParser.java b/src/jdk/nashorn/internal/parser/JSONParser.java index cb14fcdf..51988f6a 100644 --- a/src/jdk/nashorn/internal/parser/JSONParser.java +++ b/src/jdk/nashorn/internal/parser/JSONParser.java @@ -349,6 +349,10 @@ loop: case COMMARIGHT: next(); + // check for trailing comma - not allowed in JSON + if (type == RBRACKET) { + throw error(AbstractParser.message("trailing.comma.in.json", type.getNameOrType())); + } break; default: @@ -388,6 +392,10 @@ loop: case COMMARIGHT: next(); + // check for trailing comma - not allowed in JSON + if (type == RBRACE) { + throw error(AbstractParser.message("trailing.comma.in.json", type.getNameOrType())); + } break; default: diff --git a/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/src/jdk/nashorn/internal/runtime/resources/Messages.properties index 5115e2ce..1a37ba7b 100644 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties @@ -57,6 +57,7 @@ parser.error.missing.catch.or.finally=Missing catch or finally after try parser.error.regex.unsupported.flag=Unsupported RegExp flag: {0} parser.error.regex.repeated.flag=Repeated RegExp flag: {0} parser.error.regex.syntax={0} +parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON # strict mode error messages parser.error.strict.no.with="with" statement cannot be used in strict mode diff --git a/test/script/basic/JDK-8025147.js b/test/script/basic/JDK-8025147.js new file mode 100644 index 00000000..905a1c9c --- /dev/null +++ b/test/script/basic/JDK-8025147.js @@ -0,0 +1,41 @@ +/* + * 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-8025147: Trailing comma is not allowed in JSONArray and JSONObject + * + * @test + * @run + */ + +function check(str) { + try { + JSON.parse(str); + fail("should have thrown SyntaxError for " + str); + } catch (e) { + print(e); + } +} + +check("{ \"a\": 333, }"); +check("[ 4343, ]"); diff --git a/test/script/basic/JDK-8025147.js.EXPECTED b/test/script/basic/JDK-8025147.js.EXPECTED new file mode 100644 index 00000000..3afb20a8 --- /dev/null +++ b/test/script/basic/JDK-8025147.js.EXPECTED @@ -0,0 +1,6 @@ +SyntaxError: Invalid JSON: :1:12 Trailing comma is not allowed in JSON +{ "a": 333, } + ^ +SyntaxError: Invalid JSON: :1:8 Trailing comma is not allowed in JSON +[ 4343, ] + ^ -- cgit v1.2.3 From afd7befa7d1a5b0c4da985cb5f294ca9879c4b44 Mon Sep 17 00:00:00 2001 From: sundar Date: Fri, 20 Sep 2013 22:37:08 +0530 Subject: 8025149: JSON.stringify does not handle 'space' argument as per the spec. Reviewed-by: jlaskey, hannesw --- src/jdk/nashorn/internal/objects/NativeJSON.java | 33 ++++++++++------- test/script/basic/JDK-8025149.js | 47 ++++++++++++++++++++++++ test/script/basic/JDK-8025149.js.EXPECTED | 9 +++++ 3 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 test/script/basic/JDK-8025149.js create mode 100644 test/script/basic/JDK-8025149.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/NativeJSON.java b/src/jdk/nashorn/internal/objects/NativeJSON.java index b2fa46d2..344b6da9 100644 --- a/src/jdk/nashorn/internal/objects/NativeJSON.java +++ b/src/jdk/nashorn/internal/objects/NativeJSON.java @@ -162,22 +162,27 @@ public final class NativeJSON extends ScriptObject { String gap; - if (space instanceof Number || space instanceof NativeNumber) { - int indent; - if (space instanceof NativeNumber) { - indent = ((NativeNumber)space).intValue(); - } else { - indent = ((Number)space).intValue(); - } + // modifiable 'space' - parameter is final + Object modSpace = space; + if (modSpace instanceof NativeNumber) { + modSpace = JSType.toNumber(JSType.toPrimitive(modSpace, Number.class)); + } else if (modSpace instanceof NativeString) { + modSpace = JSType.toString(JSType.toPrimitive(modSpace, String.class)); + } - final StringBuilder sb = new StringBuilder(); - for (int i = 0; i < Math.min(10, indent); i++) { - sb.append(' '); + if (modSpace instanceof Number) { + int indent = Math.min(10, JSType.toInteger(modSpace)); + if (indent < 1) { + gap = ""; + } else { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) { + sb.append(' '); + } + gap = sb.toString(); } - gap = sb.toString(); - - } else if (space instanceof String || space instanceof ConsString || space instanceof NativeString) { - final String str = (space instanceof String) ? (String)space : space.toString(); + } else if (modSpace instanceof String || modSpace instanceof ConsString) { + final String str = modSpace.toString(); gap = str.substring(0, Math.min(10, str.length())); } else { gap = ""; diff --git a/test/script/basic/JDK-8025149.js b/test/script/basic/JDK-8025149.js new file mode 100644 index 00000000..b1d33a1a --- /dev/null +++ b/test/script/basic/JDK-8025149.js @@ -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-8025149: JSON.stringify does not handle 'space' argument as per the spec. + * + * @test + * @run + */ + +print(JSON.stringify({ foo : 23, bar: { x : 22} }, undefined ,new Number(Infinity))); + +print(JSON.stringify({ foo : 23, bar: { x : 22} }, undefined ,new Number(-Infinity))); + +try { + JSON.stringify({},[], + (n = new Number(0), n.valueOf = function() { throw ("inside n.valueOf") }, n)); +} catch (e) { + print(e); +} + +try { + JSON.stringify({},[], + (s = new String(""), s.toString = function() { throw ("inside s.toString") }, s)); +} catch (e) { + print(e); +} diff --git a/test/script/basic/JDK-8025149.js.EXPECTED b/test/script/basic/JDK-8025149.js.EXPECTED new file mode 100644 index 00000000..10fd8641 --- /dev/null +++ b/test/script/basic/JDK-8025149.js.EXPECTED @@ -0,0 +1,9 @@ +{ + "foo": 23, + "bar": { + "x": 22 + } +} +{"foo":23,"bar":{"x":22}} +inside n.valueOf +inside s.toString -- cgit v1.2.3 From 2e27840e4fecc3b212f7d05e335481ed8c298373 Mon Sep 17 00:00:00 2001 From: hannesw Date: Sat, 21 Sep 2013 10:11:15 +0200 Subject: 8025163: Date methods should not return -0 Reviewed-by: lagergren, jlaskey --- src/jdk/nashorn/internal/objects/NativeDate.java | 128 +++++++++++------------ test/script/basic/JDK-8025163.js | 39 +++++++ test/script/basic/JDK-8025163.js.EXPECTED | 8 ++ 3 files changed, 110 insertions(+), 65 deletions(-) create mode 100644 test/script/basic/JDK-8025163.js create mode 100644 test/script/basic/JDK-8025163.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/NativeDate.java b/src/jdk/nashorn/internal/objects/NativeDate.java index 859745f3..935285f0 100644 --- a/src/jdk/nashorn/internal/objects/NativeDate.java +++ b/src/jdk/nashorn/internal/objects/NativeDate.java @@ -75,11 +75,11 @@ public final class NativeDate extends ScriptObject { private static final int FORMAT_LOCAL_TIME = 5; // Constants defined in ECMA 15.9.1.10 - private static final double hoursPerDay = 24; - private static final double minutesPerHour = 60; - private static final double secondsPerMinute = 60; - private static final double msPerSecond = 1_000; - private static final double msPerMinute = 60_000; + private static final int hoursPerDay = 24; + private static final int minutesPerHour = 60; + private static final int secondsPerMinute = 60; + private static final int msPerSecond = 1_000; + private static final int msPerMinute = 60_000; private static final double msPerHour = 3_600_000; private static final double msPerDay = 86_400_000; @@ -926,13 +926,13 @@ public final class NativeDate extends ScriptObject { case FORMAT_DATE : case FORMAT_LOCAL_DATE_TIME: // EEE MMM dd yyyy - sb.append(weekDays[(int) weekDay(t)]) + sb.append(weekDays[weekDay(t)]) .append(' ') - .append(months[(int) monthFromTime(t)]) + .append(months[monthFromTime(t)]) .append(' '); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append(' '); - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); if (format == FORMAT_DATE) { break; } @@ -948,11 +948,11 @@ public final class NativeDate extends ScriptObject { offset = (offset / 60) * 100 + offset % 60; // HH:mm:ss GMT+HHmm - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append(" GMT") .append(offset < 0 ? '-' : '+'); zeroPad(sb, Math.abs(offset), 4); @@ -963,20 +963,20 @@ public final class NativeDate extends ScriptObject { case FORMAT_LOCAL_DATE: // yyyy-MM-dd - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append('-'); - zeroPad(sb, (int) monthFromTime(t) + 1, 2); + zeroPad(sb, monthFromTime(t) + 1, 2); sb.append('-'); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); break; case FORMAT_LOCAL_TIME: // HH:mm:ss - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); break; default: @@ -996,19 +996,19 @@ public final class NativeDate extends ScriptObject { final StringBuilder sb = new StringBuilder(29); final double t = nd.getTime(); // EEE, dd MMM yyyy HH:mm:ss z - sb.append(weekDays[(int) weekDay(t)]) + sb.append(weekDays[weekDay(t)]) .append(", "); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append(' ') - .append(months[(int) monthFromTime(t)]) + .append(months[monthFromTime(t)]) .append(' '); - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append(' '); - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append(" GMT"); return sb.toString(); } @@ -1023,19 +1023,19 @@ public final class NativeDate extends ScriptObject { final StringBuilder sb = new StringBuilder(24); final double t = nd.getTime(); // yyyy-MM-dd'T'HH:mm:ss.SSS'Z' - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append('-'); - zeroPad(sb, (int) monthFromTime(t) + 1, 2); + zeroPad(sb, monthFromTime(t) + 1, 2); sb.append('-'); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append('T'); - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append('.'); - zeroPad(sb, (int) msFromTime(t), 3); + zeroPad(sb, msFromTime(t), 3); sb.append("Z"); return sb.toString(); } @@ -1072,29 +1072,30 @@ public final class NativeDate extends ScriptObject { } // ECMA 15.9.1.3 Year Number - private static double timeFromYear(final double y) { + private static double timeFromYear(final int y) { return dayFromYear(y) * msPerDay; } - private static double yearFromTime(final double t) { - double y = Math.floor(t / (msPerDay * 365.2425)) + 1970; + // ECMA 15.9.1.3 Year Number + private static int yearFromTime(final double t) { + int y = (int) Math.floor(t / (msPerDay * 365.2425)) + 1970; final double t2 = timeFromYear(y); if (t2 > t) { y--; - } else if (t2 + msPerDay * daysInYear((int) y) <= t) { + } else if (t2 + msPerDay * daysInYear(y) <= t) { y++; } return y; } - private static double dayWithinYear(final double t, final double year) { - return day(t) - dayFromYear(year); + private static int dayWithinYear(final double t, final int year) { + return (int) (day(t) - dayFromYear(year)); } - private static double monthFromTime(final double t) { - final double year = yearFromTime(t); - final double day = dayWithinYear(t, year); - final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0]; + private static int monthFromTime(final double t) { + final int year = yearFromTime(t); + final int day = dayWithinYear(t, year); + final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0]; int month = 0; while (month < 11 && firstDay[month + 1] <= day) { @@ -1103,10 +1104,10 @@ public final class NativeDate extends ScriptObject { return month; } - private static double dayFromTime(final double t) { - final double year = yearFromTime(t); - final double day = dayWithinYear(t, year); - final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0]; + private static int dayFromTime(final double t) { + final int year = yearFromTime(t); + final int day = dayWithinYear(t, year); + final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0]; int month = 0; while (month < 11 && firstDay[month + 1] <= day) { @@ -1121,11 +1122,8 @@ public final class NativeDate extends ScriptObject { return firstDay[month]; } - private static double weekDay(final double time) { - if (isNaN(time)) { - return NaN; - } - final double day = (day(time) + 4) % 7; + private static int weekDay(final double time) { + final int day = (int) (day(time) + 4) % 7; return day < 0 ? day + 7 : day; } @@ -1140,26 +1138,26 @@ public final class NativeDate extends ScriptObject { } // ECMA 15.9.1.10 Hours, Minutes, Second, and Milliseconds - private static double hourFromTime(final double t) { - final double h = Math.floor(t / msPerHour) % hoursPerDay; + private static int hourFromTime(final double t) { + final int h = (int) (Math.floor(t / msPerHour) % hoursPerDay); return h < 0 ? h + hoursPerDay: h; } - private static double minFromTime(final double t) { - final double m = Math.floor(t / msPerMinute) % minutesPerHour; + private static int minFromTime(final double t) { + final int m = (int) (Math.floor(t / msPerMinute) % minutesPerHour); return m < 0 ? m + minutesPerHour : m; } - private static double secFromTime(final double t) { - final double s = Math.floor(t / msPerSecond) % secondsPerMinute; + private static int secFromTime(final double t) { + final int s = (int) (Math.floor(t / msPerSecond) % secondsPerMinute); return s < 0 ? s + secondsPerMinute : s; } - private static double msFromTime(final double t) { - final double m = t % msPerSecond; + private static int msFromTime(final double t) { + final int m = (int) (t % msPerSecond); return m < 0 ? m + msPerSecond : m; } - private static double valueFromTime(final int unit, final double t) { + private static int valueFromTime(final int unit, final double t) { switch (unit) { case YEAR: return yearFromTime(t); case MONTH: return monthFromTime(t); @@ -1180,12 +1178,12 @@ public final class NativeDate extends ScriptObject { // ECMA 15.9.1.12 MakeDay (year, month, date) private static double makeDay(final double year, final double month, final double date) { final double y = year + Math.floor(month / 12); - double m = month % 12; + int m = (int) (month % 12); if (m < 0) { m += 12; } - double d = Math.floor(dayFromYear(y)); - d += dayFromMonth((int) m, (int) y); + double d = dayFromYear(y); + d += dayFromMonth(m, (int) y); return d + date - 1; } @@ -1257,13 +1255,13 @@ public final class NativeDate extends ScriptObject { nullReturn = true; } - if (! nullReturn) { + if (!nullReturn && !isNaN(time)) { d[i - start] = valueFromTime(i, time); } } } - return nullReturn? null : d; + return nullReturn ? null : d; } // ECMA 15.9.1.14 TimeClip (time) diff --git a/test/script/basic/JDK-8025163.js b/test/script/basic/JDK-8025163.js new file mode 100644 index 00000000..1eaa98e8 --- /dev/null +++ b/test/script/basic/JDK-8025163.js @@ -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-8025163: Date methods should not return -0 + * + * @test + * @run + */ + +print(1 / (new Date(0, 0, 1)).getYear()); +print(1 / (new Date(1969, 1, 2)).getDay()); +print(1 / (new Date(1969, 0, 1)).getHours()); +print(1 / (new Date(1969, 0, 1)).getHours()); +print(1 / (new Date(1969, 0, 1)).getMinutes()); +print(1 / (new Date(1969, 0, 1)).getSeconds()); +print(1 / (new Date(1969, 0, 1)).getMilliseconds()); +print(1 / (new Date(1969, 0, 1)).getMilliseconds()); + diff --git a/test/script/basic/JDK-8025163.js.EXPECTED b/test/script/basic/JDK-8025163.js.EXPECTED new file mode 100644 index 00000000..cde7e193 --- /dev/null +++ b/test/script/basic/JDK-8025163.js.EXPECTED @@ -0,0 +1,8 @@ +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity -- cgit v1.2.3 From 9caeea64d60f9c2a9d15a0e504e9cc7d80393924 Mon Sep 17 00:00:00 2001 From: sundar Date: Tue, 24 Sep 2013 20:43:42 +0530 Subject: 8025312: parseInt should convert 'radix' argument to ToInt32 even if empty string is parsed Reviewed-by: jlaskey, hannesw --- .../nashorn/internal/runtime/GlobalFunctions.java | 2 +- test/script/basic/JDK-8025312.js | 35 ++++++++++++++++++++++ test/script/basic/JDK-8025312.js.EXPECTED | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/script/basic/JDK-8025312.js create mode 100644 test/script/basic/JDK-8025312.js.EXPECTED diff --git a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java index c504276f..9ddc7090 100644 --- a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java +++ b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java @@ -90,6 +90,7 @@ public final class GlobalFunctions { public static double parseInt(final Object self, final Object string, final Object rad) { final String str = JSType.trimLeft(JSType.toString(string)); final int length = str.length(); + int radix = JSType.toInt32(rad); // empty string is not valid if (length == 0) { @@ -113,7 +114,6 @@ public final class GlobalFunctions { } boolean stripPrefix = true; - int radix = JSType.toInt32(rad); if (radix != 0) { if (radix < 2 || radix > 36) { diff --git a/test/script/basic/JDK-8025312.js b/test/script/basic/JDK-8025312.js new file mode 100644 index 00000000..6f2b42f3 --- /dev/null +++ b/test/script/basic/JDK-8025312.js @@ -0,0 +1,35 @@ +/* + * 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-8025312: parseInt should convert 'radix' argument to ToInt32 even if empty string is parsed + * + * @test + * @run + */ + +parseInt("", { + valueOf: function() { + print("inside valueOf of 'radix'"); + } +}); diff --git a/test/script/basic/JDK-8025312.js.EXPECTED b/test/script/basic/JDK-8025312.js.EXPECTED new file mode 100644 index 00000000..31ffef83 --- /dev/null +++ b/test/script/basic/JDK-8025312.js.EXPECTED @@ -0,0 +1 @@ +inside valueOf of 'radix' -- cgit v1.2.3 From 47058d4b4a148d7ebccaee3d53d07886c07dcbd2 Mon Sep 17 00:00:00 2001 From: sundar Date: Wed, 25 Sep 2013 08:17:37 +0530 Subject: 8025325: parseFloat does not handle '.' in exponent part Reviewed-by: hannesw --- .../nashorn/internal/runtime/GlobalFunctions.java | 2 +- test/script/basic/JDK-8025325.js | 35 ++++++++++++++++++++++ test/script/basic/JDK-8025325.js.EXPECTED | 5 ++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 test/script/basic/JDK-8025325.js create mode 100644 test/script/basic/JDK-8025325.js.EXPECTED diff --git a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java index 9ddc7090..c750d80e 100644 --- a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java +++ b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java @@ -211,7 +211,7 @@ loop: switch (ch) { case '.': // dot allowed only once - if (dotSeen) { + if (exponentOffset != -1 || dotSeen) { break loop; } dotSeen = true; diff --git a/test/script/basic/JDK-8025325.js b/test/script/basic/JDK-8025325.js new file mode 100644 index 00000000..63dfef9d --- /dev/null +++ b/test/script/basic/JDK-8025325.js @@ -0,0 +1,35 @@ +/* + * 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-8025325: parseFloat does not handle '.' in exponent part + * + * @test + * @run + */ + +print(parseFloat("2e2.")); +print(parseFloat("2e2.3")); +print(parseFloat("2e2.fdgdf")); +print(parseFloat("2e2. gdfgdf")); +print(parseFloat("2e2. ")); diff --git a/test/script/basic/JDK-8025325.js.EXPECTED b/test/script/basic/JDK-8025325.js.EXPECTED new file mode 100644 index 00000000..4ddf679a --- /dev/null +++ b/test/script/basic/JDK-8025325.js.EXPECTED @@ -0,0 +1,5 @@ +200 +200 +200 +200 +200 -- cgit v1.2.3 From 33e09329205c3b07aae24b2261de601442d48040 Mon Sep 17 00:00:00 2001 From: hannesw Date: Wed, 25 Sep 2013 16:37:56 +0200 Subject: 8025434: RegExp lastIndex can exceed int range Reviewed-by: lagergren, sundar --- src/jdk/nashorn/internal/objects/NativeRegExp.java | 2 +- test/script/basic/JDK-8025434.js | 66 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/script/basic/JDK-8025434.js diff --git a/src/jdk/nashorn/internal/objects/NativeRegExp.java b/src/jdk/nashorn/internal/objects/NativeRegExp.java index 5a219635..2c4d3324 100644 --- a/src/jdk/nashorn/internal/objects/NativeRegExp.java +++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java @@ -883,7 +883,7 @@ public final class NativeRegExp extends ScriptObject { * @return last index property as int */ public int getLastIndex() { - return JSType.toInt32(lastIndex); + return JSType.toInteger(lastIndex); } /** diff --git a/test/script/basic/JDK-8025434.js b/test/script/basic/JDK-8025434.js new file mode 100644 index 00000000..1d429594 --- /dev/null +++ b/test/script/basic/JDK-8025434.js @@ -0,0 +1,66 @@ +/* + * 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-8025434: RegExp lastIndex can exceed int range + * + * @test + * @run + */ + +var r = /a/g; + +r.lastIndex = 0x100000000; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = 0x100000000000000; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = -0x100000000; +if (r.test("a")) { + throw new Error("Expected match"); +} + +r.lastIndex = -0x100000000000000; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = 1; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = -1; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = 0; +if (!r.test("a")) { + throw new Error("Expected match"); +} -- cgit v1.2.3 From 3340d2d8e399643da49c1e3f3cd56e8484aa58ba Mon Sep 17 00:00:00 2001 From: hannesw Date: Thu, 26 Sep 2013 10:14:24 +0200 Subject: 8025197: String replace method fails with regexp /$/gi Reviewed-by: sundar --- src/jdk/nashorn/internal/objects/NativeRegExp.java | 7 +++- test/script/basic/JDK-8025197.js | 37 ++++++++++++++++++++++ test/script/basic/JDK-8025197.js.EXPECTED | 7 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/script/basic/JDK-8025197.js create mode 100644 test/script/basic/JDK-8025197.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/NativeRegExp.java b/src/jdk/nashorn/internal/objects/NativeRegExp.java index 2c4d3324..be4a93d0 100644 --- a/src/jdk/nashorn/internal/objects/NativeRegExp.java +++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java @@ -697,8 +697,13 @@ public final class NativeRegExp extends ScriptObject { appendReplacement(matcher, string, replacement, sb); } - // ECMA 15.5.4.10 String.prototype.match(regexp) thisIndex = matcher.end(); + if (thisIndex == string.length() && matcher.start() == matcher.end()) { + // Avoid getting empty match at end of string twice + break; + } + + // ECMA 15.5.4.10 String.prototype.match(regexp) if (thisIndex == previousLastIndex) { setLastIndex(thisIndex + 1); previousLastIndex = thisIndex + 1; diff --git a/test/script/basic/JDK-8025197.js b/test/script/basic/JDK-8025197.js new file mode 100644 index 00000000..5099b673 --- /dev/null +++ b/test/script/basic/JDK-8025197.js @@ -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-8025197: String replace method fails with regexp /$/gi + * + * @test + * @run + */ + +print('dog'.replace(/$/gi, 's')); +print('dog'.replace(/(?:g)$/gi, 's')); +print('dog'.replace(/(?:a)$/gi, 's')); +print('dog'.replace(/(?!g)$/gi, 's')); +print('dog'.replace(/(?!a)$/gi, 's')); +print('dog'.replace(/g?$/gi, 's')); +print('dog'.replace(/.?$/gi, 's')); diff --git a/test/script/basic/JDK-8025197.js.EXPECTED b/test/script/basic/JDK-8025197.js.EXPECTED new file mode 100644 index 00000000..9f2a08f6 --- /dev/null +++ b/test/script/basic/JDK-8025197.js.EXPECTED @@ -0,0 +1,7 @@ +dogs +dos +dog +dogs +dogs +doss +doss -- cgit v1.2.3 From 54155ecac81d849c2a5387c4ee13cc14dc2966ff Mon Sep 17 00:00:00 2001 From: hannesw Date: Thu, 26 Sep 2013 11:47:24 +0200 Subject: 8025486: RegExp constructor arguments are not evaluated in right order Reviewed-by: sundar --- src/jdk/nashorn/internal/objects/NativeRegExp.java | 16 +++---- test/script/basic/JDK-8025486.js | 55 ++++++++++++++++++++++ test/script/basic/JDK-8025486.js.EXPECTED | 3 ++ 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 test/script/basic/JDK-8025486.js create mode 100644 test/script/basic/JDK-8025486.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/NativeRegExp.java b/src/jdk/nashorn/internal/objects/NativeRegExp.java index be4a93d0..318ca2a0 100644 --- a/src/jdk/nashorn/internal/objects/NativeRegExp.java +++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java @@ -191,23 +191,21 @@ public final class NativeRegExp extends ScriptObject { public static NativeRegExp newRegExp(final Object regexp, final Object flags) { String patternString = ""; String flagString = ""; - boolean flagsDefined = false; - - if (flags != UNDEFINED) { - flagsDefined = true; - flagString = JSType.toString(flags); - } if (regexp != UNDEFINED) { if (regexp instanceof NativeRegExp) { - if (!flagsDefined) { - return (NativeRegExp)regexp; // 15.10.3.1 - undefined flags and regexp as + if (flags != UNDEFINED) { + throw typeError("regex.cant.supply.flags"); } - throw typeError("regex.cant.supply.flags"); + return (NativeRegExp)regexp; // 15.10.3.1 - undefined flags and regexp as } patternString = JSType.toString(regexp); } + if (flags != UNDEFINED) { + flagString = JSType.toString(flags); + } + return new NativeRegExp(patternString, flagString); } diff --git a/test/script/basic/JDK-8025486.js b/test/script/basic/JDK-8025486.js new file mode 100644 index 00000000..8012f723 --- /dev/null +++ b/test/script/basic/JDK-8025486.js @@ -0,0 +1,55 @@ +/* + * 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-8025486: RegExp constructor arguments are not evaluated in right order + * + * @test + * @run + */ + +new RegExp({ + toString: function() { + print("source"); + return "a"; + } +}, { + toString: function() { + print("flags"); + return "g"; + } +}); + +try { + new RegExp(/asdf/, { + toString: function() { + fail("toString should not be called"); + } + }); + fail("expected TypeError"); +} catch (e) { + if (!(e instanceof TypeError)) { + fail("expected TypeError"); + } + print(e); +} diff --git a/test/script/basic/JDK-8025486.js.EXPECTED b/test/script/basic/JDK-8025486.js.EXPECTED new file mode 100644 index 00000000..cf46bd7a --- /dev/null +++ b/test/script/basic/JDK-8025486.js.EXPECTED @@ -0,0 +1,3 @@ +source +flags +TypeError: Cannot supply flags when constructing one RegExp from another -- cgit v1.2.3