Mercurial > hg > icedtea9-forest > nashorn
changeset 650:767e85d2a1b3
Merge
author | lana |
---|---|
date | Mon, 28 Oct 2013 12:29:40 -0700 |
parents | 640c1854f742 (diff) 79f7b79bf97b (current diff) |
children | 406f2b672937 |
files | |
diffstat | 56 files changed, 1667 insertions(+), 316 deletions(-) [+] |
line wrap: on
line diff
--- a/make/build.xml Thu Oct 24 09:10:54 2013 -0700 +++ b/make/build.xml Mon Oct 28 12:29:40 2013 -0700 @@ -46,6 +46,16 @@ <available property="asm.available" classname="jdk.internal.org.objectweb.asm.Type"/> <!-- check if testng.jar is avaiable --> <available property="testng.available" file="${file.reference.testng.jar}"/> + <!-- check if Jemmy ang testng.jar are avaiable --> + <condition property="jemmy.jfx.testng.available" value="true"> + <and> + <available file="${file.reference.jemmyfx.jar}"/> + <available file="${file.reference.jemmycore.jar}"/> + <available file="${file.reference.jemmyawtinput.jar}"/> + <available file="${file.reference.jfxrt.jar}"/> + <isset property="testng.available"/> + </and> + </condition> <!-- enable/disable make code coverage --> <condition property="cc.enabled"> @@ -351,6 +361,31 @@ </java> </target> + <target name="check-jemmy.jfx.testng" unless="jemmy.jfx.testng.available"> + <echo message="WARNING: Jemmy or JavaFX or TestNG not available, will not run tests. Please copy testng.jar, JemmyCore.jar, JemmyFX.jar, JemmyAWTInput.jar under test${file.separator}lib directory. And make sure you have jfxrt.jar in ${java.home}${file.separator}lib${file.separator}ext dir."/> + </target> + + <target name="testjfx" depends="jar, check-jemmy.jfx.testng, compile-test" if="jemmy.jfx.testng.available"> + <fileset id="test.classes" dir="${build.test.classes.dir}"> + <include name="**/framework/*Test.class"/> + </fileset> + + <copy file="${file.reference.jfxrt.jar}" todir="dist"/> + + <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes" + verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}"> + <jvmarg line="${ext.class.path}"/> + <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/> + <propertyset> + <propertyref prefix="testjfx-test-sys-prop."/> + <mapper from="testjfx-test-sys-prop.*" to="*" type="glob"/> + </propertyset> + <classpath> + <pathelement path="${testjfx.run.test.classpath}"/> + </classpath> + </testng> + </target> + <target name="test262" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available"> <fileset id="test.classes" dir="${build.test.classes.dir}"> <include name="**/framework/*Test.class"/>
--- a/make/project.properties Thu Oct 24 09:10:54 2013 -0700 +++ b/make/project.properties Mon Oct 28 12:29:40 2013 -0700 @@ -118,6 +118,7 @@ test.external.dir=test/script/external test262.dir=${test.external.dir}/test262 test262.suite.dir=${test262.dir}/test/suite +testjfx.dir=${test.script.dir}/jfx test-sys-prop.test.dir=${test.dir} test-sys-prop.test.js.roots=${test.basic.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir} @@ -208,6 +209,32 @@ ${test262.dir}/test/harness/framework.js \ ${test262.dir}/test/harness/sta.js +# testjfx test root +testjfx-test-sys-prop.test.js.roots=${testjfx.dir} + +# execute testjfx tests in shared nashorn context or not? +testjfx-test-sys-prop.test.js.shared.context=false + +# framework root for our script tests +testjfx-test-sys-prop.test.js.framework=\ + -fx \ + ${test.script.dir}${file.separator}jfx.js + +file.reference.jemmyfx.jar=test${file.separator}lib${file.separator}JemmyFX.jar +file.reference.jemmycore.jar=test${file.separator}lib${file.separator}JemmyCore.jar +file.reference.jemmyawtinput.jar=test${file.separator}lib${file.separator}JemmyAWTInput.jar +file.reference.jfxrt.jar=${java.home}${file.separator}lib${file.separator}ext${file.separator}jfxrt.jar +testjfx.run.test.classpath=\ + ${file.reference.jemmyfx.jar}${path.separator}\ + ${file.reference.jemmycore.jar}${path.separator}\ + ${file.reference.jemmyawtinput.jar}${path.separator}\ + ${file.reference.testng.jar}${path.separator}\ + ${nashorn.internal.tests.jar}${path.separator}\ + ${nashorn.api.tests.jar} + +# testjfx VM options for script tests with @fork option +testjfx-test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} -cp ${testjfx.run.test.classpath} + run.test.classpath=\ ${file.reference.testng.jar}:\ ${nashorn.internal.tests.jar}:\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk/nashorn/api/scripting/AbstractJSObject.java Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,254 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.api.scripting; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +/** + * This is the base class for nashorn ScriptObjectMirror class. + * + * This class can also be subclassed by an arbitrary Java class. Nashorn will + * treat objects of such classes just like nashorn script objects. Usual nashorn + * operations like obj[i], obj.foo, obj.func(), delete obj.foo will be glued + * to appropriate method call of this class. + */ +public abstract class AbstractJSObject implements JSObject { + /** + * Call this object as a JavaScript function. This is equivalent to + * 'func.apply(thiz, args)' in JavaScript. + * + * @param thiz 'this' object to be passed to the function + * @param args arguments to method + * @return result of call + */ + @Override + public Object call(final Object thiz, final Object... args) { + throw new UnsupportedOperationException("call"); + } + + /** + * Call this 'constructor' JavaScript function to create a new object. + * This is equivalent to 'new func(arg1, arg2...)' in JavaScript. + * + * @param args arguments to method + * @return result of constructor call + */ + @Override + public Object newObject(final Object... args) { + throw new UnsupportedOperationException("newObject"); + } + + /** + * Evaluate a JavaScript expression. + * + * @param s JavaScript expression to evaluate + * @return evaluation result + */ + @Override + public Object eval(final String s) { + throw new UnsupportedOperationException("eval"); + } + + /** + * Retrieves a named member of this JavaScript object. + * + * @param name of member + * @return member + */ + @Override + public Object getMember(final String name) { + return null; + } + + /** + * Retrieves an indexed member of this JavaScript object. + * + * @param index index slot to retrieve + * @return member + */ + @Override + public Object getSlot(final int index) { + return null; + } + + /** + * Does this object have a named member? + * + * @param name name of member + * @return true if this object has a member of the given name + */ + @Override + public boolean hasMember(final String name) { + return false; + } + + /** + * Does this object have a indexed property? + * + * @param slot index to check + * @return true if this object has a slot + */ + @Override + public boolean hasSlot(final int slot) { + return false; + } + + /** + * Remove a named member from this JavaScript object + * + * @param name name of the member + */ + @Override + public void removeMember(final String name) { + //empty + } + + /** + * Set a named member in this JavaScript object + * + * @param name name of the member + * @param value value of the member + */ + @Override + public void setMember(final String name, final Object value) { + //empty + } + + /** + * Set an indexed member in this JavaScript object + * + * @param index index of the member slot + * @param value value of the member + */ + @Override + public void setSlot(final int index, final Object value) { + //empty + } + + // property and value iteration + + /** + * Returns the set of all property names of this object. + * + * @return set of property names + */ + @Override + @SuppressWarnings("unchecked") + public Set<String> keySet() { + return Collections.EMPTY_SET; + } + + /** + * Returns the set of all property values of this object. + * + * @return set of property values. + */ + @Override + @SuppressWarnings("unchecked") + public Collection<Object> values() { + return Collections.EMPTY_SET; + } + + // JavaScript instanceof check + + /** + * Checking whether the given object is an instance of 'this' object. + * + * @param instance instace to check + * @return true if the given 'instance' is an instance of this 'function' object + */ + @Override + public boolean isInstance(final Object instance) { + return false; + } + + /** + * Checking whether this object is an instance of the given 'clazz' object. + * + * @param clazz clazz to check + * @return true if this object is an instance of the given 'clazz' + */ + @Override + public boolean isInstanceOf(final Object clazz) { + if (clazz instanceof JSObject) { + return ((JSObject)clazz).isInstance(this); + } + + return false; + } + + /** + * ECMA [[Class]] property + * + * @return ECMA [[Class]] property value of this object + */ + @Override + public String getClassName() { + return getClass().getName(); + } + + /** + * Is this a function object? + * + * @return if this mirror wraps a ECMAScript function instance + */ + @Override + public boolean isFunction() { + return false; + } + + /** + * Is this a 'use strict' function object? + * + * @return true if this mirror represents a ECMAScript 'use strict' function + */ + @Override + public boolean isStrictFunction() { + return false; + } + + /** + * Is this an array object? + * + * @return if this mirror wraps a ECMAScript array object + */ + @Override + public boolean isArray() { + return false; + } + + /** + * Returns this object's numeric value. + * + * @return this object's numeric value. + */ + @Override + public double toNumber() { + return Double.NaN; + } +}
--- a/src/jdk/nashorn/api/scripting/JSObject.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/api/scripting/JSObject.java Mon Oct 28 12:29:40 2013 -0700 @@ -30,14 +30,12 @@ import java.util.Set; /** - * This is the base class for nashorn ScriptObjectMirror class. - * - * This class can also be subclassed by an arbitrary Java class. Nashorn will + * This interface can be implemented by an arbitrary Java class. Nashorn will * treat objects of such classes just like nashorn script objects. Usual nashorn * operations like obj[i], obj.foo, obj.func(), delete obj.foo will be glued - * to appropriate method call of this class. + * to appropriate method call of this interface. */ -public abstract class JSObject { +public interface JSObject { /** * Call this object as a JavaScript function. This is equivalent to * 'func.apply(thiz, args)' in JavaScript. @@ -46,9 +44,7 @@ * @param args arguments to method * @return result of call */ - public Object call(final Object thiz, final Object... args) { - throw new UnsupportedOperationException("call"); - } + public Object call(final Object thiz, final Object... args); /** * Call this 'constructor' JavaScript function to create a new object. @@ -57,9 +53,7 @@ * @param args arguments to method * @return result of constructor call */ - public Object newObject(final Object... args) { - throw new UnsupportedOperationException("newObject"); - } + public Object newObject(final Object... args); /** * Evaluate a JavaScript expression. @@ -67,20 +61,7 @@ * @param s JavaScript expression to evaluate * @return evaluation result */ - public Object eval(final String s) { - throw new UnsupportedOperationException("eval"); - } - - /** - * Call a JavaScript function member of this object. - * - * @param name name of the member function to call - * @param args arguments to be passed to the member function - * @return result of call - */ - public Object callMember(final String name, final Object... args) { - throw new UnsupportedOperationException("call"); - } + public Object eval(final String s); /** * Retrieves a named member of this JavaScript object. @@ -88,9 +69,7 @@ * @param name of member * @return member */ - public Object getMember(final String name) { - return null; - } + public Object getMember(final String name); /** * Retrieves an indexed member of this JavaScript object. @@ -98,9 +77,7 @@ * @param index index slot to retrieve * @return member */ - public Object getSlot(final int index) { - return null; - } + public Object getSlot(final int index); /** * Does this object have a named member? @@ -108,9 +85,7 @@ * @param name name of member * @return true if this object has a member of the given name */ - public boolean hasMember(final String name) { - return false; - } + public boolean hasMember(final String name); /** * Does this object have a indexed property? @@ -118,18 +93,14 @@ * @param slot index to check * @return true if this object has a slot */ - public boolean hasSlot(final int slot) { - return false; - } + public boolean hasSlot(final int slot); /** * Remove a named member from this JavaScript object * * @param name name of the member */ - public void removeMember(final String name) { - //empty - } + public void removeMember(final String name); /** * Set a named member in this JavaScript object @@ -137,9 +108,7 @@ * @param name name of the member * @param value value of the member */ - public void setMember(final String name, final Object value) { - //empty - } + public void setMember(final String name, final Object value); /** * Set an indexed member in this JavaScript object @@ -147,9 +116,7 @@ * @param index index of the member slot * @param value value of the member */ - public void setSlot(final int index, final Object value) { - //empty - } + public void setSlot(final int index, final Object value); // property and value iteration @@ -158,20 +125,14 @@ * * @return set of property names */ - @SuppressWarnings("unchecked") - public Set<String> keySet() { - return Collections.EMPTY_SET; - } + public Set<String> keySet(); /** * Returns the set of all property values of this object. * * @return set of property values. */ - @SuppressWarnings("unchecked") - public Collection<Object> values() { - return Collections.EMPTY_SET; - } + public Collection<Object> values(); // JavaScript instanceof check @@ -181,9 +142,7 @@ * @param instance instace to check * @return true if the given 'instance' is an instance of this 'function' object */ - public boolean isInstance(final Object instance) { - return false; - } + public boolean isInstance(final Object instance); /** * Checking whether this object is an instance of the given 'clazz' object. @@ -191,47 +150,40 @@ * @param clazz clazz to check * @return true if this object is an instance of the given 'clazz' */ - public boolean isInstanceOf(final Object clazz) { - if (clazz instanceof JSObject) { - return ((JSObject)clazz).isInstance(this); - } - - return false; - } + public boolean isInstanceOf(final Object clazz); /** * ECMA [[Class]] property * * @return ECMA [[Class]] property value of this object */ - public String getClassName() { - return getClass().getName(); - } + public String getClassName(); /** * Is this a function object? * * @return if this mirror wraps a ECMAScript function instance */ - public boolean isFunction() { - return false; - } + public boolean isFunction(); /** * Is this a 'use strict' function object? * * @return true if this mirror represents a ECMAScript 'use strict' function */ - public boolean isStrictFunction() { - return false; - } + public boolean isStrictFunction(); /** * Is this an array object? * * @return if this mirror wraps a ECMAScript array object */ - public boolean isArray() { - return false; - } + public boolean isArray(); + + /** + * Returns this object's numeric value. + * + * @return this object's numeric value. + */ + public double toNumber(); }
--- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Mon Oct 28 12:29:40 2013 -0700 @@ -43,6 +43,7 @@ import javax.script.Bindings; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.GlobalObject; +import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -50,7 +51,7 @@ /** * Mirror object that wraps a given Nashorn Script object. */ -public final class ScriptObjectMirror extends JSObject implements Bindings { +public final class ScriptObjectMirror extends AbstractJSObject implements Bindings { private static AccessControlContext getContextAccCtxt() { final Permissions perms = new Permissions(); perms.add(new RuntimePermission(Context.NASHORN_GET_CONTEXT)); @@ -161,7 +162,6 @@ }); } - @Override public Object callMember(final String functionName, final Object... args) { functionName.getClass(); // null check final ScriptObject oldGlobal = Context.getGlobal(); @@ -705,4 +705,13 @@ } } } + + @Override + public double toNumber() { + return inGlobal(new Callable<Double>() { + @Override public Double call() { + return JSType.toNumber(sobj); + } + }); + } }
--- a/src/jdk/nashorn/internal/codegen/BranchOptimizer.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/BranchOptimizer.java Mon Oct 28 12:29:40 2013 -0700 @@ -72,8 +72,7 @@ } // convert to boolean - codegen.load(unaryNode); - method.convert(Type.BOOLEAN); + codegen.load(unaryNode, Type.BOOLEAN); if (state) { method.ifne(label); } else { @@ -146,8 +145,7 @@ break; } - codegen.load(binaryNode); - method.convert(Type.BOOLEAN); + codegen.load(binaryNode, Type.BOOLEAN); if (state) { method.ifne(label); } else { @@ -169,8 +167,7 @@ } } - codegen.load(node); - method.convert(Type.BOOLEAN); + codegen.load(node, Type.BOOLEAN); if (state) { method.ifne(label); } else {
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Mon Oct 28 12:29:40 2013 -0700 @@ -402,7 +402,7 @@ return loadBinaryOperands(node.lhs(), node.rhs(), node.getType(), false); } - private MethodEmitter load(final Expression node, final Type type) { + MethodEmitter load(final Expression node, final Type type) { return load(node, type, false); } @@ -432,7 +432,7 @@ @Override public boolean enterAccessNode(final AccessNode accessNode) { if (!baseAlreadyOnStack) { - load(accessNode.getBase()).convert(Type.OBJECT); + load(accessNode.getBase(), Type.OBJECT); } assert method.peekType().isObject(); method.dynamicGet(type, accessNode.getProperty().getName(), getCallSiteFlags(), accessNode.isFunction()); @@ -442,7 +442,7 @@ @Override public boolean enterIndexNode(final IndexNode indexNode) { if (!baseAlreadyOnStack) { - load(indexNode.getBase()).convert(Type.OBJECT); + load(indexNode.getBase(), Type.OBJECT); load(indexNode.getIndex()); } method.dynamicGetIndex(type, getCallSiteFlags(), indexNode.isFunction()); @@ -632,11 +632,13 @@ final Type[] params = signature == null ? null : Type.getMethodArguments(signature); for (final Expression arg : args) { assert arg != null; - load(arg); if (n >= argCount) { + load(arg); method.pop(); // we had to load the arg for its side effects } else if (params != null) { - method.convert(params[n]); + load(arg, params[n]); + } else { + load(arg); } n++; } @@ -1277,7 +1279,7 @@ for (int i = 0; i < args.size(); i++) { method.dup(); method.load(i); - load(args.get(i)).convert(Type.OBJECT); //has to be upcast to object or we fail + load(args.get(i), Type.OBJECT); //has to be upcast to object or we fail method.arraystore(); } @@ -1719,7 +1721,7 @@ } for (final Expression arg : args) { - load(arg).convert(Type.OBJECT); + load(arg, Type.OBJECT); } method.invokestatic( @@ -2105,7 +2107,7 @@ if (exceptionCondition != null) { next = new Label("next"); - load(exceptionCondition).convert(Type.BOOLEAN).ifeq(next); + load(exceptionCondition, Type.BOOLEAN).ifeq(next); } else { next = null; } @@ -2352,7 +2354,7 @@ final List<Expression> args = callNode.getArgs(); // Load function reference. - load(callNode.getFunction()).convert(Type.OBJECT); // must detect type error + load(callNode.getFunction(), Type.OBJECT); // must detect type error method.dynamicNew(1 + loadArgs(args), getCallSiteFlags()); method.store(unaryNode.getSymbol()); @@ -2383,7 +2385,7 @@ @Override public boolean enterSUB(final UnaryNode unaryNode) { assert unaryNode.getType().isNumeric(); - load(unaryNode.rhs()).convert(unaryNode.getType()).neg().store(unaryNode.getSymbol()); + load(unaryNode.rhs(), unaryNode.getType()).neg().store(unaryNode.getSymbol()); return false; } @@ -2424,7 +2426,7 @@ final Label skip = new Label("skip"); - load(lhs).convert(Type.OBJECT).dup().convert(Type.BOOLEAN); + load(lhs, Type.OBJECT).dup().convert(Type.BOOLEAN); if (binaryNode.tokenType() == TokenType.AND) { method.ifeq(skip); @@ -2433,7 +2435,7 @@ } method.pop(); - load(rhs).convert(Type.OBJECT); + load(rhs, Type.OBJECT); method.label(skip); method.store(binaryNode.getSymbol());
--- a/src/jdk/nashorn/internal/codegen/Lower.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/Lower.java Mon Oct 28 12:29:40 2013 -0700 @@ -88,12 +88,12 @@ private static final DebugLogger LOG = new DebugLogger("lower"); // needed only to get unique eval id - private final CodeInstaller installer; + private final CodeInstaller<?> installer; /** * Constructor. */ - Lower(final CodeInstaller installer) { + Lower(final CodeInstaller<?> installer) { super(new BlockLexicalContext() { @Override
--- a/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java Mon Oct 28 12:29:40 2013 -0700 @@ -32,7 +32,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; - import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.LiteralNode; @@ -143,7 +142,7 @@ method.dup(); method.getField(Type.getInternalName(ScriptObject.class), "spill", Type.OBJECT_ARRAY.getDescriptor()); method.load(property.getSlot()); - codegen.load(values.get(i)).convert(OBJECT); + codegen.load(values.get(i), OBJECT); method.arraystore(); } }
--- a/src/jdk/nashorn/internal/objects/Global.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/Global.java Mon Oct 28 12:29:40 2013 -0700 @@ -1665,9 +1665,9 @@ final ScriptObject stringPrototype = getStringPrototype(); stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0); - // add Array.prototype.length + // set isArray flag on Array.prototype final ScriptObject arrayPrototype = getArrayPrototype(); - arrayPrototype.addOwnProperty("length", Attribute.NOT_ENUMERABLE|Attribute.NOT_CONFIGURABLE, 0.0); + arrayPrototype.setIsArray(); this.DEFAULT_DATE = new NativeDate(Double.NaN, this);
--- a/src/jdk/nashorn/internal/objects/NativeArray.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java Mon Oct 28 12:29:40 2013 -0700 @@ -372,9 +372,7 @@ */ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) public static Object isArray(final Object self, final Object arg) { - return isArray(arg) || (arg == Global.instance().getArrayPrototype()) - || (arg instanceof NativeRegExpExecResult) - || (arg instanceof JSObject && ((JSObject)arg).isArray()); + return isArray(arg) || (arg instanceof JSObject && ((JSObject)arg).isArray()); } /** @@ -403,6 +401,26 @@ } } + /** + * Prototype length getter + * @param self self reference + * @return the length of the object + */ + @Getter(name = "length", where = Where.PROTOTYPE, attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE) + public static Object getProtoLength(final Object self) { + return length(self); // Same as instance getter but we can't make nasgen use the same method for prototype + } + + /** + * Prototype length setter + * @param self self reference + * @param length new length property + */ + @Setter(name = "length", where = Where.PROTOTYPE, attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE) + public static void setProtoLength(final Object self, final Object length) { + length(self, length); // Same as instance setter but we can't make nasgen use the same method for prototype + } + static long validLength(final Object length, final boolean reject) { final double doubleLength = JSType.toNumber(length); if (!Double.isNaN(doubleLength) && JSType.isRepresentableAsLong(doubleLength)) { @@ -1007,19 +1025,42 @@ final long actualStart = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len); final long actualDeleteCount = Math.min(Math.max(JSType.toLong(deleteCount), 0), len - actualStart); - final NativeArray array = new NativeArray(actualDeleteCount); + NativeArray returnValue; + + if (actualStart <= Integer.MAX_VALUE && actualDeleteCount <= Integer.MAX_VALUE && bulkable(sobj)) { + try { + returnValue = new NativeArray(sobj.getArray().fastSplice((int)actualStart, (int)actualDeleteCount, items.length)); - for (long k = 0; k < actualDeleteCount; k++) { - final long from = actualStart + k; + // Since this is a dense bulkable array we can use faster defineOwnProperty to copy new elements + int k = (int) actualStart; + for (int i = 0; i < items.length; i++, k++) { + sobj.defineOwnProperty(k, items[i]); + } + } catch (UnsupportedOperationException uoe) { + returnValue = slowSplice(sobj, actualStart, actualDeleteCount, items, len); + } + } else { + returnValue = slowSplice(sobj, actualStart, actualDeleteCount, items, len); + } + + return returnValue; + } + + private static NativeArray slowSplice(final ScriptObject sobj, final long start, final long deleteCount, final Object[] items, final long len) { + + final NativeArray array = new NativeArray(deleteCount); + + for (long k = 0; k < deleteCount; k++) { + final long from = start + k; if (sobj.has(from)) { array.defineOwnProperty(ArrayIndex.getArrayIndex(k), sobj.get(from)); } } - if (items.length < actualDeleteCount) { - for (long k = actualStart; k < (len - actualDeleteCount); k++) { - final long from = k + actualDeleteCount; + if (items.length < deleteCount) { + for (long k = start; k < (len - deleteCount); k++) { + final long from = k + deleteCount; final long to = k + items.length; if (sobj.has(from)) { @@ -1029,12 +1070,12 @@ } } - for (long k = len; k > (len - actualDeleteCount + items.length); k--) { + for (long k = len; k > (len - deleteCount + items.length); k--) { sobj.delete(k - 1, true); } - } else if (items.length > actualDeleteCount) { - for (long k = len - actualDeleteCount; k > actualStart; k--) { - final long from = k + actualDeleteCount - 1; + } else if (items.length > deleteCount) { + for (long k = len - deleteCount; k > start; k--) { + final long from = k + deleteCount - 1; final long to = k + items.length - 1; if (sobj.has(from)) { @@ -1046,12 +1087,12 @@ } } - long k = actualStart; + long k = start; for (int i = 0; i < items.length; i++, k++) { sobj.set(k, items[i], true); } - final long newLength = len - actualDeleteCount + items.length; + final long newLength = len - deleteCount + items.length; sobj.set("length", newLength, true); return array; @@ -1122,12 +1163,16 @@ try { final ScriptObject sobj = (ScriptObject)Global.toObject(self); final long len = JSType.toUint32(sobj.getLength()); - final long n = JSType.toLong(fromIndex); - - if (len == 0 || n >= len) { + if (len == 0) { return -1; } + final long n = JSType.toLong(fromIndex); + if (n >= len) { + return -1; + } + + for (long k = Math.max(0, (n < 0) ? (len - Math.abs(n)) : n); k < len; k++) { if (sobj.has(k)) { if (ScriptRuntime.EQ_STRICT(sobj.get(k), searchElement)) {
--- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Mon Oct 28 12:29:40 2013 -0700 @@ -629,7 +629,8 @@ // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, func.makeBoundFunction(this, new Object[] { name })), 0, Object.class), - adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), testJSAdaptor(adaptee, null, null, null)); + adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), + testJSAdaptor(adaptee, null, null, null)); } } throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
--- a/src/jdk/nashorn/internal/objects/NativeString.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeString.java Mon Oct 28 12:29:40 2013 -0700 @@ -505,7 +505,7 @@ */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object charAt(final Object self, final Object pos) { - return charAt(self, JSType.toInteger(pos)); + return charAtImpl(checkObjectToString(self), JSType.toInteger(pos)); } /** @@ -527,7 +527,10 @@ */ @SpecializedFunction public static String charAt(final Object self, final int pos) { - final String str = checkObjectToString(self); + return charAtImpl(checkObjectToString(self), pos); + } + + private static String charAtImpl(final String str, final int pos) { return (pos < 0 || pos >= str.length()) ? "" : String.valueOf(str.charAt(pos)); } @@ -539,7 +542,7 @@ */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object charCodeAt(final Object self, final Object pos) { - return charCodeAt(self, JSType.toInteger(pos)); + return charCodeAtImpl(checkObjectToString(self), JSType.toInteger(pos)); } /** @@ -561,7 +564,10 @@ */ @SpecializedFunction public static double charCodeAt(final Object self, final int pos) { - final String str = checkObjectToString(self); + return charCodeAtImpl(checkObjectToString(self), pos); + } + + private static double charCodeAtImpl(final String str, final int pos) { return (pos < 0 || pos >= str.length()) ? Double.NaN : str.charAt(pos); }
--- a/src/jdk/nashorn/internal/parser/Lexer.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/parser/Lexer.java Mon Oct 28 12:29:40 2013 -0700 @@ -47,7 +47,6 @@ import jdk.nashorn.internal.runtime.ECMAErrors; import jdk.nashorn.internal.runtime.ErrorManager; import jdk.nashorn.internal.runtime.JSErrorType; -import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ParserException; import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.options.Options; @@ -1054,16 +1053,6 @@ } /** - * Convert string to number. - * - * @param valueString String to convert. - * @return Converted number. - */ - private static Number valueOf(final String valueString) throws NumberFormatException { - return JSType.narrowestIntegerRepresentation(Double.valueOf(valueString)); - } - - /** * Scan a number. */ protected void scanNumber() { @@ -1623,7 +1612,7 @@ case HEXADECIMAL: return Lexer.valueOf(source.getString(start + 2, len - 2), 16); // number case FLOATING: - return Lexer.valueOf(source.getString(start, len)); // number + return Double.valueOf(source.getString(start, len)); // number case STRING: return source.getString(start, len); // String case ESCSTRING:
--- a/src/jdk/nashorn/internal/runtime/JSType.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Mon Oct 28 12:29:40 2013 -0700 @@ -210,26 +210,6 @@ } /** - * Get the smallest integer representation of a number. Returns an Integer - * for something that is int representable, and Long for something that - * is long representable. If the number needs to be a double, this is an - * identity function - * - * @param number number to check - * - * @return Number instanceof the narrowest possible integer representation for number - */ - public static Number narrowestIntegerRepresentation(final double number) { - if (isRepresentableAsInt(number)) { - return (int)number; - } else if (isRepresentableAsLong(number)) { - return (long)number; - } else { - return number; - } - } - - /** * Check whether an object is primitive * * @param obj an object @@ -266,12 +246,11 @@ * @return the primitive form of the object */ public static Object toPrimitive(final Object obj, final Class<?> hint) { - if (!(obj instanceof ScriptObject)) { - return obj; - } + return obj instanceof ScriptObject ? toPrimitive((ScriptObject)obj, hint) : obj; + } - final ScriptObject sobj = (ScriptObject)obj; - final Object result = sobj.getDefaultValue(hint); + private static Object toPrimitive(final ScriptObject sobj, final Class<?> hint) { + final Object result = sobj.getDefaultValue(hint); if (!isPrimitive(result)) { throw typeError("bad.default.value", result.toString()); @@ -495,6 +474,19 @@ return toNumberGeneric(obj); } + + /** + * JavaScript compliant conversion of Object to number + * See ECMA 9.3 ToNumber + * + * @param obj an object + * + * @return a number + */ + public static double toNumber(final ScriptObject obj) { + return toNumber(toPrimitive(obj, Number.class)); + } + /** * Digit representation for a character * @@ -1048,7 +1040,11 @@ } if (obj instanceof ScriptObject) { - return toNumber(toPrimitive(obj, Number.class)); + return toNumber((ScriptObject)obj); + } + + if (obj instanceof JSObject) { + return ((JSObject)obj).toNumber(); } return Double.NaN;
--- a/src/jdk/nashorn/internal/runtime/ListAdapter.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java Mon Oct 28 12:29:40 2013 -0700 @@ -33,6 +33,7 @@ import java.util.RandomAccess; import java.util.concurrent.Callable; import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.InvokeByName; @@ -135,7 +136,8 @@ */ public static ListAdapter create(final Object obj) { if (obj instanceof ScriptObject) { - return new ScriptObjectListAdapter((ScriptObject)obj); + final Object mirror = ScriptObjectMirror.wrap(obj, Context.getGlobal()); + return new JSObjectListAdapter((JSObject)mirror); } else if (obj instanceof JSObject) { return new JSObjectListAdapter((JSObject)obj); } else {
--- a/src/jdk/nashorn/internal/runtime/PropertyMap.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java Mon Oct 28 12:29:40 2013 -0700 @@ -26,6 +26,8 @@ package jdk.nashorn.internal.runtime; import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_HASHMAP; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; import java.lang.invoke.SwitchPoint; import java.lang.ref.WeakReference; @@ -50,6 +52,8 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener { /** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */ public static final int NOT_EXTENSIBLE = 0b0000_0001; + /** Does this map contain valid array keys? */ + public static final int CONTAINS_ARRAY_KEYS = 0b0000_0010; /** This mask is used to preserve certain flags when cloning the PropertyMap. Others should not be copied */ private static final int CLONEABLE_FLAGS_MASK = 0b0000_1111; /** Has a listener been added to this property map. This flag is not copied when cloning a map. See {@link PropertyListener} */ @@ -91,12 +95,16 @@ * @param fieldCount Number of fields in use. * @param fieldMaximum Number of fields available. * @param spillLength Number of spill slots used. + * @param containsArrayKeys True if properties contain numeric keys */ - private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum, final int spillLength) { + private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum, final int spillLength, final boolean containsArrayKeys) { this.properties = properties; this.fieldCount = fieldCount; this.fieldMaximum = fieldMaximum; this.spillLength = spillLength; + if (containsArrayKeys) { + setContainsArrayKeys(); + } if (Context.DEBUG) { count++; @@ -104,15 +112,6 @@ } /** - * Constructor. - * - * @param properties A {@link PropertyHashMap} with initial contents. - */ - private PropertyMap(final PropertyHashMap properties) { - this(properties, 0, 0, 0); - } - - /** * Cloning constructor. * * @param propertyMap Existing property map. @@ -152,12 +151,15 @@ if (Context.DEBUG) { duplicatedCount++; } - return new PropertyMap(this.properties); + return new PropertyMap(this.properties, 0, 0, 0, containsArrayKeys()); } /** * Public property map allocator. * + * <p>It is the caller's responsibility to make sure that {@code properties} does not contain + * properties with keys that are valid array indices.</p> + * * @param properties Collection of initial properties. * @param fieldCount Number of fields in use. * @param fieldMaximum Number of fields available. @@ -166,11 +168,15 @@ */ public static PropertyMap newMap(final Collection<Property> properties, final int fieldCount, final int fieldMaximum, final int spillLength) { PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties); - return new PropertyMap(newProperties, fieldCount, fieldMaximum, spillLength); + return new PropertyMap(newProperties, fieldCount, fieldMaximum, spillLength, false); } /** * Public property map allocator. Used by nasgen generated code. + * + * <p>It is the caller's responsibility to make sure that {@code properties} does not contain + * properties with keys that are valid array indices.</p> + * * @param properties Collection of initial properties. * @return New {@link PropertyMap}. */ @@ -184,7 +190,7 @@ * @return New empty {@link PropertyMap}. */ public static PropertyMap newMap() { - return new PropertyMap(EMPTY_HASHMAP); + return new PropertyMap(EMPTY_HASHMAP, 0, 0, 0, false); } /** @@ -294,6 +300,9 @@ if(!property.isSpill()) { newMap.fieldCount = Math.max(newMap.fieldCount, property.getSlot() + 1); } + if (isValidArrayIndex(getArrayIndex(property.getKey()))) { + newMap.setContainsArrayKeys(); + } newMap.spillLength += property.getSpillCount(); } @@ -408,6 +417,9 @@ final PropertyMap newMap = new PropertyMap(this, newProperties); for (final Property property : otherProperties) { + if (isValidArrayIndex(getArrayIndex(property.getKey()))) { + newMap.setContainsArrayKeys(); + } newMap.spillLength += property.getSpillCount(); } @@ -700,6 +712,22 @@ } /** + * Check if this map contains properties with valid array keys + * + * @return {@code true} if this map contains properties with valid array keys + */ + public final boolean containsArrayKeys() { + return (flags & CONTAINS_ARRAY_KEYS) != 0; + } + + /** + * Flag this object as having array keys in defined properties + */ + private void setContainsArrayKeys() { + flags |= CONTAINS_ARRAY_KEYS; + } + + /** * Check whether a {@link PropertyListener} has been added to this map. * * @return {@code true} if {@link PropertyListener} exists
--- a/src/jdk/nashorn/internal/runtime/ScriptLoader.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptLoader.java Mon Oct 28 12:29:40 2013 -0700 @@ -52,24 +52,10 @@ @Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { checkPackageAccess(name); - try { - return super.loadClass(name, resolve); - } catch (final ClassNotFoundException | SecurityException e) { - // We'll get ClassNotFoundException for Nashorn 'struct' classes. - // Also, we'll get SecurityException for jdk.nashorn.internal.* - // classes. So, load these using to context's 'shared' loader. - // All these classes start with "jdk.nashorn.internal." prefix. - try { - if (name.startsWith(NASHORN_PKG_PREFIX)) { - return context.getSharedLoader().loadClass(name); - } - } catch (final ClassNotFoundException ignored) { - //ignored - } - - // throw the original exception from here - throw e; + if (name.startsWith(NASHORN_PKG_PREFIX)) { + return context.getSharedLoader().loadClass(name); } + return super.loadClass(name, resolve); } // package-private and private stuff below this point
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Oct 28 12:29:40 2013 -0700 @@ -508,7 +508,7 @@ if (property == null) { // promoting an arrayData value to actual property addOwnProperty(key, propFlags, value); - removeArraySlot(key); + checkIntegerKey(key); } else { // Now set the new flags modifyOwnProperty(property, propFlags); @@ -594,7 +594,7 @@ * @param index key for property * @param value value to define */ - protected final void defineOwnProperty(final int index, final Object value) { + public final void defineOwnProperty(final int index, final Object value) { assert isValidArrayIndex(index) : "invalid array index"; final long longIndex = ArrayIndex.toLongIndex(index); if (longIndex >= getArray().length()) { @@ -616,15 +616,6 @@ } } - private void removeArraySlot(final String key) { - final int index = getArrayIndex(key); - final ArrayData array = getArray(); - - if (array.has(index)) { - setArray(array.delete(index)); - } - } - /** * Add a new property to the object. * @@ -1203,21 +1194,10 @@ * Check if this ScriptObject has array entries. This means that someone has * set values with numeric keys in the object. * - * Note: this can be O(n) up to the array length - * * @return true if array entries exists. */ public boolean hasArrayEntries() { - final ArrayData array = getArray(); - final long length = array.length(); - - for (long i = 0; i < length; i++) { - if (array.has((int)i)) { - return true; - } - } - - return false; + return getArray().length() > 0 || getMap().containsArrayKeys(); } /** @@ -2356,8 +2336,29 @@ } if (newLength < arrayLength) { - setArray(getArray().shrink(newLength)); - getArray().setLength(newLength); + long actualLength = newLength; + + // Check for numeric keys in property map and delete them or adjust length, depending on whether + // they're defined as configurable. See ES5 #15.4.5.2 + if (getMap().containsArrayKeys()) { + + for (long l = arrayLength - 1; l >= newLength; l--) { + final FindProperty find = findProperty(JSType.toString(l), false); + + if (find != null) { + + if (find.getProperty().isConfigurable()) { + deleteOwnProperty(find.getProperty()); + } else { + actualLength = l + 1; + break; + } + } + } + } + + setArray(getArray().shrink(actualLength)); + getArray().setLength(actualLength); } } @@ -2680,7 +2681,7 @@ final long oldLength = getArray().length(); final long longIndex = index & JSType.MAX_UINT; - if (!getArray().has(index)) { + if (getMap().containsArrayKeys()) { final String key = JSType.toString(longIndex); final FindProperty find = findProperty(key, true);
--- a/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java Thu Oct 24 09:10:54 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package jdk.nashorn.internal.runtime; - -/** - * A ListAdapter that can wrap a ScriptObject. - */ -public final class ScriptObjectListAdapter extends ListAdapter { - /** - * Creates a new list wrapper for the specified ScriptObject. - * @param obj script the object to wrap - */ - public ScriptObjectListAdapter(final ScriptObject obj) { - super(obj); - } - - @Override - public int size() { - return JSType.toInt32(((ScriptObject)obj).getLength()); - } - - @Override - protected Object getAt(int index) { - return ((ScriptObject)obj).get(index); - } - - @Override - protected void setAt(int index, Object element) { - ((ScriptObject)obj).set(index, element, false); - } -}
--- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Mon Oct 28 12:29:40 2013 -0700 @@ -47,6 +47,7 @@ import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.ir.debug.JSONWriter; +import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.parser.Lexer; import jdk.nashorn.internal.runtime.linker.Bootstrap; @@ -258,6 +259,11 @@ return ((Map<?,?>)obj).keySet().iterator(); } + final Object wrapped = Global.instance().wrapAsObject(obj); + if (wrapped instanceof ScriptObject) { + return ((ScriptObject)wrapped).propertyIterator(); + } + return Collections.emptyIterator(); } @@ -336,6 +342,11 @@ return ((Iterable<?>)obj).iterator(); } + final Object wrapped = Global.instance().wrapAsObject(obj); + if (wrapped instanceof ScriptObject) { + return ((ScriptObject)wrapped).valueIterator(); + } + return Collections.emptyIterator(); }
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Mon Oct 28 12:29:40 2013 -0700 @@ -461,7 +461,23 @@ */ public abstract ArrayData slice(long from, long to); - private static Class<?> widestType(final Object... items) { + /** + * Fast splice operation. This just modifies the array according to the number of + * elements added and deleted but does not insert the added elements. Throws + * {@code UnsupportedOperationException} if fast splice operation is not supported + * for this class or arguments. + * + * @param start start index of splice operation + * @param removed number of removed elements + * @param added number of added elements + * @throws UnsupportedOperationException if fast splice is not supported for the class or arguments. + */ + public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + + static Class<?> widestType(final Object... items) { assert items.length > 0; Class<?> widest = Integer.class;
--- a/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Mon Oct 28 12:29:40 2013 -0700 @@ -269,4 +269,32 @@ return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength); } + + @Override + public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException { + final long oldLength = length(); + final long newLength = oldLength - removed + added; + if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) { + throw new UnsupportedOperationException(); + } + final ArrayData returnValue = (removed == 0) ? + EMPTY_ARRAY : new IntArrayData(Arrays.copyOfRange(array, start, start + removed), removed); + + if (newLength != oldLength) { + final int[] newArray; + + if (newLength > array.length) { + newArray = new int[ArrayData.nextSize((int)newLength)]; + System.arraycopy(array, 0, newArray, 0, start); + } else { + newArray = array; + } + + System.arraycopy(array, start + removed, newArray, start + added, (int)(oldLength - start - removed)); + array = newArray; + setLength(newLength); + } + + return returnValue; + } }
--- a/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Mon Oct 28 12:29:40 2013 -0700 @@ -92,7 +92,7 @@ @Override public ArrayData convert(final Class<?> type) { - if (type == Long.class) { + if (type == Integer.class || type == Long.class) { return this; } final int length = (int) length(); @@ -238,4 +238,32 @@ final long newLength = to - start; return new LongArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength); } + + @Override + public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException { + final long oldLength = length(); + final long newLength = oldLength - removed + added; + if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) { + throw new UnsupportedOperationException(); + } + final ArrayData returnValue = (removed == 0) ? + EMPTY_ARRAY : new LongArrayData(Arrays.copyOfRange(array, start, start + removed), removed); + + if (newLength != oldLength) { + final long[] newArray; + + if (newLength > array.length) { + newArray = new long[ArrayData.nextSize((int)newLength)]; + System.arraycopy(array, 0, newArray, 0, start); + } else { + newArray = array; + } + + System.arraycopy(array, start + removed, newArray, start + added, (int)(oldLength - start - removed)); + array = newArray; + setLength(newLength); + } + + return returnValue; + } }
--- a/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Mon Oct 28 12:29:40 2013 -0700 @@ -218,4 +218,32 @@ final long newLength = to - start; return new NumberArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength); } + + @Override + public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException { + final long oldLength = length(); + final long newLength = oldLength - removed + added; + if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) { + throw new UnsupportedOperationException(); + } + final ArrayData returnValue = (removed == 0) ? + EMPTY_ARRAY : new NumberArrayData(Arrays.copyOfRange(array, start, start + removed), removed); + + if (newLength != oldLength) { + final double[] newArray; + + if (newLength > array.length) { + newArray = new double[ArrayData.nextSize((int)newLength)]; + System.arraycopy(array, 0, newArray, 0, start); + } else { + newArray = array; + } + + System.arraycopy(array, start + removed, newArray, start + added, (int)(oldLength - start - removed)); + array = newArray; + setLength(newLength); + } + + return returnValue; + } }
--- a/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java Mon Oct 28 12:29:40 2013 -0700 @@ -206,4 +206,32 @@ final long newLength = to - start; return new ObjectArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength); } + + @Override + public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException { + final long oldLength = length(); + final long newLength = oldLength - removed + added; + if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) { + throw new UnsupportedOperationException(); + } + final ArrayData returnValue = (removed == 0) ? + EMPTY_ARRAY : new ObjectArrayData(Arrays.copyOfRange(array, start, start + removed), removed); + + if (newLength != oldLength) { + final Object[] newArray; + + if (newLength > array.length) { + newArray = new Object[ArrayData.nextSize((int)newLength)]; + System.arraycopy(array, 0, newArray, 0, start); + } else { + newArray = array; + } + + System.arraycopy(array, start + removed, newArray, start + added, (int)(oldLength - start - removed)); + array = newArray; + setLength(newLength); + } + + return returnValue; + } }
--- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Thu Oct 24 09:10:54 2013 -0700 +++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Mon Oct 28 12:29:40 2013 -0700 @@ -25,25 +25,28 @@ package jdk.nashorn.internal.runtime.linker; -import jdk.nashorn.internal.lookup.MethodHandleFunctionality; -import jdk.nashorn.internal.lookup.MethodHandleFactory; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.util.HashMap; +import java.util.Map; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; +import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; import jdk.internal.dynalink.support.CallSiteDescriptorFactory; +import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.internal.lookup.MethodHandleFactory; +import jdk.nashorn.internal.lookup.MethodHandleFunctionality; import jdk.nashorn.internal.runtime.JSType; -import jdk.nashorn.api.scripting.JSObject; /** * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well * as ScriptObjects from other Nashorn contexts. */ -final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { +final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory { @Override public boolean canLinkType(final Class<?> type) { return canLinkTypeStatic(type); @@ -75,6 +78,22 @@ return Bootstrap.asType(inv, linkerServices, desc); } + @Override + public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception { + final boolean sourceIsAlwaysJSObject = JSObject.class.isAssignableFrom(sourceType); + if(!sourceIsAlwaysJSObject && !sourceType.isAssignableFrom(JSObject.class)) { + return null; + } + + final MethodHandle converter = CONVERTERS.get(targetType); + if(converter == null) { + return null; + } + + return new GuardedInvocation(converter, sourceIsAlwaysJSObject ? null : IS_JSOBJECT_GUARD).asType(MethodType.methodType(targetType, sourceType)); + } + + private static GuardedInvocation lookup(final CallSiteDescriptor desc) { final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0); final int c = desc.getNameTokenCount(); @@ -87,9 +106,7 @@ case "setElem": return c > 2 ? findSetMethod(desc) : findSetIndexMethod(); case "call": - return findCallMethod(desc, operator); - case "callMethod": - return findCallMethodMethod(desc, operator); + return findCallMethod(desc); case "new": return findNewMethod(desc); default: @@ -115,14 +132,7 @@ return new GuardedInvocation(JSOBJECTLINKER_PUT, null, IS_JSOBJECT_GUARD); } - private static GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final String operator) { - final String methodName = desc.getNameToken(2); - MethodHandle func = MH.insertArguments(JSOBJECT_CALLMEMBER, 1, methodName); - func = MH.asCollector(func, Object[].class, desc.getMethodType().parameterCount() - 1); - return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); - } - - private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) { + private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc) { final MethodHandle func = MH.asCollector(JSOBJECT_CALL, Object[].class, desc.getMethodType().parameterCount() - 2); return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); } @@ -163,6 +173,25 @@ } } + @SuppressWarnings("unused") + private static int toInt32(final JSObject obj) { + return JSType.toInt32(toNumber(obj)); + } + + @SuppressWarnings("unused") + private static long toInt64(final JSObject obj) { + return JSType.toInt64(toNumber(obj)); + } + + private static double toNumber(final JSObject obj) { + return obj == null ? 0 : obj.toNumber(); + } + + @SuppressWarnings("unused") + private static boolean toBoolean(final JSObject obj) { + return obj != null; + } + private static int getIndex(final Number n) { final double value = n.doubleValue(); return JSType.isRepresentableAsInt(value) ? (int)value : -1; @@ -178,27 +207,31 @@ // method handles of JSObject class private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH("getMember", Object.class, String.class); private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH("setMember", Void.TYPE, String.class, Object.class); - private static final MethodHandle JSOBJECT_CALLMEMBER = findJSObjectMH("callMember", Object.class, String.class, Object[].class); private static final MethodHandle JSOBJECT_CALL = findJSObjectMH("call", Object.class, Object.class, Object[].class); private static final MethodHandle JSOBJECT_NEW = findJSObjectMH("newObject", Object.class, Object[].class); + private static final Map<Class<?>, MethodHandle> CONVERTERS = new HashMap<>(); + static { + CONVERTERS.put(boolean.class, findOwnMH("toBoolean", boolean.class, JSObject.class)); + CONVERTERS.put(int.class, findOwnMH("toInt32", int.class, JSObject.class)); + CONVERTERS.put(long.class, findOwnMH("toInt64", long.class, JSObject.class)); + CONVERTERS.put(double.class, findOwnMH("toNumber", double.class, JSObject.class)); + } + private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { - final Class<?> own = JSObjectLinker.class; - final MethodType mt = MH.type(rtype, types); - try { - return MH.findStatic(MethodHandles.lookup(), own, name, mt); - } catch (final MethodHandleFactory.LookupException e) { - return MH.findVirtual(MethodHandles.lookup(), own, name, mt); - } + return findMH(name, JSObjectLinker.class, rtype, types); } private static MethodHandle findJSObjectMH(final String name, final Class<?> rtype, final Class<?>... types) { - final Class<?> own = JSObject.class; + return findMH(name, JSObject.class, rtype, types); + } + + private static MethodHandle findMH(final String name, final Class<?> target, final Class<?> rtype, final Class<?>... types) { final MethodType mt = MH.type(rtype, types); try { - return MH.findVirtual(MethodHandles.publicLookup(), own, name, mt); + return MH.findStatic(MethodHandles.lookup(), target, name, mt); } catch (final MethodHandleFactory.LookupException e) { - return MH.findVirtual(MethodHandles.lookup(), own, name, mt); + return MH.findVirtual(MethodHandles.lookup(), target, name, mt); } } }
--- a/src/overview.html Thu Oct 24 09:10:54 2013 -0700 +++ b/src/overview.html Mon Oct 28 12:29:40 2013 -0700 @@ -108,6 +108,6 @@ <h2>Other non-standard built-in objects</h2> In addition to {@code Java}, Nashorn also exposes some other non-standard built-in objects: <a href="jdk/nashorn/internal/objects/NativeJSAdapter.html">{@code JSAdapter}</a>, -<a href="jdk/nashorn/internal/objects/NativeJavaImporter.html">{@code JavaImporter}, +<a href="jdk/nashorn/internal/objects/NativeJavaImporter.html">{@code JavaImporter}</a>, <a href="jdk/nashorn/internal/runtime/NativeJavaPackage.html">{@code Packages}.</a> </body>
--- a/test/examples/array-micro.js Thu Oct 24 09:10:54 2013 -0700 +++ b/test/examples/array-micro.js Mon Oct 28 12:29:40 2013 -0700 @@ -90,6 +90,24 @@ array[6] = 6; }); +bench("push", function() { + var arr = [1, 2, 3]; + arr.push(4); + arr.push(5); + arr.push(6); +}); + +bench("pop", function() { + var arr = [1, 2, 3]; + arr.pop(); + arr.pop(); + arr.pop(); +}); + +bench("splice", function() { + [1, 2, 3].splice(0, 2, 5, 6, 7); +}); + var all = function(e) { return true; }; var none = function(e) { return false; };
--- a/test/script/basic/JDK-8024847.js Thu Oct 24 09:10:54 2013 -0700 +++ b/test/script/basic/JDK-8024847.js Mon Oct 28 12:29:40 2013 -0700 @@ -100,3 +100,9 @@ var jlist = Java.to(obj, java.util.List); print(jlist instanceof java.util.List); print(jlist); + +var obj = new JSObject() { + toNumber: function() { return 42; } +}; + +print(32 + obj);
--- a/test/script/basic/JDK-8024847.js.EXPECTED Thu Oct 24 09:10:54 2013 -0700 +++ b/test/script/basic/JDK-8024847.js.EXPECTED Mon Oct 28 12:29:40 2013 -0700 @@ -10,3 +10,4 @@ [hello, world] true [nashorn, js] +74
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026161.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,32 @@ +/* + * 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-8026161: Don't narrow floating-point literals in the lexer + * + * @test + * @run + */ + +print(new java.awt.Color(1, 1, 1)) // creates Color[r=1,g=1,b=1] +print(new java.awt.Color(1.0, 1.0, 1.0)) // Color[r=255,g=255,b=255]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026161.js.EXPECTED Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,2 @@ +java.awt.Color[r=1,g=1,b=1] +java.awt.Color[r=255,g=255,b=255]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026701.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,72 @@ +/* + * 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-8026701: Array.prototype.splice is slow on dense arrays + * + * @test + * @run + */ + +function testSplice(arr, e1, e2, e3) { + try { + print(arr); + print(arr.splice(3, 0, e1, e2, e3)); + print(arr); + print(arr.splice(2, 3)); + print(arr); + print(arr.splice(2, 3, arr[2], arr[3], arr[4])); + print(arr); + print(arr.splice(20, 10)); + print(arr); + print(arr.splice(arr.length, 0, e1, e2, e3)); + print(arr); + print(arr.splice(0, 2, arr[0], arr[1], arr[2], arr[3])); + print(arr); + } catch (error) { + print(error); + } +} + +function convert(array, type) { + return (typeof Java === "undefined") ? array : Java.from(Java.to(array, type)); +} + +// run some splice tests on all dense array implementations +testSplice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], -1, -2, -3); +testSplice(convert([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "long[]"), -1, -2, -3); +testSplice(convert([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "double[]"), -1, -2, -3); +testSplice(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], -1, -2, -3); + +// test array conversion during splice +testSplice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], -1, "-2", "-3"); +testSplice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], -1, -2.5, -3.5); +testSplice(convert([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "long[]"), -1, "-2", "-3"); +testSplice(convert([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "long[]"), -1, -2.5, -3.5); +testSplice(convert([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "double[]"), -1, "-2", "-3"); + +// test combination with defined elements +testSplice(Object.defineProperty([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5, {value: 13}), -1, -2, -3); +testSplice(Object.defineProperty([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5, {value: 13, writable: false}), -1, -2, -3); +testSplice(Object.defineProperty([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5, {value: 13, configurable: false}), -1, -2, -3); +testSplice(Object.defineProperty([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5, {value: 13, writable: false, configurable: false}), -1, -2, -3);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026701.js.EXPECTED Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,147 @@ +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,6,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,6,7,8,9,10 +-3,4,5 +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,6,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,6,7,8,9,10 +-3,4,5 +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,6,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,6,7,8,9,10 +-3,4,5 +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,6,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,6,7,8,9,10 +-3,4,5 +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,6,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,6,7,8,9,10 +-3,4,5 +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2.5,-3.5,4,5,6,7,8,9,10 +3,-1,-2.5 +1,2,-3.5,4,5,6,7,8,9,10 +-3.5,4,5 +1,2,-3.5,4,5,6,7,8,9,10 + +1,2,-3.5,4,5,6,7,8,9,10 + +1,2,-3.5,4,5,6,7,8,9,10,-1,-2.5,-3.5 +1,2 +1,2,-3.5,4,-3.5,4,5,6,7,8,9,10,-1,-2.5,-3.5 +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,6,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,6,7,8,9,10 +-3,4,5 +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2.5,-3.5,4,5,6,7,8,9,10 +3,-1,-2.5 +1,2,-3.5,4,5,6,7,8,9,10 +-3.5,4,5 +1,2,-3.5,4,5,6,7,8,9,10 + +1,2,-3.5,4,5,6,7,8,9,10 + +1,2,-3.5,4,5,6,7,8,9,10,-1,-2.5,-3.5 +1,2 +1,2,-3.5,4,-3.5,4,5,6,7,8,9,10,-1,-2.5,-3.5 +1,2,3,4,5,6,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,6,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,6,7,8,9,10 +-3,4,5 +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10 + +1,2,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,6,7,8,9,10,-1,-2,-3 +1,2,3,4,5,13,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,13,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,13,7,8,9,10 +-3,4,5 +1,2,-3,4,5,13,7,8,9,10 + +1,2,-3,4,5,13,7,8,9,10 + +1,2,-3,4,5,13,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,13,7,8,9,10,-1,-2,-3 +1,2,3,4,5,13,7,8,9,10 +TypeError: "5" is not a writable property of [object Array] +1,2,3,4,5,13,7,8,9,10 + +1,2,3,-1,-2,-3,4,5,13,7,8,9,10 +3,-1,-2 +1,2,-3,4,5,13,7,8,9,10 +-3,4,5 +1,2,-3,4,5,13,7,8,9,10 + +1,2,-3,4,5,13,7,8,9,10 + +1,2,-3,4,5,13,7,8,9,10,-1,-2,-3 +1,2 +1,2,-3,4,-3,4,5,13,7,8,9,10,-1,-2,-3 +1,2,3,4,5,13,7,8,9,10 +TypeError: "5" is not a writable property of [object Array]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026805.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,49 @@ +/* + * 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-8026805: Array.prototype.length doesn't work as expected + * + * @test + * @run + */ + +if (Array.prototype.length !== 0) { + throw new Error("Initial length not 0"); +} + +Array.prototype[3] = 1; + +if (Array.prototype.length !== 4) { + throw new Error("length not updated to 4"); +} + +Array.prototype.length = 0; + +if (Array.prototype.length !== 0) { + throw new Error("length not reset to 0"); +} + +if (3 in Array.prototype) { + throw new Error("array element not deleted"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026858.js Mon Oct 28 12:29:40 2013 -0700 @@ -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-8026858: Array length does not handle defined properties correctly + * + * @test + * @run + */ + +var arr = []; + +Object.defineProperty(arr, "3", {value: 1 /* configurable: false */}); + +if (arr[3] != 1) { + throw new Error("arr[3] not defined"); +} + +if (arr.length !== 4) { + throw new Error("Array length not updated to 4"); +} + +Object.defineProperty(arr, "5", {value: 1, configurable: true}); + +if (arr[5] != 1) { + throw new Error("arr[5] not defined"); +} + +if (arr.length !== 6) { + throw new Error("Array length not updated to 4"); +} + +arr.length = 0; + +if (5 in arr) { + throw new Error("configurable element was not deleted"); +} + +if (arr[3] != 1) { + throw new Error("non-configurable element was deleted"); +} + +if (arr.length !== 4) { + throw new Error("Array length not set"); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026955.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,51 @@ +/* + * 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-8026955: for-in should convert primitive values to object + * + * @test + * @run + */ + +Object.prototype[4] = "world"; +String.prototype[3] = "hello"; +Number.prototype[3] = "hello"; +Boolean.prototype[3] = "hello"; + +function testForIn(x) { + for (var i in x) { + print(i, x[i]); + } + for each (var i in x) { + print(i); + } +} + +testForIn("abc"); +testForIn(false); +testForIn(3); +testForIn(null); +testForIn(); +testForIn(String.prototype); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026955.js.EXPECTED Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,22 @@ +0 a +1 b +2 c +3 hello +4 world +a +b +c +hello +world +3 hello +4 world +hello +world +3 hello +4 world +hello +world +3 hello +4 world +hello +world
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8027016.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,42 @@ +/* + * 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-8027016: Array.prototype.indexOf should return -1 when array is of length zero + * + * @test + * @run + */ + +var res = [].indexOf(null, {valueOf:function(){throw "not reached"}}); +if (res != -1) { + fail("expected -1 on indexOf on empty array"); +} + +// add index beyond length check as well + +res = [].indexOf(null, 1); +if (res != -1) { + fail("expected -1 on indexOf on empty array"); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8027024.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,58 @@ +/* + * 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-8027024: String.prototype.charAt and charCodeAt do not evaluate 'self' and 'pos' arguments in right order + * + * @test + * @run + */ + + +String.prototype.charAt.call( + { + toString: function() { + print("charAt.self.toString"); + } + }, + + { + valueOf: function() { + print("charAt.pos.valueOf"); + } + } +); + +String.prototype.charCodeAt.call( + { + toString: function() { + print("charCodeAt.self.toString"); + } + }, + + { + valueOf: function() { + print("charCodeAt.pos.valueOf"); + } + } +);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8027024.js.EXPECTED Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,4 @@ +charAt.self.toString +charAt.pos.valueOf +charCodeAt.self.toString +charCodeAt.pos.valueOf
--- a/test/script/basic/NASHORN-397.js Thu Oct 24 09:10:54 2013 -0700 +++ b/test/script/basic/NASHORN-397.js Mon Oct 28 12:29:40 2013 -0700 @@ -35,11 +35,8 @@ fail("typeof(5).x is not 'number'"); } -// It is function because PrintStream implements Closeable, which is -// marked with @FunctionalInterface. Yes, this means calling a stream -// like "stream()" closes it. -if (typeof (java.lang.System.out) != 'function') { - fail("typeof java.lang.System.out is not 'object'"); +if (typeof (java.net.Proxy.NO_PROXY) != 'object') { + fail("typeof java.net.Proxy.NO_PROXY is not 'object'"); } if (typeof (java.lang.Math.PI) != 'number') {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/jfx.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 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. + */ + +/** + * Base library for JavaFX canvas run by Nashorn testing. + * @subtest + * + * + */ + +var System = Java.type("java.lang.System"); +var AWTImage = Java.type("org.jemmy.image.AWTImage"); +var PNGDecoder = Java.type("org.jemmy.image.PNGDecoder"); +var JemmyFxRoot = Java.type("org.jemmy.fx.Root"); +var AWTRobotCapturer = Java.type("org.jemmy.image.AWTRobotCapturer"); +var ByWindowType = Java.type("org.jemmy.fx.ByWindowType"); +var Scene = Java.type("javafx.scene.Scene"); +var Stage = Java.type("javafx.stage.Stage"); +var File = Java.type("java.io.File"); +var Timer = Java.type("java.util.Timer"); +var TimerTask = Java.type("java.util.TimerTask"); +var OSInfo = Java.type("sun.awt.OSInfo"); +var OSType = Java.type("sun.awt.OSInfo.OSType"); +var StringBuffer = Java.type("java.lang.StringBuffer"); + +var WAIT = 2000; +var TESTNAME = "test"; +var fsep = System.getProperty("file.separator"); + +function checkImageAndExit() { + var raceTimer = new Timer(true); + var timerTask = new TimerTask() { + run: function run() { + var tmpdir = System.getProperty("java.io.tmpdir"); + var timenow = (new Date()).getTime(); + makeScreenShot(tmpdir + fsep + "screenshot" + timenow +".png"); + var dupImg = isDuplicateImages(tmpdir + fsep + "screenshot" + timenow +".png", __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden"); + (new File(mpdir + fsep + "screenshot" + timenow +".png")).delete(); + if (!dupImg) System.err.println("ERROR: screenshot does not match golden image"); + exit(0); + } + }; + raceTimer.schedule(timerTask, WAIT); +} + +function makeScreenShot(shootToImg) { + JemmyFxRoot.ROOT.getEnvironment().setImageCapturer(new AWTRobotCapturer()); + var wrap = JemmyFxRoot.ROOT.lookup(new ByWindowType($STAGE.class)).lookup(Scene.class).wrap(0); + var imageJemmy = wrap.getScreenImage(); + imageJemmy.save(shootToImg); +} + +function isDuplicateImages(file1, file2) { + var f1 = new File(file1); + var f2; + var sb = new StringBuffer(file2); + if (OSInfo.getOSType() == OSType.WINDOWS) { + f2 = new File(sb.append(fsep + "windows.png").toString()); + } else if (OSInfo.getOSType() == OSType.LINUX) { + f2 = new File(sb.append(fsep + "linux.png").toString()); + } else if (OSInfo.getOSType() == OSType.MACOSX) { + f2 = new File(sb.append(fsep + "macosx.png").toString()); + } + print(f1.getAbsolutePath()); + print(f2.getAbsolutePath()); + if (f1.exists() && f2.exists()) { + var image1 = new AWTImage(PNGDecoder.decode(f1.getAbsolutePath())); + var image2 = new AWTImage(PNGDecoder.decode(f2.getAbsolutePath())); + return image1.compareTo(image2) == null ? true : false; + } + return false; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/jfx/flyingimage.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 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. + */ + +/** + * Testing JavaFX canvas run by Nashorn. + * + * @test/nocompare + * @run + * @fork + */ + +TESTNAME = "flyingimage"; + +var Image = Java.type("javafx.scene.image.Image"); +var Color = Java.type("javafx.scene.paint.Color"); +var Canvas = Java.type("javafx.scene.canvas.Canvas"); +var BorderPane = Java.type("javafx.scene.layout.BorderPane"); +var StackPane = Java.type("javafx.scene.layout.StackPane"); +var Font = Java.type("javafx.scene.text.Font"); +var FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType"); +var Text = Java.type("javafx.scene.text.Text"); + +var WIDTH = 800; +var HEIGHT = 600; +var canvas = new Canvas(WIDTH, HEIGHT); +function fileToURL(file) { + return new File(file).toURI().toURL().toExternalForm(); +} +var imageUrl = fileToURL(__DIR__ + "flyingimage/flyingimage.png"); +var img = new Image(imageUrl); +var font = new Font("Arial", 16); +var t = 0; +var isFrameRendered = false; +function renderFrame() { + var gc = canvas.graphicsContext2D; + gc.setFill(Color.web("#cccccc")); + gc.fillRect(0, 0, WIDTH, HEIGHT); + gc.setStroke(Color.web("#000000")); + gc.setLineWidth(1); + gc.strokeRect(5, 5, WIDTH - 10, HEIGHT - 10); + var c = 200; + var msc= 0.5 * HEIGHT / img.height; + var sp0 = 0.003; + for (var h = 0; h < c; h++, t++) { + gc.setTransform(1, 0, 0, 1, 0, 0); + var yh = h / (c - 1); + gc.translate((0.5 + Math.sin(t * sp0 + h * 0.1) / 3) * WIDTH, 25 + (HEIGHT * 3 / 4 - 40) * (yh * yh)); + var sc = 30 / img.height + msc * yh * yh; + gc.rotate(90 * Math.sin(t * sp0 + h * 0.1 + Math.PI)); + gc.scale(sc, sc); + gc.drawImage(img, -img.width / 2, -img.height / 2); + } + gc.setTransform(1, 0, 0, 1, 0, 0); + isFrameRendered = true; +} +var stack = new StackPane(); +var pane = new BorderPane(); + +pane.setCenter(canvas); +stack.getChildren().add(pane); +$STAGE.scene = new Scene(stack); +renderFrame(); +checkImageAndExit();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/jfx/kaleidoscope.js Mon Oct 28 12:29:40 2013 -0700 @@ -0,0 +1,162 @@ +/* + * Copyright (c) 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. + */ + +/** + * Testing JavaFX canvas run by Nashorn. + * + * @test/nocompare + * @run + * @fork + */ + +TESTNAME = "kaleidoscope"; +WAIT = 4000; + +var Paint = Java.type("javafx.scene.paint.Paint"); +var Canvas = Java.type("javafx.scene.canvas.Canvas"); +var BorderPane = Java.type("javafx.scene.layout.BorderPane"); +var StackPane = Java.type("javafx.scene.layout.StackPane"); +var StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); + +var WIDTH = 800; +var HEIGHT = 600; +var canvas = new Canvas(WIDTH, HEIGHT); +var context = canvas.graphicsContext2D; + +var x,y; +var p_x,p_y; +var a=0; +var b=0; +var angle=Math.PI/180*8; +var color=0; +var limit1=Math.PI*1.5; +var limit2=Math.PI*1.79; +var c=new Array(6); +var d=new Array(6); +var r,e; +var fade; +var prv_x,prv_y,prv_x2,prv_y2; + +function renderFrame() { + a=0.2*angle; + b=0.7*angle; + r=0; + fade=32; + for(var i=0;i<6;i++) + { + c[i]=1.0/(i+1)/2; + d[i]=1.0/(i+1)/2; + } + radius=Math.round((WIDTH+HEIGHT)/8); + e=radius*0.2; + p_x=Math.round(WIDTH/2); + p_y=Math.round(HEIGHT/2); + x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]); + y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]); + for (i = 0; i < 800; i++) { + anim(); + } +} + +function anim() { + var a1=Math.cos(a*2); + var a2=Math.cos(a*4); + var a3=Math.cos(a); + var a4=Math.sin(a); + if(b>limit1&&b<limit2) { + r+=radius*0.02*a1; + prv_x=x; + prv_y=y; + x=prv_x2+r*a3; + y=prv_y2+r*a4; + } else { + prv_x=x; + prv_y=y; + prv_x2=x; + prv_y2=y; + x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]); + y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]); + } + var c3=16*Math.cos(a*10); + var c1=Math.floor(56*Math.cos(a*angle*4)+c3); + var c2=Math.floor(56*Math.sin(a*angle*4)-c3); + context.lineCap=StrokeLineCap.ROUND; + context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.01-0.005*-a1)+')')); + context.lineWidth=e*1.4+e*0.8*a3; + draw_line(p_x,p_y,prv_x,prv_y,x,y); + context.lineWidth=e+e*0.8*a3; + draw_line(p_x,p_y,prv_x,prv_y,x,y); + context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.06-0.03*-a1)+')')); + context.lineWidth=e*0.6+e*0.35*a3; + draw_line(p_x,p_y,prv_x,prv_y,x,y); + context.setStroke(Paint.valueOf('rgba(0,0,0,0.06)')); + context.lineWidth=e*0.4+e*0.225*a3; + draw_line(p_x,p_y,prv_x,prv_y,x,y); + context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.1-0.075*-a1)+')')); + context.lineWidth=e*0.2+e*0.1*a3; + draw_line(p_x,p_y,prv_x,prv_y,x,y); + context.setStroke(Paint.valueOf('rgba(255,255,255,0.4)')); + context.lineWidth=e*(0.1-0.05*-a2); + draw_line(p_x,p_y,prv_x,prv_y,x,y); + a+=angle*Math.cos(b); + b+=angle*0.1; +} + +function draw_line(x,y,x1,y1,x2,y2) { + context.beginPath(); + context.moveTo(x+x1,y+y1); + context.lineTo(x+x2,y+y2); + context.moveTo(x-x1,y+y1); + context.lineTo(x-x2,y+y2); + context.moveTo(x-x1,y-y1); + context.lineTo(x-x2,y-y2); + context.moveTo(x+x1,y-y1); + context.lineTo(x+x2,y-y2); + context.moveTo(x+y1,y+x1); + context.lineTo(x+y2,y+x2); + context.moveTo(x-y1,y+x1); + context.lineTo(x-y2,y+x2); + context.moveTo(x-y1,y-x1); + context.lineTo(x-y2,y-x2); + context.moveTo(x+y1,y-x1); + context.lineTo(x+y2,y-x2); + context.moveTo(x,y+x2); + context.lineTo(x,y+x1); + context.moveTo(x,y-x2); + context.lineTo(x,y-x1); + context.moveTo(x+x2,y); + context.lineTo(x+x1,y); + context.moveTo(x-x2,y); + context.lineTo(x-x1,y); + context.stroke(); + context.closePath(); +} + +var stack = new StackPane(); +var pane = new BorderPane(); + +pane.setCenter(canvas); +stack.getChildren().add(pane); +$STAGE.scene = new Scene(stack); +renderFrame(); +checkImageAndExit(); \ No newline at end of file
--- a/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java Thu Oct 24 09:10:54 2013 -0700 +++ b/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java Mon Oct 28 12:29:40 2013 -0700 @@ -412,7 +412,7 @@ @Test public void accessMethodMixedWithEllipsis() throws ScriptException { - assertArrayEquals(new Object[] { "Hello", 10, true, -100500, 80 }, (Object[])e.eval("o.methodMixedWithEllipsis('Hello', 10, true, -100500,80.0);")); + assertArrayEquals(new Object[] { "Hello", 10, true, -100500, 80d }, (Object[])e.eval("o.methodMixedWithEllipsis('Hello', 10, true, -100500,80.0);")); assertArrayEquals(new Object[] { "Nashorn", 15 }, (Object[])e.eval("o.methodMixedWithEllipsis('Nashorn',15);")); } @@ -431,8 +431,8 @@ @Test public void accessMethodDoubleVSintOverloaded() throws ScriptException { - assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(0.0);")); - assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(1000.0);")); + assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.0);")); + assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(1000.0);")); assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.01);")); assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(100.02);")); assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(0);"));
--- a/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java Thu Oct 24 09:10:54 2013 -0700 +++ b/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java Mon Oct 28 12:29:40 2013 -0700 @@ -46,7 +46,7 @@ * JSObject implementations. */ public class PluggableJSObjectTest { - public static class MapWrapperObject extends JSObject { + public static class MapWrapperObject extends AbstractJSObject { private final HashMap<String, Object> map = new LinkedHashMap<>(); public HashMap<String, Object> getMap() { @@ -109,7 +109,7 @@ } } - public static class BufferObject extends JSObject { + public static class BufferObject extends AbstractJSObject { private final IntBuffer buf; public BufferObject(int size) { @@ -170,7 +170,7 @@ } } - public static class Adder extends JSObject { + public static class Adder extends AbstractJSObject { @Override public Object call(Object thiz, Object... args) { double res = 0.0; @@ -202,7 +202,7 @@ } } - public static class Factory extends JSObject { + public static class Factory extends AbstractJSObject { @Override public Object newObject(Object... args) { return new HashMap<Object, Object>();
--- a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Thu Oct 24 09:10:54 2013 -0700 +++ b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Mon Oct 28 12:29:40 2013 -0700 @@ -129,7 +129,7 @@ final ScriptEngine e = m.getEngineByName("nashorn"); try { e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); - JSObject obj = (JSObject) e.get("obj"); + ScriptObjectMirror obj = (ScriptObjectMirror) e.get("obj"); // try basic get on existing properties if (!obj.getMember("bar").equals("hello")) {