Merge
This commit is contained in:
commit
30066363bb
@ -156,6 +156,7 @@
|
|||||||
<fileset dir="${src.dir}/jdk/nashorn/tools/resources/"/>
|
<fileset dir="${src.dir}/jdk/nashorn/tools/resources/"/>
|
||||||
</copy>
|
</copy>
|
||||||
<copy file="${src.dir}/jdk/internal/dynalink/support/messages.properties" todir="${build.classes.dir}/jdk/internal/dynalink/support"/>
|
<copy file="${src.dir}/jdk/internal/dynalink/support/messages.properties" todir="${build.classes.dir}/jdk/internal/dynalink/support"/>
|
||||||
|
<copy file="${src.dir}/jdk/nashorn/internal/codegen/anchor.properties" todir="${build.classes.dir}/jdk/nashorn/internal/codegen"/>
|
||||||
|
|
||||||
<echo message="full=${nashorn.fullversion}" file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties"/>
|
<echo message="full=${nashorn.fullversion}" file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties"/>
|
||||||
<echo file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties" append="true">${line.separator}</echo>
|
<echo file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties" append="true">${line.separator}</echo>
|
||||||
|
@ -140,6 +140,11 @@ public final class ApplySpecialization extends NodeVisitor<LexicalContext> imple
|
|||||||
private boolean hasApplies(final FunctionNode functionNode) {
|
private boolean hasApplies(final FunctionNode functionNode) {
|
||||||
try {
|
try {
|
||||||
functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
|
functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
|
||||||
|
@Override
|
||||||
|
public boolean enterFunctionNode(final FunctionNode fn) {
|
||||||
|
return fn == functionNode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean enterCallNode(final CallNode callNode) {
|
public boolean enterCallNode(final CallNode callNode) {
|
||||||
if (isApply(callNode)) {
|
if (isApply(callNode)) {
|
||||||
@ -162,7 +167,7 @@ public final class ApplySpecialization extends NodeVisitor<LexicalContext> imple
|
|||||||
* scope, thus we are conservative and treat any access to arguments outside the
|
* scope, thus we are conservative and treat any access to arguments outside the
|
||||||
* apply call as a case of "we cannot apply the optimization".
|
* apply call as a case of "we cannot apply the optimization".
|
||||||
*/
|
*/
|
||||||
private void checkValidTransform(final FunctionNode functionNode) {
|
private static void checkValidTransform(final FunctionNode functionNode) {
|
||||||
|
|
||||||
final Set<Expression> argumentsFound = new HashSet<>();
|
final Set<Expression> argumentsFound = new HashSet<>();
|
||||||
final Deque<Set<Expression>> stack = new ArrayDeque<>();
|
final Deque<Set<Expression>> stack = new ArrayDeque<>();
|
||||||
|
@ -33,6 +33,8 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -221,11 +223,37 @@ public final class OptimisticTypesPersistence {
|
|||||||
private static void reportError(final String msg, final File file, final Exception e) {
|
private static void reportError(final String msg, final File file, final Exception e) {
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
if(now - lastReportedError > ERROR_REPORT_THRESHOLD) {
|
if(now - lastReportedError > ERROR_REPORT_THRESHOLD) {
|
||||||
getLogger().warning(String.format("Failed to %s %s", msg, file), e);
|
reportError(String.format("Failed to %s %s", msg, file), e);
|
||||||
lastReportedError = now;
|
lastReportedError = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an error message with warning severity (reasoning being that we're reporting an error that'll disable the
|
||||||
|
* type info cache, but it's only logged as a warning because that doesn't prevent Nashorn from running, it just
|
||||||
|
* disables a performance-enhancing cache).
|
||||||
|
* @param msg the message to log
|
||||||
|
* @param e the exception that represents the error.
|
||||||
|
*/
|
||||||
|
private static void reportError(final String msg, final Exception e) {
|
||||||
|
getLogger().warning(msg, "\n", exceptionToString(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper that prints an exception stack trace into a string. We have to do this as if we just pass the exception
|
||||||
|
* to {@link DebugLogger#warning(Object...)}, it will only log the exception message and not the stack, making
|
||||||
|
* problems harder to diagnose.
|
||||||
|
* @param e the exception
|
||||||
|
* @return the string representation of {@link Exception#printStackTrace()} output.
|
||||||
|
*/
|
||||||
|
private static String exceptionToString(final Exception e) {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final PrintWriter pw = new PrintWriter(sw, false);
|
||||||
|
e.printStackTrace(pw);
|
||||||
|
pw.flush();
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private static File createBaseCacheDir() {
|
private static File createBaseCacheDir() {
|
||||||
if(MAX_FILES == 0 || Options.getBooleanProperty("nashorn.typeInfo.disabled")) {
|
if(MAX_FILES == 0 || Options.getBooleanProperty("nashorn.typeInfo.disabled")) {
|
||||||
return null;
|
return null;
|
||||||
@ -233,7 +261,7 @@ public final class OptimisticTypesPersistence {
|
|||||||
try {
|
try {
|
||||||
return createBaseCacheDirPrivileged();
|
return createBaseCacheDirPrivileged();
|
||||||
} catch(final Exception e) {
|
} catch(final Exception e) {
|
||||||
getLogger().warning("Failed to create cache dir", e);
|
reportError("Failed to create cache dir", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,7 +295,7 @@ public final class OptimisticTypesPersistence {
|
|||||||
try {
|
try {
|
||||||
return createCacheDirPrivileged(baseDir);
|
return createCacheDirPrivileged(baseDir);
|
||||||
} catch(final Exception e) {
|
} catch(final Exception e) {
|
||||||
getLogger().warning("Failed to create cache dir", e);
|
reportError("Failed to create cache dir", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,7 +308,7 @@ public final class OptimisticTypesPersistence {
|
|||||||
try {
|
try {
|
||||||
versionDirName = getVersionDirName();
|
versionDirName = getVersionDirName();
|
||||||
} catch(final Exception e) {
|
} catch(final Exception e) {
|
||||||
getLogger().warning("Failed to calculate version dir name", e);
|
reportError("Failed to calculate version dir name", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final File versionDir = new File(baseDir, versionDirName);
|
final File versionDir = new File(baseDir, versionDirName);
|
||||||
@ -328,7 +356,12 @@ public final class OptimisticTypesPersistence {
|
|||||||
* @throws Exception if digest could not be created
|
* @throws Exception if digest could not be created
|
||||||
*/
|
*/
|
||||||
public static String getVersionDirName() throws Exception {
|
public static String getVersionDirName() throws Exception {
|
||||||
final URL url = OptimisticTypesPersistence.class.getResource("");
|
// NOTE: getResource("") won't work if the JAR file doesn't have directory entries (and JAR files in JDK distro
|
||||||
|
// don't, or at least it's a bad idea counting on it). Alternatively, we could've tried
|
||||||
|
// getResource("OptimisticTypesPersistence.class") but behavior of getResource with regard to its willingness
|
||||||
|
// to hand out URLs to .class files is also unspecified. Therefore, the most robust way to obtain an URL to our
|
||||||
|
// package is to have a small non-class anchor file and start out from its URL.
|
||||||
|
final URL url = OptimisticTypesPersistence.class.getResource("anchor.properties");
|
||||||
final String protocol = url.getProtocol();
|
final String protocol = url.getProtocol();
|
||||||
if (protocol.equals("jar")) {
|
if (protocol.equals("jar")) {
|
||||||
// Normal deployment: nashorn.jar
|
// Normal deployment: nashorn.jar
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2014, 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
# This file exists only so OptimisticTypesPersistence.getVersionDirName() can take its URL.
|
@ -264,6 +264,10 @@ public final class BinaryNode extends Expression implements Assignment<Expressio
|
|||||||
case COMMARIGHT: {
|
case COMMARIGHT: {
|
||||||
return rhs.getType(localVariableTypes);
|
return rhs.getType(localVariableTypes);
|
||||||
}
|
}
|
||||||
|
case AND:
|
||||||
|
case OR:{
|
||||||
|
return Type.widestReturnType(lhs.getType(localVariableTypes), rhs.getType(localVariableTypes));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (isComparison()) {
|
if (isComparison()) {
|
||||||
return Type.BOOLEAN;
|
return Type.BOOLEAN;
|
||||||
|
@ -35,7 +35,6 @@ import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArray
|
|||||||
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
|
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.SwitchPoint;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -93,17 +92,6 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
private static final Object CALL_CMP = new Object();
|
private static final Object CALL_CMP = new Object();
|
||||||
private static final Object TO_LOCALE_STRING = new Object();
|
private static final Object TO_LOCALE_STRING = new Object();
|
||||||
|
|
||||||
private SwitchPoint lengthMadeNotWritableSwitchPoint;
|
|
||||||
private PushLinkLogic pushLinkLogic;
|
|
||||||
private PopLinkLogic popLinkLogic;
|
|
||||||
private ConcatLinkLogic concatLinkLogic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Index for the modification SwitchPoint that triggers when length
|
|
||||||
* becomes not writable
|
|
||||||
*/
|
|
||||||
private static final int LENGTH_NOT_WRITABLE_SWITCHPOINT = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructors.
|
* Constructors.
|
||||||
*/
|
*/
|
||||||
@ -271,12 +259,83 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
@Override
|
@Override
|
||||||
public Object getLength() {
|
public Object getLength() {
|
||||||
final long length = JSType.toUint32(getArray().length());
|
final long length = JSType.toUint32(getArray().length());
|
||||||
if(length < Integer.MAX_VALUE) {
|
if (length < Integer.MAX_VALUE) {
|
||||||
return (int)length;
|
return (int)length;
|
||||||
}
|
}
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean defineLength(final long oldLen, final PropertyDescriptor oldLenDesc, final PropertyDescriptor desc, final boolean reject) {
|
||||||
|
// Step 3a
|
||||||
|
if (!desc.has(VALUE)) {
|
||||||
|
return super.defineOwnProperty("length", desc, reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3b
|
||||||
|
final PropertyDescriptor newLenDesc = desc;
|
||||||
|
|
||||||
|
// Step 3c and 3d - get new length and convert to long
|
||||||
|
final long newLen = NativeArray.validLength(newLenDesc.getValue(), true);
|
||||||
|
|
||||||
|
// Step 3e
|
||||||
|
newLenDesc.setValue(newLen);
|
||||||
|
|
||||||
|
// Step 3f
|
||||||
|
// increasing array length - just need to set new length value (and attributes if any) and return
|
||||||
|
if (newLen >= oldLen) {
|
||||||
|
return super.defineOwnProperty("length", newLenDesc, reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3g
|
||||||
|
if (!oldLenDesc.isWritable()) {
|
||||||
|
if (reject) {
|
||||||
|
throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3h and 3i
|
||||||
|
final boolean newWritable = !newLenDesc.has(WRITABLE) || newLenDesc.isWritable();
|
||||||
|
if (!newWritable) {
|
||||||
|
newLenDesc.setWritable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3j and 3k
|
||||||
|
final boolean succeeded = super.defineOwnProperty("length", newLenDesc, reject);
|
||||||
|
if (!succeeded) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3l
|
||||||
|
// make sure that length is set till the point we can delete the old elements
|
||||||
|
long o = oldLen;
|
||||||
|
while (newLen < o) {
|
||||||
|
o--;
|
||||||
|
final boolean deleteSucceeded = delete(o, false);
|
||||||
|
if (!deleteSucceeded) {
|
||||||
|
newLenDesc.setValue(o + 1);
|
||||||
|
if (!newWritable) {
|
||||||
|
newLenDesc.setWritable(false);
|
||||||
|
}
|
||||||
|
super.defineOwnProperty("length", newLenDesc, false);
|
||||||
|
if (reject) {
|
||||||
|
throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3m
|
||||||
|
if (!newWritable) {
|
||||||
|
// make 'length' property not writable
|
||||||
|
final ScriptObject newDesc = Global.newEmptyInstance();
|
||||||
|
newDesc.set(WRITABLE, false, 0);
|
||||||
|
return super.defineOwnProperty("length", newDesc, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ECMA 15.4.5.1 [[DefineOwnProperty]] ( P, Desc, Throw )
|
* ECMA 15.4.5.1 [[DefineOwnProperty]] ( P, Desc, Throw )
|
||||||
*/
|
*/
|
||||||
@ -290,82 +349,16 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
|
|
||||||
// Step 2
|
// Step 2
|
||||||
// get old length and convert to long
|
// get old length and convert to long
|
||||||
long oldLen = NativeArray.validLength(oldLenDesc.getValue(), true);
|
final long oldLen = NativeArray.validLength(oldLenDesc.getValue(), true);
|
||||||
|
|
||||||
// Step 3
|
// Step 3
|
||||||
if ("length".equals(key)) {
|
if ("length".equals(key)) {
|
||||||
// check for length being made non-writable
|
// check for length being made non-writable
|
||||||
|
final boolean result = defineLength(oldLen, oldLenDesc, desc, reject);
|
||||||
if (desc.has(WRITABLE) && !desc.isWritable()) {
|
if (desc.has(WRITABLE) && !desc.isWritable()) {
|
||||||
setIsLengthNotWritable();
|
setIsLengthNotWritable();
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
// Step 3a
|
|
||||||
if (!desc.has(VALUE)) {
|
|
||||||
return super.defineOwnProperty("length", desc, reject);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3b
|
|
||||||
final PropertyDescriptor newLenDesc = desc;
|
|
||||||
|
|
||||||
// Step 3c and 3d - get new length and convert to long
|
|
||||||
final long newLen = NativeArray.validLength(newLenDesc.getValue(), true);
|
|
||||||
|
|
||||||
// Step 3e
|
|
||||||
newLenDesc.setValue(newLen);
|
|
||||||
|
|
||||||
// Step 3f
|
|
||||||
// increasing array length - just need to set new length value (and attributes if any) and return
|
|
||||||
if (newLen >= oldLen) {
|
|
||||||
return super.defineOwnProperty("length", newLenDesc, reject);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3g
|
|
||||||
if (!oldLenDesc.isWritable()) {
|
|
||||||
if (reject) {
|
|
||||||
throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3h and 3i
|
|
||||||
final boolean newWritable = !newLenDesc.has(WRITABLE) || newLenDesc.isWritable();
|
|
||||||
if (!newWritable) {
|
|
||||||
newLenDesc.setWritable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3j and 3k
|
|
||||||
final boolean succeeded = super.defineOwnProperty("length", newLenDesc, reject);
|
|
||||||
if (!succeeded) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3l
|
|
||||||
// make sure that length is set till the point we can delete the old elements
|
|
||||||
while (newLen < oldLen) {
|
|
||||||
oldLen--;
|
|
||||||
final boolean deleteSucceeded = delete(oldLen, false);
|
|
||||||
if (!deleteSucceeded) {
|
|
||||||
newLenDesc.setValue(oldLen + 1);
|
|
||||||
if (!newWritable) {
|
|
||||||
newLenDesc.setWritable(false);
|
|
||||||
}
|
|
||||||
super.defineOwnProperty("length", newLenDesc, false);
|
|
||||||
if (reject) {
|
|
||||||
throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3m
|
|
||||||
if (!newWritable) {
|
|
||||||
// make 'length' property not writable
|
|
||||||
final ScriptObject newDesc = Global.newEmptyInstance();
|
|
||||||
newDesc.set(WRITABLE, false, 0);
|
|
||||||
return super.defineOwnProperty("length", newDesc, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4a
|
// Step 4a
|
||||||
@ -441,23 +434,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
@Override
|
@Override
|
||||||
public void setIsLengthNotWritable() {
|
public void setIsLengthNotWritable() {
|
||||||
super.setIsLengthNotWritable();
|
super.setIsLengthNotWritable();
|
||||||
/*
|
setArray(ArrayData.setIsLengthNotWritable(getArray()));
|
||||||
* Switchpoints are created lazily. If we link any push or pop site,
|
|
||||||
* we need to create the "length made not writable" switchpoint, if it
|
|
||||||
* doesn't exist.
|
|
||||||
*
|
|
||||||
* If the switchpoint already exists, we will find it here, and invalidate
|
|
||||||
* it, invalidating all previous callsites that use it.
|
|
||||||
*
|
|
||||||
* If the switchpoint doesn't exist, no push/pop has been linked so far,
|
|
||||||
* because that would create it too. We invalidate it immediately and the
|
|
||||||
* check link logic for all future callsites will fail immediately at link
|
|
||||||
* time
|
|
||||||
*/
|
|
||||||
if (lengthMadeNotWritableSwitchPoint == null) {
|
|
||||||
lengthMadeNotWritableSwitchPoint = new SwitchPoint();
|
|
||||||
}
|
|
||||||
SwitchPoint.invalidateAll(new SwitchPoint[] { lengthMadeNotWritableSwitchPoint });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -494,7 +471,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
@Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
|
@Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
|
||||||
public static void length(final Object self, final Object length) {
|
public static void length(final Object self, final Object length) {
|
||||||
if (isArray(self)) {
|
if (isArray(self)) {
|
||||||
((ScriptObject) self).setLength(validLength(length, true));
|
((ScriptObject)self).setLength(validLength(length, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1306,10 +1283,13 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
// Get only non-missing elements. Missing elements go at the end
|
// Get only non-missing elements. Missing elements go at the end
|
||||||
// of the sorted array. So, just don't copy these to sort input.
|
// of the sorted array. So, just don't copy these to sort input.
|
||||||
final ArrayList<Object> src = new ArrayList<>();
|
final ArrayList<Object> src = new ArrayList<>();
|
||||||
for (long i = 0; i < len; i = array.nextIndex(i)) {
|
|
||||||
if (array.has((int) i)) {
|
for (final Iterator<Long> iter = array.indexIterator(); iter.hasNext(); ) {
|
||||||
src.add(array.getObject((int) i));
|
final long index = iter.next();
|
||||||
|
if (index >= len) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
src.add(array.getObject((int)index));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Object[] sorted = sort(src.toArray(), comparefn);
|
final Object[] sorted = sort(src.toArray(), comparefn);
|
||||||
@ -1767,11 +1747,11 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
@Override
|
@Override
|
||||||
public SpecializedFunction.LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz) {
|
public SpecializedFunction.LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz) {
|
||||||
if (clazz == PushLinkLogic.class) {
|
if (clazz == PushLinkLogic.class) {
|
||||||
return pushLinkLogic == null ? new PushLinkLogic(this) : pushLinkLogic;
|
return PushLinkLogic.INSTANCE;
|
||||||
} else if (clazz == PopLinkLogic.class) {
|
} else if (clazz == PopLinkLogic.class) {
|
||||||
return popLinkLogic == null ? new PopLinkLogic(this) : pushLinkLogic;
|
return PopLinkLogic.INSTANCE;
|
||||||
} else if (clazz == ConcatLinkLogic.class) {
|
} else if (clazz == ConcatLinkLogic.class) {
|
||||||
return concatLinkLogic == null ? new ConcatLinkLogic(this) : concatLinkLogic;
|
return ConcatLinkLogic.INSTANCE;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1787,21 +1767,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
* modification switchpoint which is touched when length is written.
|
* modification switchpoint which is touched when length is written.
|
||||||
*/
|
*/
|
||||||
private static abstract class ArrayLinkLogic extends SpecializedFunction.LinkLogic {
|
private static abstract class ArrayLinkLogic extends SpecializedFunction.LinkLogic {
|
||||||
private final NativeArray array;
|
protected ArrayLinkLogic() {
|
||||||
|
|
||||||
protected ArrayLinkLogic(final NativeArray array) {
|
|
||||||
this.array = array;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SwitchPoint getSwitchPoint() {
|
|
||||||
return array.lengthMadeNotWritableSwitchPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SwitchPoint newSwitchPoint() {
|
|
||||||
assert array.lengthMadeNotWritableSwitchPoint == null;
|
|
||||||
final SwitchPoint sp = new SwitchPoint();
|
|
||||||
array.lengthMadeNotWritableSwitchPoint = sp;
|
|
||||||
return sp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ContinuousArrayData getContinuousArrayData(final Object self) {
|
protected static ContinuousArrayData getContinuousArrayData(final Object self) {
|
||||||
@ -1822,68 +1788,13 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
public Class<? extends Throwable> getRelinkException() {
|
public Class<? extends Throwable> getRelinkException() {
|
||||||
return ClassCastException.class;
|
return ClassCastException.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasModificationSwitchPoints() {
|
|
||||||
return getSwitchPoint() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasModificationSwitchPoint(final int index) {
|
|
||||||
assert index == LENGTH_NOT_WRITABLE_SWITCHPOINT;
|
|
||||||
return hasModificationSwitchPoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SwitchPoint getOrCreateModificationSwitchPoint(final int index) {
|
|
||||||
assert index == LENGTH_NOT_WRITABLE_SWITCHPOINT;
|
|
||||||
SwitchPoint sp = getSwitchPoint();
|
|
||||||
if (sp == null) {
|
|
||||||
sp = newSwitchPoint();
|
|
||||||
}
|
|
||||||
return sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SwitchPoint[] getOrCreateModificationSwitchPoints() {
|
|
||||||
return new SwitchPoint[] { getOrCreateModificationSwitchPoint(LENGTH_NOT_WRITABLE_SWITCHPOINT) };
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateModificationSwitchPoint(final int index) {
|
|
||||||
assert index == LENGTH_NOT_WRITABLE_SWITCHPOINT;
|
|
||||||
invalidateModificationSwitchPoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateModificationSwitchPoints() {
|
|
||||||
final SwitchPoint sp = getSwitchPoint();
|
|
||||||
assert sp != null : "trying to invalidate non-existant modified SwitchPoint";
|
|
||||||
if (!sp.hasBeenInvalidated()) {
|
|
||||||
SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasInvalidatedModificationSwitchPoint(final int index) {
|
|
||||||
assert index == LENGTH_NOT_WRITABLE_SWITCHPOINT;
|
|
||||||
return hasInvalidatedModificationSwitchPoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasInvalidatedModificationSwitchPoints() {
|
|
||||||
final SwitchPoint sp = getSwitchPoint();
|
|
||||||
return sp != null && !sp.hasBeenInvalidated();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is linker logic for optimistic concatenations
|
* This is linker logic for optimistic concatenations
|
||||||
*/
|
*/
|
||||||
private static final class ConcatLinkLogic extends ArrayLinkLogic {
|
private static final class ConcatLinkLogic extends ArrayLinkLogic {
|
||||||
private ConcatLinkLogic(final NativeArray array) {
|
private static final LinkLogic INSTANCE = new ConcatLinkLogic();
|
||||||
super(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
|
public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
|
||||||
@ -1915,9 +1826,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
* This is linker logic for optimistic pushes
|
* This is linker logic for optimistic pushes
|
||||||
*/
|
*/
|
||||||
private static final class PushLinkLogic extends ArrayLinkLogic {
|
private static final class PushLinkLogic extends ArrayLinkLogic {
|
||||||
private PushLinkLogic(final NativeArray array) {
|
private static final LinkLogic INSTANCE = new PushLinkLogic();
|
||||||
super(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
|
public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
|
||||||
@ -1929,9 +1838,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
* This is linker logic for optimistic pops
|
* This is linker logic for optimistic pops
|
||||||
*/
|
*/
|
||||||
private static final class PopLinkLogic extends ArrayLinkLogic {
|
private static final class PopLinkLogic extends ArrayLinkLogic {
|
||||||
private PopLinkLogic(final NativeArray array) {
|
private static final LinkLogic INSTANCE = new PopLinkLogic();
|
||||||
super(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We need to check if we are dealing with a continuous non empty array data here,
|
* We need to check if we are dealing with a continuous non empty array data here,
|
||||||
|
@ -39,6 +39,7 @@ import jdk.nashorn.internal.runtime.PropertyListeners;
|
|||||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||||
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
import jdk.nashorn.internal.runtime.events.RuntimeEvent;
|
import jdk.nashorn.internal.runtime.events.RuntimeEvent;
|
||||||
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
|
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
|
||||||
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
||||||
@ -65,6 +66,36 @@ public final class NativeDebug extends ScriptObject {
|
|||||||
return "Debug";
|
return "Debug";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the ArrayData class for this ScriptObject
|
||||||
|
* @param self self
|
||||||
|
* @param obj script object to check
|
||||||
|
* @return ArrayData class, or undefined if no ArrayData is present
|
||||||
|
*/
|
||||||
|
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||||
|
public static Object getArrayDataClass(final Object self, final Object obj) {
|
||||||
|
try {
|
||||||
|
return ((ScriptObject)obj).getArray().getClass();
|
||||||
|
} catch (final ClassCastException e) {
|
||||||
|
return ScriptRuntime.UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the ArrayData for this ScriptObject
|
||||||
|
* @param self self
|
||||||
|
* @param obj script object to check
|
||||||
|
* @return ArrayData, ArrayDatas have toString methods, return Undefined if data missing
|
||||||
|
*/
|
||||||
|
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||||
|
public static Object getArrayData(final Object self, final Object obj) {
|
||||||
|
try {
|
||||||
|
return ((ScriptObject)obj).getArray();
|
||||||
|
} catch (final ClassCastException e) {
|
||||||
|
return ScriptRuntime.UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nashorn extension: get context, context utility
|
* Nashorn extension: get context, context utility
|
||||||
*
|
*
|
||||||
|
@ -30,7 +30,6 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.SwitchPoint;
|
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
import jdk.internal.dynalink.linker.LinkRequest;
|
import jdk.internal.dynalink.linker.LinkRequest;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
@ -62,10 +61,6 @@ public @interface SpecializedFunction {
|
|||||||
*/
|
*/
|
||||||
public static final LinkLogic EMPTY_INSTANCE = new Empty();
|
public static final LinkLogic EMPTY_INSTANCE = new Empty();
|
||||||
|
|
||||||
private static final SwitchPoint[] INVALIDATED_SWITCHPOINTS = new SwitchPoint[0];
|
|
||||||
|
|
||||||
private SwitchPoint[] modificationSwitchPoints; //cache
|
|
||||||
|
|
||||||
/** Empty link logic class - allow all linking, no guards */
|
/** Empty link logic class - allow all linking, no guards */
|
||||||
private static final class Empty extends LinkLogic {
|
private static final class Empty extends LinkLogic {
|
||||||
@Override
|
@Override
|
||||||
@ -166,92 +161,6 @@ public @interface SpecializedFunction {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the modification SwitchPoint of a particular index from this OptimisticBuiltins
|
|
||||||
* If none exists, one is created and that one is return.
|
|
||||||
*
|
|
||||||
* The implementor must map indexes to specific SwitchPoints for specific events and keep
|
|
||||||
* track of what they mean, for example NativeArray.LENGTH_NOT_WRITABLE_SWITCHPOINT
|
|
||||||
* might be a useful index mapping
|
|
||||||
*
|
|
||||||
* @param index index for SwitchPoint to get or create
|
|
||||||
* @return modification SwitchPoint of particular index for the receiver
|
|
||||||
*/
|
|
||||||
public SwitchPoint getOrCreateModificationSwitchPoint(final int index) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the modification SwitchPoint from this OptimisticBuiltins. If none
|
|
||||||
* exists, one is created and that one is return.
|
|
||||||
*
|
|
||||||
* @return modification SwitchPoint for the receiver
|
|
||||||
*/
|
|
||||||
public SwitchPoint[] getOrCreateModificationSwitchPoints() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook to invalidate a modification SwitchPoint by index.
|
|
||||||
*
|
|
||||||
* @param index index for SwitchPoint to invalidate
|
|
||||||
*/
|
|
||||||
public void invalidateModificationSwitchPoint(final int index) {
|
|
||||||
//empty
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook to invalidate all modification SwitchPoints for a receiver
|
|
||||||
*/
|
|
||||||
public void invalidateModificationSwitchPoints() {
|
|
||||||
//empty
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether the receiver has an invalidated modification SwitchPoint.
|
|
||||||
*
|
|
||||||
* @param index index for the modification SwitchPoint
|
|
||||||
* @return true if the particular SwitchPoint at the index is invalidated
|
|
||||||
*/
|
|
||||||
public boolean hasInvalidatedModificationSwitchPoint(final int index) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether at least one of the modification SwitchPoints has been
|
|
||||||
* invalidated
|
|
||||||
* @return true if one of the SwitchPoints has been invalidated
|
|
||||||
*/
|
|
||||||
public boolean hasInvalidatedModificationSwitchPoints() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether this OptimisticBuiltins has a SwitchPoints of particular
|
|
||||||
* index.
|
|
||||||
*
|
|
||||||
* As creation overhead for a SwitchPoint is non-zero, we have to create them lazily instead of,
|
|
||||||
* e.g. in the constructor of every subclass.
|
|
||||||
*
|
|
||||||
* @param index index for the modification SwitchPoint
|
|
||||||
* @return true if a modification SwitchPoint exists, no matter if it has been invalidated or not
|
|
||||||
*/
|
|
||||||
public boolean hasModificationSwitchPoint(final int index) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether this OptimisticBuiltins has SwitchPoints.
|
|
||||||
*
|
|
||||||
* As creation overhead for a SwitchPoint is non-zero, we have to create them lazily instead of,
|
|
||||||
* e.g. in the constructor of every subclass.
|
|
||||||
*
|
|
||||||
* @return true if a modification SwitchPoint exists, no matter if it has been invalidated or not
|
|
||||||
*/
|
|
||||||
public boolean hasModificationSwitchPoints() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check, given a link request and a receiver, if this specialization
|
* Check, given a link request and a receiver, if this specialization
|
||||||
* fits This is used by the linker in {@link ScriptFunction} to figure
|
* fits This is used by the linker in {@link ScriptFunction} to figure
|
||||||
@ -265,47 +174,9 @@ public @interface SpecializedFunction {
|
|||||||
* pick a non specialized target
|
* pick a non specialized target
|
||||||
*/
|
*/
|
||||||
public boolean checkLinkable(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
|
public boolean checkLinkable(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
|
||||||
// no matter what the modification switchpoints are, if any of them are invalidated,
|
|
||||||
// we can't link. Side effect is that if it's the first time we see this callsite,
|
|
||||||
// we have to create the SwitchPoint(s) so future modification switchpoint invalidations
|
|
||||||
// relink it
|
|
||||||
final SwitchPoint[] sps = getOrCreateModificationSwitchPoints(self);
|
|
||||||
if (sps == INVALIDATED_SWITCHPOINTS) {
|
|
||||||
// nope, can't do the fast link as this assumption
|
|
||||||
// has been invalidated already, e.g. length of an
|
|
||||||
// array set to not writable
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
modificationSwitchPoints = sps; //cache
|
|
||||||
|
|
||||||
// check the link guard, if it says we can link, go ahead
|
// check the link guard, if it says we can link, go ahead
|
||||||
return canLink(self, desc, request);
|
return canLink(self, desc, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwitchPoint[] getOrCreateModificationSwitchPoints(final Object self) {
|
|
||||||
final SwitchPoint[] sps = getOrCreateModificationSwitchPoints(); //ask for all my switchpoints
|
|
||||||
if (sps != null) { //switchpoint exists, but some may be invalidated
|
|
||||||
for (final SwitchPoint sp : sps) {
|
|
||||||
if (sp.hasBeenInvalidated()) {
|
|
||||||
return INVALIDATED_SWITCHPOINTS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sps;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the cached modification switchpoints. Only possible to do after a link
|
|
||||||
* check call has been performed, one that has answered "true", or you will get the
|
|
||||||
* wrong information.
|
|
||||||
*
|
|
||||||
* Should be used only from {@link ScriptFunction#findCallMethod}
|
|
||||||
*
|
|
||||||
* @return cached modification switchpoints for this callsite, null if none
|
|
||||||
*/
|
|
||||||
public SwitchPoint[] getModificationSwitchPoints() {
|
|
||||||
return modificationSwitchPoints == null ? null : modificationSwitchPoints.clone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,10 +82,9 @@ public abstract class CodeStore implements Loggable {
|
|||||||
* Returns a new code store instance.
|
* Returns a new code store instance.
|
||||||
*
|
*
|
||||||
* @param context the current context
|
* @param context the current context
|
||||||
* @return The instance
|
* @return The instance, or null if code store could not be created
|
||||||
* @throws IOException If an error occurs
|
|
||||||
*/
|
*/
|
||||||
public static CodeStore newCodeStore(final Context context) throws IOException {
|
public static CodeStore newCodeStore(final Context context) {
|
||||||
final Class<CodeStore> baseClass = CodeStore.class;
|
final Class<CodeStore> baseClass = CodeStore.class;
|
||||||
try {
|
try {
|
||||||
// security check first
|
// security check first
|
||||||
@ -103,9 +102,14 @@ public abstract class CodeStore implements Loggable {
|
|||||||
} catch (final AccessControlException e) {
|
} catch (final AccessControlException e) {
|
||||||
context.getLogger(CodeStore.class).warning("failed to load code store provider ", e);
|
context.getLogger(CodeStore.class).warning("failed to load code store provider ", e);
|
||||||
}
|
}
|
||||||
final CodeStore store = new DirectoryCodeStore(context);
|
try {
|
||||||
store.initLogger(context);
|
final CodeStore store = new DirectoryCodeStore(context);
|
||||||
return store;
|
store.initLogger(context);
|
||||||
|
return store;
|
||||||
|
} catch (final IOException e) {
|
||||||
|
context.getLogger(CodeStore.class).warning("failed to create cache directory ", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,9 +33,11 @@ import java.lang.invoke.MethodHandles;
|
|||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.invoke.MutableCallSite;
|
import java.lang.invoke.MutableCallSite;
|
||||||
import java.lang.invoke.SwitchPoint;
|
import java.lang.invoke.SwitchPoint;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@ -726,34 +728,58 @@ final class CompiledFunction {
|
|||||||
* @param ipp
|
* @param ipp
|
||||||
* @return string describing the ipp map
|
* @return string describing the ipp map
|
||||||
*/
|
*/
|
||||||
private static String toStringInvalidations(final Map<Integer, Type> ipp) {
|
private static List<String> toStringInvalidations(final Map<Integer, Type> ipp) {
|
||||||
if (ipp == null) {
|
if (ipp == null) {
|
||||||
return "";
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
final List<String> list = new ArrayList<>();
|
||||||
|
|
||||||
for (final Iterator<Map.Entry<Integer, Type>> iter = ipp.entrySet().iterator(); iter.hasNext(); ) {
|
for (final Iterator<Map.Entry<Integer, Type>> iter = ipp.entrySet().iterator(); iter.hasNext(); ) {
|
||||||
final Map.Entry<Integer, Type> entry = iter.next();
|
final Map.Entry<Integer, Type> entry = iter.next();
|
||||||
final char bct = entry.getValue().getBytecodeStackType();
|
final char bct = entry.getValue().getBytecodeStackType();
|
||||||
|
final String type;
|
||||||
|
|
||||||
|
switch (entry.getValue().getBytecodeStackType()) {
|
||||||
|
case 'A':
|
||||||
|
type = "object";
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
type = "int";
|
||||||
|
break;
|
||||||
|
case 'J':
|
||||||
|
type = "long";
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
type = "double";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = String.valueOf(bct);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append('[').
|
sb.append('[').
|
||||||
|
append("program point: ").
|
||||||
append(entry.getKey()).
|
append(entry.getKey()).
|
||||||
append("->").
|
append(" -> ").
|
||||||
append(bct == 'A' ? 'O' : bct).
|
append(type).
|
||||||
append(']');
|
append(']');
|
||||||
|
|
||||||
if (iter.hasNext()) {
|
list.add(sb.toString());
|
||||||
sb.append(' ');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logRecompile(final String reason, final FunctionNode fn, final MethodType type, final Map<Integer, Type> ipp) {
|
private void logRecompile(final String reason, final FunctionNode fn, final MethodType type, final Map<Integer, Type> ipp) {
|
||||||
if (log.isEnabled()) {
|
if (log.isEnabled()) {
|
||||||
log.info(reason, DebugLogger.quote(fn.getName()), " signature: ", type, " ", toStringInvalidations(ipp));
|
log.info(reason, DebugLogger.quote(fn.getName()), " signature: ", type);
|
||||||
|
log.indent();
|
||||||
|
for (final String str : toStringInvalidations(ipp)) {
|
||||||
|
log.fine(str);
|
||||||
|
}
|
||||||
|
log.unindent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,7 +795,14 @@ final class CompiledFunction {
|
|||||||
*/
|
*/
|
||||||
private synchronized MethodHandle handleRewriteException(final OptimismInfo oldOptInfo, final RewriteException re) {
|
private synchronized MethodHandle handleRewriteException(final OptimismInfo oldOptInfo, final RewriteException re) {
|
||||||
if (log.isEnabled()) {
|
if (log.isEnabled()) {
|
||||||
log.info(new RecompilationEvent(Level.INFO, re, re.getReturnValueNonDestructive()), "RewriteException ", re.getMessageShort());
|
log.info(
|
||||||
|
new RecompilationEvent(
|
||||||
|
Level.INFO,
|
||||||
|
re,
|
||||||
|
re.getReturnValueNonDestructive()),
|
||||||
|
"caught RewriteException ",
|
||||||
|
re.getMessageShort());
|
||||||
|
log.indent();
|
||||||
}
|
}
|
||||||
|
|
||||||
final MethodType type = type();
|
final MethodType type = type();
|
||||||
@ -799,7 +832,7 @@ final class CompiledFunction {
|
|||||||
|
|
||||||
logRecompile("Deoptimizing recompilation (up to bytecode) ", fn, ct, effectiveOptInfo.invalidatedProgramPoints);
|
logRecompile("Deoptimizing recompilation (up to bytecode) ", fn, ct, effectiveOptInfo.invalidatedProgramPoints);
|
||||||
fn = compiler.compile(fn, serialized ? CompilationPhases.RECOMPILE_SERIALIZED_UPTO_BYTECODE : CompilationPhases.COMPILE_UPTO_BYTECODE);
|
fn = compiler.compile(fn, serialized ? CompilationPhases.RECOMPILE_SERIALIZED_UPTO_BYTECODE : CompilationPhases.COMPILE_UPTO_BYTECODE);
|
||||||
log.info("Reusable IR generated");
|
log.fine("Reusable IR generated");
|
||||||
|
|
||||||
// compile the rest of the function, and install it
|
// compile the rest of the function, and install it
|
||||||
log.info("Generating and installing bytecode from reusable IR...");
|
log.info("Generating and installing bytecode from reusable IR...");
|
||||||
@ -815,15 +848,15 @@ final class CompiledFunction {
|
|||||||
compiler.persistClassInfo(cacheKey, normalFn);
|
compiler.persistClassInfo(cacheKey, normalFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Done.");
|
|
||||||
|
|
||||||
final boolean canBeDeoptimized = normalFn.canBeDeoptimized();
|
final boolean canBeDeoptimized = normalFn.canBeDeoptimized();
|
||||||
|
|
||||||
if (log.isEnabled()) {
|
if (log.isEnabled()) {
|
||||||
log.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ") ", canBeDeoptimized ? " can still be deoptimized." : " is completely deoptimized.");
|
log.unindent();
|
||||||
}
|
log.info("Done.");
|
||||||
|
|
||||||
log.info("Looking up invoker...");
|
log.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ") ", canBeDeoptimized ? "can still be deoptimized." : " is completely deoptimized.");
|
||||||
|
log.finest("Looking up invoker...");
|
||||||
|
}
|
||||||
|
|
||||||
final MethodHandle newInvoker = effectiveOptInfo.data.lookup(fn);
|
final MethodHandle newInvoker = effectiveOptInfo.data.lookup(fn);
|
||||||
invoker = newInvoker.asType(type.changeReturnType(newInvoker.type().returnType()));
|
invoker = newInvoker.asType(type.changeReturnType(newInvoker.type().returnType()));
|
||||||
@ -870,7 +903,6 @@ final class CompiledFunction {
|
|||||||
private SwitchPoint optimisticAssumptions;
|
private SwitchPoint optimisticAssumptions;
|
||||||
private final DebugLogger log;
|
private final DebugLogger log;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
OptimismInfo(final RecompilableScriptFunctionData data, final Map<Integer, Type> invalidatedProgramPoints) {
|
OptimismInfo(final RecompilableScriptFunctionData data, final Map<Integer, Type> invalidatedProgramPoints) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.log = data.getLogger();
|
this.log = data.getLogger();
|
||||||
|
@ -509,11 +509,7 @@ public final class Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (env._persistent_cache) {
|
if (env._persistent_cache) {
|
||||||
try {
|
codeStore = newCodeStore(this);
|
||||||
codeStore = newCodeStore(this);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException("Error initializing code cache", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// print version info if asked.
|
// print version info if asked.
|
||||||
@ -1200,7 +1196,7 @@ public final class Context {
|
|||||||
FunctionNode functionNode = null;
|
FunctionNode functionNode = null;
|
||||||
// We only use the code store here if optimistic types are disabled. With optimistic types, initial compilation
|
// We only use the code store here if optimistic types are disabled. With optimistic types, initial compilation
|
||||||
// just creates a thin wrapper, and actual code is stored per function in RecompilableScriptFunctionData.
|
// just creates a thin wrapper, and actual code is stored per function in RecompilableScriptFunctionData.
|
||||||
final boolean useCodeStore = env._persistent_cache && !env._parse_only && !env._optimistic_types;
|
final boolean useCodeStore = codeStore != null && !env._parse_only && !env._optimistic_types;
|
||||||
final String cacheKey = useCodeStore ? CodeStore.getCacheKey(0, null) : null;
|
final String cacheKey = useCodeStore ? CodeStore.getCacheKey(0, null) : null;
|
||||||
|
|
||||||
if (useCodeStore) {
|
if (useCodeStore) {
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
package jdk.nashorn.internal.runtime;
|
package jdk.nashorn.internal.runtime;
|
||||||
|
|
||||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
@ -620,20 +619,25 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodHandle lookup(final FunctionInitializer fnInit) {
|
private void logLookup(final boolean shouldLog, final MethodType targetType) {
|
||||||
|
if (shouldLog && log.isEnabled()) {
|
||||||
|
log.info("Looking up ", DebugLogger.quote(functionName), " type=", targetType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MethodHandle lookup(final FunctionInitializer fnInit, final boolean shouldLog) {
|
||||||
final MethodType type = fnInit.getMethodType();
|
final MethodType type = fnInit.getMethodType();
|
||||||
|
logLookup(shouldLog, type);
|
||||||
return lookupCodeMethod(fnInit.getCode(), type);
|
return lookupCodeMethod(fnInit.getCode(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodHandle lookup(final FunctionNode fn) {
|
MethodHandle lookup(final FunctionNode fn) {
|
||||||
final MethodType type = new FunctionSignature(fn).getMethodType();
|
final MethodType type = new FunctionSignature(fn).getMethodType();
|
||||||
|
logLookup(true, type);
|
||||||
return lookupCodeMethod(fn.getCompileUnit().getCode(), type);
|
return lookupCodeMethod(fn.getCompileUnit().getCode(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodHandle lookupCodeMethod(final Class<?> codeClass, final MethodType targetType) {
|
MethodHandle lookupCodeMethod(final Class<?> codeClass, final MethodType targetType) {
|
||||||
if (log.isEnabled()) {
|
|
||||||
log.info("Looking up ", DebugLogger.quote(functionName), " type=", targetType);
|
|
||||||
}
|
|
||||||
return MH.findStatic(LOOKUP, codeClass, functionName, targetType);
|
return MH.findStatic(LOOKUP, codeClass, functionName, targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,7 +653,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||||||
if(!code.isEmpty()) {
|
if(!code.isEmpty()) {
|
||||||
throw new IllegalStateException(name);
|
throw new IllegalStateException(name);
|
||||||
}
|
}
|
||||||
addCode(lookup(initializer), null, null, initializer.getFlags());
|
addCode(lookup(initializer, true), null, null, initializer.getFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompiledFunction addCode(final MethodHandle target, final Map<Integer, Type> invalidatedProgramPoints,
|
private CompiledFunction addCode(final MethodHandle target, final Map<Integer, Type> invalidatedProgramPoints,
|
||||||
@ -671,10 +675,10 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||||||
*/
|
*/
|
||||||
private CompiledFunction addCode(final FunctionInitializer fnInit, final MethodType callSiteType) {
|
private CompiledFunction addCode(final FunctionInitializer fnInit, final MethodType callSiteType) {
|
||||||
if (isVariableArity()) {
|
if (isVariableArity()) {
|
||||||
return addCode(lookup(fnInit), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags());
|
return addCode(lookup(fnInit, true), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
final MethodHandle handle = lookup(fnInit);
|
final MethodHandle handle = lookup(fnInit, true);
|
||||||
final MethodType fromType = handle.type();
|
final MethodType fromType = handle.type();
|
||||||
MethodType toType = needsCallee(fromType) ? callSiteType.changeParameterType(0, ScriptFunction.class) : callSiteType.dropParameterTypes(0, 1);
|
MethodType toType = needsCallee(fromType) ? callSiteType.changeParameterType(0, ScriptFunction.class) : callSiteType.dropParameterTypes(0, 1);
|
||||||
toType = toType.changeReturnType(fromType.returnType());
|
toType = toType.changeReturnType(fromType.returnType());
|
||||||
@ -699,7 +703,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
|
|||||||
toType = toType.dropParameterTypes(fromCount, toCount);
|
toType = toType.dropParameterTypes(fromCount, toCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return addCode(lookup(fnInit).asType(toType), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags());
|
return addCode(lookup(fnInit, false).asType(toType), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -603,16 +603,6 @@ public abstract class ScriptFunction extends ScriptObject {
|
|||||||
log.info("Linking optimistic builtin function: '", name, "' args=", Arrays.toString(request.getArguments()), " desc=", desc);
|
log.info("Linking optimistic builtin function: '", name, "' args=", Arrays.toString(request.getArguments()), " desc=", desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
final SwitchPoint[] msps = linkLogic.getModificationSwitchPoints();
|
|
||||||
if (msps != null) {
|
|
||||||
for (final SwitchPoint sp : msps) {
|
|
||||||
if (sp != null) {
|
|
||||||
assert !sp.hasBeenInvalidated();
|
|
||||||
sps.add(sp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exceptionGuard = linkLogic.getRelinkException();
|
exceptionGuard = linkLogic.getRelinkException();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -510,6 +510,13 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void invalidateGlobalConstant(final String key) {
|
||||||
|
final GlobalConstants globalConstants = getGlobalConstants();
|
||||||
|
if (globalConstants != null) {
|
||||||
|
globalConstants.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ECMA 8.12.9 [[DefineOwnProperty]] (P, Desc, Throw)
|
* ECMA 8.12.9 [[DefineOwnProperty]] (P, Desc, Throw)
|
||||||
*
|
*
|
||||||
@ -525,6 +532,8 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final Object current = getOwnPropertyDescriptor(key);
|
final Object current = getOwnPropertyDescriptor(key);
|
||||||
final String name = JSType.toString(key);
|
final String name = JSType.toString(key);
|
||||||
|
|
||||||
|
invalidateGlobalConstant(key);
|
||||||
|
|
||||||
if (current == UNDEFINED) {
|
if (current == UNDEFINED) {
|
||||||
if (isExtensible()) {
|
if (isExtensible()) {
|
||||||
// add a new own property
|
// add a new own property
|
||||||
@ -923,10 +932,8 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
if (property instanceof UserAccessorProperty) {
|
if (property instanceof UserAccessorProperty) {
|
||||||
((UserAccessorProperty)property).setAccessors(this, getMap(), null);
|
((UserAccessorProperty)property).setAccessors(this, getMap(), null);
|
||||||
}
|
}
|
||||||
final GlobalConstants globalConstants = getGlobalConstants();
|
|
||||||
if (globalConstants != null) {
|
invalidateGlobalConstant(property.getKey());
|
||||||
globalConstants.delete(property.getKey());
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1352,12 +1359,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final PropertyMap selfMap = this.getMap();
|
final PropertyMap selfMap = this.getMap();
|
||||||
|
|
||||||
final ArrayData array = getArray();
|
final ArrayData array = getArray();
|
||||||
final long length = array.length();
|
|
||||||
|
|
||||||
for (long i = 0; i < length; i = array.nextIndex(i)) {
|
for (final Iterator<Long> iter = array.indexIterator(); iter.hasNext(); ) {
|
||||||
if (array.has((int)i)) {
|
keys.add(JSType.toString(iter.next().longValue()));
|
||||||
keys.add(JSType.toString(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Property property : selfMap.getProperties()) {
|
for (final Property property : selfMap.getProperties()) {
|
||||||
@ -1516,12 +1520,12 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
*
|
*
|
||||||
* @return {@code true} if 'length' property is non-writable
|
* @return {@code true} if 'length' property is non-writable
|
||||||
*/
|
*/
|
||||||
public final boolean isLengthNotWritable() {
|
public boolean isLengthNotWritable() {
|
||||||
return (flags & IS_LENGTH_NOT_WRITABLE) != 0;
|
return (flags & IS_LENGTH_NOT_WRITABLE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag this object as having non-writable length property
|
* Flag this object as having non-writable length property.
|
||||||
*/
|
*/
|
||||||
public void setIsLengthNotWritable() {
|
public void setIsLengthNotWritable() {
|
||||||
flags |= IS_LENGTH_NOT_WRITABLE;
|
flags |= IS_LENGTH_NOT_WRITABLE;
|
||||||
@ -3152,6 +3156,8 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
public final void setObject(final FindProperty find, final int callSiteFlags, final String key, final Object value) {
|
public final void setObject(final FindProperty find, final int callSiteFlags, final String key, final Object value) {
|
||||||
FindProperty f = find;
|
FindProperty f = find;
|
||||||
|
|
||||||
|
invalidateGlobalConstant(key);
|
||||||
|
|
||||||
if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) {
|
if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) {
|
||||||
final boolean isScope = NashornCallSiteDescriptor.isScopeFlag(callSiteFlags);
|
final boolean isScope = NashornCallSiteDescriptor.isScopeFlag(callSiteFlags);
|
||||||
// If the start object of the find is not this object it means the property was found inside a
|
// If the start object of the find is not this object it means the property was found inside a
|
||||||
@ -3177,7 +3183,6 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) {
|
if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) {
|
||||||
throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this));
|
throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3588,7 +3593,6 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return deleteObject(JSType.toObject(key), strict);
|
return deleteObject(JSType.toObject(key), strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@ import java.lang.invoke.MethodHandle;
|
|||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
import jdk.internal.dynalink.linker.LinkRequest;
|
import jdk.internal.dynalink.linker.LinkRequest;
|
||||||
@ -55,6 +58,21 @@ public abstract class ArrayData {
|
|||||||
* a proper ArrayData when we try to write to it */
|
* a proper ArrayData when we try to write to it */
|
||||||
public static final ArrayData EMPTY_ARRAY = new UntouchedArrayData();
|
public static final ArrayData EMPTY_ARRAY = new UntouchedArrayData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of the array data. Not necessarily length of the wrapped array.
|
||||||
|
* This is private to ensure that no one in a subclass is able to touch the length
|
||||||
|
* without going through {@link setLength}. This is used to implement
|
||||||
|
* {@link LengthNotWritableFilter}s, ensuring that there are no ways past
|
||||||
|
* a {@link setLength} function replaced by a nop
|
||||||
|
*/
|
||||||
|
private long length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method handle to throw an {@link UnwarrantedOptimismException} when getting an element
|
||||||
|
* of the wrong type
|
||||||
|
*/
|
||||||
|
protected static final CompilerConstants.Call THROW_UNWARRANTED = staticCall(MethodHandles.lookup(), ArrayData.class, "throwUnwarranted", void.class, ArrayData.class, int.class, int.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable empty array to get ScriptObjects started.
|
* Immutable empty array to get ScriptObjects started.
|
||||||
* Use the same array and convert it to mutable as soon as it is modified
|
* Use the same array and convert it to mutable as soon as it is modified
|
||||||
@ -82,7 +100,7 @@ public abstract class ArrayData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContinuousArrayData copy() {
|
public ContinuousArrayData copy() {
|
||||||
return new UntouchedArrayData((int)length);
|
return new UntouchedArrayData((int)length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -112,6 +130,16 @@ public abstract class ArrayData {
|
|||||||
return toRealArrayData(0).convert(type);
|
return toRealArrayData(0).convert(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData delete(final int index) {
|
||||||
|
return new DeletedRangeArrayFilter(this, index, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData delete(final long fromIndex, final long toIndex) {
|
||||||
|
return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shiftLeft(final int by) {
|
public void shiftLeft(final int by) {
|
||||||
//nop, always empty or we wouldn't be of this class
|
//nop, always empty or we wouldn't be of this class
|
||||||
@ -172,16 +200,6 @@ public abstract class ArrayData {
|
|||||||
return false; //empty
|
return false; //empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData delete(final int index) {
|
|
||||||
return new DeletedRangeArrayFilter(this, index, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData delete(final long fromIndex, final long toIndex) {
|
|
||||||
return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
return ScriptRuntime.UNDEFINED;
|
return ScriptRuntime.UNDEFINED;
|
||||||
@ -230,17 +248,6 @@ public abstract class ArrayData {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Length of the array data. Not necessarily length of the wrapped array.
|
|
||||||
*/
|
|
||||||
protected long length;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method handle to throw an {@link UnwarrantedOptimismException} when getting an element
|
|
||||||
* of the wrong type
|
|
||||||
*/
|
|
||||||
protected static final CompilerConstants.Call THROW_UNWARRANTED = staticCall(MethodHandles.lookup(), ArrayData.class, "throwUnwarranted", void.class, ArrayData.class, int.class, int.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param length Virtual length of the array.
|
* @param length Virtual length of the array.
|
||||||
@ -393,6 +400,16 @@ public abstract class ArrayData {
|
|||||||
return new NonExtensibleArrayFilter(underlying);
|
return new NonExtensibleArrayFilter(underlying);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent this array from having its length reset
|
||||||
|
*
|
||||||
|
* @param underlying the underlying ArrayDAta to wrap in the non extensible filter
|
||||||
|
* @return new array data, filtered
|
||||||
|
*/
|
||||||
|
public static final ArrayData setIsLengthNotWritable(final ArrayData underlying) {
|
||||||
|
return new LengthNotWritableFilter(underlying);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the length of the array data. This may differ from the actual
|
* Return the length of the array data. This may differ from the actual
|
||||||
* length of the array this wraps as length may be set or gotten as any
|
* length of the array this wraps as length may be set or gotten as any
|
||||||
@ -445,6 +462,22 @@ public abstract class ArrayData {
|
|||||||
this.length = length;
|
this.length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase length by 1
|
||||||
|
* @return the new length, not the old one (i.e. pre-increment)
|
||||||
|
*/
|
||||||
|
protected final long increaseLength() {
|
||||||
|
return ++this.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrease length by 1.
|
||||||
|
* @return the new length, not the old one (i.e. pre-decrement)
|
||||||
|
*/
|
||||||
|
protected final long decreaseLength() {
|
||||||
|
return --this.length;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shift the array data left
|
* Shift the array data left
|
||||||
*
|
*
|
||||||
@ -454,7 +487,7 @@ public abstract class ArrayData {
|
|||||||
*
|
*
|
||||||
* @param by offset to shift
|
* @param by offset to shift
|
||||||
*/
|
*/
|
||||||
public abstract void shiftLeft(int by);
|
public abstract void shiftLeft(final int by);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shift the array right
|
* Shift the array right
|
||||||
@ -463,7 +496,7 @@ public abstract class ArrayData {
|
|||||||
|
|
||||||
* @return New arraydata (or same)
|
* @return New arraydata (or same)
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData shiftRight(int by);
|
public abstract ArrayData shiftRight(final int by);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that the given index exists and won't fail subsequent
|
* Ensure that the given index exists and won't fail subsequent
|
||||||
@ -471,7 +504,7 @@ public abstract class ArrayData {
|
|||||||
* @param safeIndex the index to ensure wont go out of bounds
|
* @param safeIndex the index to ensure wont go out of bounds
|
||||||
* @return new array data (or same)
|
* @return new array data (or same)
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData ensure(long safeIndex);
|
public abstract ArrayData ensure(final long safeIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shrink the array to a new length, may or may not retain the
|
* Shrink the array to a new length, may or may not retain the
|
||||||
@ -481,7 +514,7 @@ public abstract class ArrayData {
|
|||||||
*
|
*
|
||||||
* @return new array data (or same)
|
* @return new array data (or same)
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData shrink(long newLength);
|
public abstract ArrayData shrink(final long newLength);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an object value at a given index
|
* Set an object value at a given index
|
||||||
@ -491,7 +524,7 @@ public abstract class ArrayData {
|
|||||||
* @param strict are we in strict mode
|
* @param strict are we in strict mode
|
||||||
* @return new array data (or same)
|
* @return new array data (or same)
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData set(int index, Object value, boolean strict);
|
public abstract ArrayData set(final int index, final Object value, final boolean strict);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an int value at a given index
|
* Set an int value at a given index
|
||||||
@ -501,7 +534,7 @@ public abstract class ArrayData {
|
|||||||
* @param strict are we in strict mode
|
* @param strict are we in strict mode
|
||||||
* @return new array data (or same)
|
* @return new array data (or same)
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData set(int index, int value, boolean strict);
|
public abstract ArrayData set(final int index, final int value, final boolean strict);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a long value at a given index
|
* Set a long value at a given index
|
||||||
@ -511,7 +544,7 @@ public abstract class ArrayData {
|
|||||||
* @param strict are we in strict mode
|
* @param strict are we in strict mode
|
||||||
* @return new array data (or same)
|
* @return new array data (or same)
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData set(int index, long value, boolean strict);
|
public abstract ArrayData set(final int index, final long value, final boolean strict);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an double value at a given index
|
* Set an double value at a given index
|
||||||
@ -521,7 +554,7 @@ public abstract class ArrayData {
|
|||||||
* @param strict are we in strict mode
|
* @param strict are we in strict mode
|
||||||
* @return new array data (or same)
|
* @return new array data (or same)
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData set(int index, double value, boolean strict);
|
public abstract ArrayData set(final int index, final double value, final boolean strict);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an empty value at a given index. Should only affect Object array.
|
* Set an empty value at a given index. Should only affect Object array.
|
||||||
@ -552,7 +585,7 @@ public abstract class ArrayData {
|
|||||||
* @param index the index
|
* @param index the index
|
||||||
* @return the value
|
* @return the value
|
||||||
*/
|
*/
|
||||||
public abstract int getInt(int index);
|
public abstract int getInt(final int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the optimistic type of this array data. Basically, when an array data object needs to throw an
|
* Returns the optimistic type of this array data. Basically, when an array data object needs to throw an
|
||||||
@ -581,7 +614,7 @@ public abstract class ArrayData {
|
|||||||
* @param index the index
|
* @param index the index
|
||||||
* @return the value
|
* @return the value
|
||||||
*/
|
*/
|
||||||
public abstract long getLong(int index);
|
public abstract long getLong(final int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get optimistic long - default is that it's impossible. Overridden
|
* Get optimistic long - default is that it's impossible. Overridden
|
||||||
@ -601,7 +634,7 @@ public abstract class ArrayData {
|
|||||||
* @param index the index
|
* @param index the index
|
||||||
* @return the value
|
* @return the value
|
||||||
*/
|
*/
|
||||||
public abstract double getDouble(int index);
|
public abstract double getDouble(final int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get optimistic double - default is that it's impossible. Overridden
|
* Get optimistic double - default is that it's impossible. Overridden
|
||||||
@ -621,14 +654,14 @@ public abstract class ArrayData {
|
|||||||
* @param index the index
|
* @param index the index
|
||||||
* @return the value
|
* @return the value
|
||||||
*/
|
*/
|
||||||
public abstract Object getObject(int index);
|
public abstract Object getObject(final int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests to see if an entry exists (avoids boxing.)
|
* Tests to see if an entry exists (avoids boxing.)
|
||||||
* @param index the index
|
* @param index the index
|
||||||
* @return true if entry exists
|
* @return true if entry exists
|
||||||
*/
|
*/
|
||||||
public abstract boolean has(int index);
|
public abstract boolean has(final int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if element at specific index can be deleted or not.
|
* Returns if element at specific index can be deleted or not.
|
||||||
@ -674,7 +707,7 @@ public abstract class ArrayData {
|
|||||||
* @param index the index
|
* @param index the index
|
||||||
* @return new array data (or same)
|
* @return new array data (or same)
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData delete(int index);
|
public abstract ArrayData delete(final int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a given range from this array;
|
* Delete a given range from this array;
|
||||||
@ -684,7 +717,7 @@ public abstract class ArrayData {
|
|||||||
*
|
*
|
||||||
* @return new ArrayData after deletion
|
* @return new ArrayData after deletion
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData delete(long fromIndex, long toIndex);
|
public abstract ArrayData delete(final long fromIndex, final long toIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the ArrayData to one with a different element type
|
* Convert the ArrayData to one with a different element type
|
||||||
@ -694,7 +727,7 @@ public abstract class ArrayData {
|
|||||||
* @param type new element type
|
* @param type new element type
|
||||||
* @return new array data
|
* @return new array data
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData convert(Class<?> type);
|
public abstract ArrayData convert(final Class<?> type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Push an array of items to the end of the array
|
* Push an array of items to the end of the array
|
||||||
@ -778,7 +811,7 @@ public abstract class ArrayData {
|
|||||||
* @param to end index + 1
|
* @param to end index + 1
|
||||||
* @return new array data
|
* @return new array data
|
||||||
*/
|
*/
|
||||||
public abstract ArrayData slice(long from, long to);
|
public abstract ArrayData slice(final long from, final long to);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fast splice operation. This just modifies the array according to the number of
|
* Fast splice operation. This just modifies the array according to the number of
|
||||||
@ -822,6 +855,34 @@ public abstract class ArrayData {
|
|||||||
return widest;
|
return widest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of keys in the array for the iterators
|
||||||
|
* @return iterator key list
|
||||||
|
*/
|
||||||
|
protected List<Long> computeIteratorKeys() {
|
||||||
|
final List<Long> keys = new ArrayList<>();
|
||||||
|
|
||||||
|
final long len = length();
|
||||||
|
for (long i = 0L; i < len; i = nextIndex(i)) {
|
||||||
|
if (has((int)i)) {
|
||||||
|
keys.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an iterator that goes through all indexes of elements
|
||||||
|
* in this array. This includes those after array.length if
|
||||||
|
* they exist
|
||||||
|
*
|
||||||
|
* @return iterator
|
||||||
|
*/
|
||||||
|
public Iterator<Long> indexIterator() {
|
||||||
|
return computeIteratorKeys().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exponential growth function for array size when in
|
* Exponential growth function for array size when in
|
||||||
* need of resizing.
|
* need of resizing.
|
||||||
@ -841,7 +902,7 @@ public abstract class ArrayData {
|
|||||||
*
|
*
|
||||||
* @return the next index
|
* @return the next index
|
||||||
*/
|
*/
|
||||||
public long nextIndex(final long index) {
|
long nextIndex(final long index) {
|
||||||
return index + 1;
|
return index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ abstract class ArrayFilter extends ArrayData {
|
|||||||
protected ArrayData underlying;
|
protected ArrayData underlying;
|
||||||
|
|
||||||
ArrayFilter(final ArrayData underlying) {
|
ArrayFilter(final ArrayData underlying) {
|
||||||
super(underlying.length);
|
super(underlying.length());
|
||||||
this.underlying = underlying;
|
this.underlying = underlying;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,62 +70,55 @@ abstract class ArrayFilter extends ArrayData {
|
|||||||
@Override
|
@Override
|
||||||
public void shiftLeft(final int by) {
|
public void shiftLeft(final int by) {
|
||||||
underlying.shiftLeft(by);
|
underlying.shiftLeft(by);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
underlying = underlying.shiftRight(by);
|
underlying = underlying.shiftRight(by);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData ensure(final long safeIndex) {
|
public ArrayData ensure(final long safeIndex) {
|
||||||
underlying = underlying.ensure(safeIndex);
|
underlying = underlying.ensure(safeIndex);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shrink(final long newLength) {
|
public ArrayData shrink(final long newLength) {
|
||||||
underlying = underlying.shrink(newLength);
|
underlying = underlying.shrink(newLength);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final Object value, final boolean strict) {
|
public ArrayData set(final int index, final Object value, final boolean strict) {
|
||||||
underlying = underlying.set(index, value, strict);
|
underlying = underlying.set(index, value, strict);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final int value, final boolean strict) {
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
underlying = underlying.set(index, value, strict);
|
underlying = underlying.set(index, value, strict);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final long value, final boolean strict) {
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
underlying = underlying.set(index, value, strict);
|
underlying = underlying.set(index, value, strict);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final double value, final boolean strict) {
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
underlying = underlying.set(index, value, strict);
|
underlying = underlying.set(index, value, strict);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,29 +182,28 @@ abstract class ArrayFilter extends ArrayData {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData delete(final int index) {
|
public ArrayData delete(final int index) {
|
||||||
underlying = underlying.delete(index);
|
underlying = underlying.delete(index);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData delete(final long from, final long to) {
|
public ArrayData delete(final long from, final long to) {
|
||||||
underlying = underlying.delete(from, to);
|
underlying = underlying.delete(from, to);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData convert(final Class<?> type) {
|
public ArrayData convert(final Class<?> type) {
|
||||||
underlying = underlying.convert(type);
|
underlying = underlying.convert(type);
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
final Object value = underlying.pop();
|
final Object value = underlying.pop();
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
* @return true if we don't need to do any array reallocation to fit an element at index
|
* @return true if we don't need to do any array reallocation to fit an element at index
|
||||||
*/
|
*/
|
||||||
public final boolean hasRoomFor(final int index) {
|
public final boolean hasRoomFor(final int index) {
|
||||||
return has(index) || (index == length && ensure(index) == this);
|
return has(index) || (index == length() && ensure(index) == this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,7 +73,7 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
* @return true if empty
|
* @return true if empty
|
||||||
*/
|
*/
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return length == 0L;
|
return length() == 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,8 +38,7 @@ final class DeletedArrayFilter extends ArrayFilter {
|
|||||||
|
|
||||||
DeletedArrayFilter(final ArrayData underlying) {
|
DeletedArrayFilter(final ArrayData underlying) {
|
||||||
super(underlying);
|
super(underlying);
|
||||||
|
this.deleted = new BitVector(underlying.length());
|
||||||
this.deleted = new BitVector(underlying.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -79,25 +78,24 @@ final class DeletedArrayFilter extends ArrayFilter {
|
|||||||
@Override
|
@Override
|
||||||
public void shiftLeft(final int by) {
|
public void shiftLeft(final int by) {
|
||||||
super.shiftLeft(by);
|
super.shiftLeft(by);
|
||||||
deleted.shiftLeft(by, length);
|
deleted.shiftLeft(by, length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
super.shiftRight(by);
|
super.shiftRight(by);
|
||||||
deleted.shiftRight(by, length);
|
deleted.shiftRight(by, length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData ensure(final long safeIndex) {
|
public ArrayData ensure(final long safeIndex) {
|
||||||
if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length) {
|
if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
|
||||||
return new SparseArrayData(this, safeIndex + 1);
|
return new SparseArrayData(this, safeIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.ensure(safeIndex);
|
super.ensure(safeIndex);
|
||||||
deleted.resize(length);
|
deleted.resize(length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -105,36 +103,31 @@ final class DeletedArrayFilter extends ArrayFilter {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData shrink(final long newLength) {
|
public ArrayData shrink(final long newLength) {
|
||||||
super.shrink(newLength);
|
super.shrink(newLength);
|
||||||
deleted.resize(length);
|
deleted.resize(length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final Object value, final boolean strict) {
|
public ArrayData set(final int index, final Object value, final boolean strict) {
|
||||||
deleted.clear(ArrayIndex.toLongIndex(index));
|
deleted.clear(ArrayIndex.toLongIndex(index));
|
||||||
|
|
||||||
return super.set(index, value, strict);
|
return super.set(index, value, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final int value, final boolean strict) {
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
deleted.clear(ArrayIndex.toLongIndex(index));
|
deleted.clear(ArrayIndex.toLongIndex(index));
|
||||||
|
|
||||||
return super.set(index, value, strict);
|
return super.set(index, value, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final long value, final boolean strict) {
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
deleted.clear(ArrayIndex.toLongIndex(index));
|
deleted.clear(ArrayIndex.toLongIndex(index));
|
||||||
|
|
||||||
return super.set(index, value, strict);
|
return super.set(index, value, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final double value, final boolean strict) {
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
deleted.clear(ArrayIndex.toLongIndex(index));
|
deleted.clear(ArrayIndex.toLongIndex(index));
|
||||||
|
|
||||||
return super.set(index, value, strict);
|
return super.set(index, value, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +139,7 @@ final class DeletedArrayFilter extends ArrayFilter {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData delete(final int index) {
|
public ArrayData delete(final int index) {
|
||||||
final long longIndex = ArrayIndex.toLongIndex(index);
|
final long longIndex = ArrayIndex.toLongIndex(index);
|
||||||
assert longIndex >= 0 && longIndex < length;
|
assert longIndex >= 0 && longIndex < length();
|
||||||
deleted.set(longIndex);
|
deleted.set(longIndex);
|
||||||
underlying.setEmpty(index);
|
underlying.setEmpty(index);
|
||||||
return this;
|
return this;
|
||||||
@ -154,7 +147,7 @@ final class DeletedArrayFilter extends ArrayFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData delete(final long fromIndex, final long toIndex) {
|
public ArrayData delete(final long fromIndex, final long toIndex) {
|
||||||
assert fromIndex >= 0 && fromIndex <= toIndex && toIndex < length;
|
assert fromIndex >= 0 && fromIndex <= toIndex && toIndex < length();
|
||||||
deleted.setRange(fromIndex, toIndex + 1);
|
deleted.setRange(fromIndex, toIndex + 1);
|
||||||
underlying.setEmpty(fromIndex, toIndex);
|
underlying.setEmpty(fromIndex, toIndex);
|
||||||
return this;
|
return this;
|
||||||
@ -162,7 +155,7 @@ final class DeletedArrayFilter extends ArrayFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
final long index = length - 1;
|
final long index = length() - 1;
|
||||||
|
|
||||||
if (super.has((int)index)) {
|
if (super.has((int)index)) {
|
||||||
final boolean isDeleted = deleted.isSet(index);
|
final boolean isDeleted = deleted.isSet(index);
|
||||||
@ -179,7 +172,7 @@ final class DeletedArrayFilter extends ArrayFilter {
|
|||||||
final ArrayData newArray = underlying.slice(from, to);
|
final ArrayData newArray = underlying.slice(from, to);
|
||||||
final DeletedArrayFilter newFilter = new DeletedArrayFilter(newArray);
|
final DeletedArrayFilter newFilter = new DeletedArrayFilter(newArray);
|
||||||
newFilter.getDeleted().copy(deleted);
|
newFilter.getDeleted().copy(deleted);
|
||||||
newFilter.getDeleted().shiftLeft(from, newFilter.length);
|
newFilter.getDeleted().shiftLeft(from, newFilter.length());
|
||||||
|
|
||||||
return newFilter;
|
return newFilter;
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,10 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ArrayData maybeSparse(final ArrayData underlying, final long hi) {
|
private static ArrayData maybeSparse(final ArrayData underlying, final long hi) {
|
||||||
if(hi < SparseArrayData.MAX_DENSE_LENGTH || underlying instanceof SparseArrayData) {
|
if (hi < SparseArrayData.MAX_DENSE_LENGTH || underlying instanceof SparseArrayData) {
|
||||||
return underlying;
|
return underlying;
|
||||||
}
|
}
|
||||||
return new SparseArrayData(underlying, underlying.length);
|
return new SparseArrayData(underlying, underlying.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEmpty() {
|
private boolean isEmpty() {
|
||||||
@ -93,7 +93,7 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData ensure(final long safeIndex) {
|
public ArrayData ensure(final long safeIndex) {
|
||||||
if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length) {
|
if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
|
||||||
return new SparseArrayData(this, safeIndex + 1);
|
return new SparseArrayData(this, safeIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
super.shiftRight(by);
|
super.shiftRight(by);
|
||||||
final long len = length;
|
final long len = length();
|
||||||
lo = Math.min(len, lo + by);
|
lo = Math.min(len, lo + by);
|
||||||
hi = Math.min(len - 1, hi + by);
|
hi = Math.min(len - 1, hi + by);
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
final int index = (int)length - 1;
|
final int index = (int)length() - 1;
|
||||||
if (super.has(index)) {
|
if (super.has(index)) {
|
||||||
final boolean isDeleted = isDeleted(index);
|
final boolean isDeleted = isDeleted(index);
|
||||||
final Object value = super.pop();
|
final Object value = super.pop();
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
package jdk.nashorn.internal.runtime.arrays;
|
package jdk.nashorn.internal.runtime.arrays;
|
||||||
|
|
||||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||||
|
|
||||||
import jdk.nashorn.internal.objects.Global;
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
||||||
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ArrayData after the array has been frozen by Object.freeze call.
|
* ArrayData after the array has been frozen by Object.freeze call.
|
||||||
@ -79,4 +79,15 @@ final class FrozenArrayFilter extends SealedArrayFilter {
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData push(final boolean strict, final Object... items) {
|
||||||
|
return this; //nop
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object pop() {
|
||||||
|
final int len = (int)underlying.length();
|
||||||
|
return len == 0 ? ScriptRuntime.UNDEFINED : underlying.getObject(len - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,22 +119,24 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IntArrayData copy() {
|
public IntArrayData copy() {
|
||||||
return new IntArrayData(array.clone(), (int)length);
|
return new IntArrayData(array.clone(), (int)length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object asArrayOfType(final Class<?> componentType) {
|
public Object asArrayOfType(final Class<?> componentType) {
|
||||||
if (componentType == int.class) {
|
if (componentType == int.class) {
|
||||||
return array.length == length ? array.clone() : Arrays.copyOf(array, (int)length);
|
final int len = (int)length();
|
||||||
|
return array.length == len ? array.clone() : Arrays.copyOf(array, len);
|
||||||
}
|
}
|
||||||
return super.asArrayOfType(componentType);
|
return super.asArrayOfType(componentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object[] toObjectArray(final boolean trim) {
|
private Object[] toObjectArray(final boolean trim) {
|
||||||
assert length <= array.length : "length exceeds internal array size";
|
assert length() <= array.length : "length exceeds internal array size";
|
||||||
final Object[] oarray = new Object[trim ? (int)length : array.length];
|
final int len = (int)length();
|
||||||
|
final Object[] oarray = new Object[trim ? len : array.length];
|
||||||
|
|
||||||
for (int index = 0; index < length; index++) {
|
for (int index = 0; index < len; index++) {
|
||||||
oarray[index] = Integer.valueOf(array[index]);
|
oarray[index] = Integer.valueOf(array[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,10 +144,11 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private double[] toDoubleArray() {
|
private double[] toDoubleArray() {
|
||||||
assert length <= array.length : "length exceeds internal array size";
|
assert length() <= array.length : "length exceeds internal array size";
|
||||||
|
final int len = (int)length();
|
||||||
final double[] darray = new double[array.length];
|
final double[] darray = new double[array.length];
|
||||||
|
|
||||||
for (int index = 0; index < length; index++) {
|
for (int index = 0; index < len; index++) {
|
||||||
darray[index] = array[index];
|
darray[index] = array[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,10 +156,11 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long[] toLongArray() {
|
private long[] toLongArray() {
|
||||||
assert length <= array.length : "length exceeds internal array size";
|
assert length() <= array.length : "length exceeds internal array size";
|
||||||
|
final int len = (int)length();
|
||||||
final long[] larray = new long[array.length];
|
final long[] larray = new long[array.length];
|
||||||
|
|
||||||
for (int index = 0; index < length; index++) {
|
for (int index = 0; index < len; index++) {
|
||||||
larray[index] = array[index];
|
larray[index] = array[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,15 +168,15 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private LongArrayData convertToLong() {
|
private LongArrayData convertToLong() {
|
||||||
return new LongArrayData(toLongArray(), (int)length);
|
return new LongArrayData(toLongArray(), (int)length());
|
||||||
}
|
}
|
||||||
|
|
||||||
private NumberArrayData convertToDouble() {
|
private NumberArrayData convertToDouble() {
|
||||||
return new NumberArrayData(toDoubleArray(), (int)length);
|
return new NumberArrayData(toDoubleArray(), (int)length());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectArrayData convertToObject() {
|
private ObjectArrayData convertToObject() {
|
||||||
return new ObjectArrayData(toObjectArray(false), (int)length);
|
return new ObjectArrayData(toObjectArray(false), (int)length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -196,7 +200,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
final ArrayData newData = ensure(by + length - 1);
|
final ArrayData newData = ensure(by + length() - 1);
|
||||||
if (newData != this) {
|
if (newData != this) {
|
||||||
newData.shiftRight(by);
|
newData.shiftRight(by);
|
||||||
return newData;
|
return newData;
|
||||||
@ -241,7 +245,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final int value, final boolean strict) {
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -250,7 +254,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
public ArrayData set(final int index, final long value, final boolean strict) {
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
if (JSType.isRepresentableAsInt(value)) {
|
if (JSType.isRepresentableAsInt(value)) {
|
||||||
array[index] = JSType.toInt32(value);
|
array[index] = JSType.toInt32(value);
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +265,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
public ArrayData set(final int index, final double value, final boolean strict) {
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
if (JSType.isRepresentableAsInt(value)) {
|
if (JSType.isRepresentableAsInt(value)) {
|
||||||
array[index] = (int)(long)value;
|
array[index] = (int)(long)value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,7 +309,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean has(final int index) {
|
public boolean has(final int index) {
|
||||||
return 0 <= index && index < length;
|
return 0 <= index && index < length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -320,11 +324,12 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
if (length == 0) {
|
final int len = (int)length();
|
||||||
|
if (len == 0) {
|
||||||
return ScriptRuntime.UNDEFINED;
|
return ScriptRuntime.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int newLength = (int)length - 1;
|
final int newLength = len - 1;
|
||||||
final int elem = array[newLength];
|
final int elem = array[newLength];
|
||||||
array[newLength] = 0;
|
array[newLength] = 0;
|
||||||
setLength(newLength);
|
setLength(newLength);
|
||||||
@ -334,12 +339,12 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData slice(final long from, final long to) {
|
public ArrayData slice(final long from, final long to) {
|
||||||
return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)(to - (from < 0 ? from + length : from)));
|
return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)(to - (from < 0 ? from + length() : from)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ArrayData push(final boolean strict, final int item) {
|
public final ArrayData push(final boolean strict, final int item) {
|
||||||
final long len = length;
|
final long len = length();
|
||||||
final ArrayData newData = ensure(len);
|
final ArrayData newData = ensure(len);
|
||||||
if (newData == this) {
|
if (newData == this) {
|
||||||
array[(int)len] = item;
|
array[(int)len] = item;
|
||||||
@ -350,7 +355,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
|
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
|
||||||
final long oldLength = length;
|
final long oldLength = length();
|
||||||
final long newLength = oldLength - removed + added;
|
final long newLength = oldLength - removed + added;
|
||||||
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
|
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -384,21 +389,21 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long fastPush(final int arg) {
|
public long fastPush(final int arg) {
|
||||||
final int len = (int)length;
|
final int len = (int)length();
|
||||||
if (len == array.length) {
|
if (len == array.length) {
|
||||||
array = Arrays.copyOf(array, nextSize(len));
|
array = Arrays.copyOf(array, nextSize(len));
|
||||||
}
|
}
|
||||||
array[len] = arg;
|
array[len] = arg;
|
||||||
return ++length;
|
return increaseLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
//length must not be zero
|
//length must not be zero
|
||||||
@Override
|
@Override
|
||||||
public int fastPopInt() {
|
public int fastPopInt() {
|
||||||
if (length == 0) {
|
if (length() == 0) {
|
||||||
throw new ClassCastException(); //relink
|
throw new ClassCastException(); //relink
|
||||||
}
|
}
|
||||||
final int newLength = (int)--length;
|
final int newLength = (int)decreaseLength();
|
||||||
final int elem = array[newLength];
|
final int elem = array[newLength];
|
||||||
array[newLength] = 0;
|
array[newLength] = 0;
|
||||||
return elem;
|
return elem;
|
||||||
@ -421,8 +426,8 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
final int otherLength = (int)otherData.length;
|
final int otherLength = (int)otherData.length();
|
||||||
final int thisLength = (int)length;
|
final int thisLength = (int)length();
|
||||||
assert otherLength > 0 && thisLength > 0;
|
assert otherLength > 0 && thisLength > 0;
|
||||||
|
|
||||||
final int[] otherArray = ((IntArrayData)otherData).array;
|
final int[] otherArray = ((IntArrayData)otherData).array;
|
||||||
@ -437,7 +442,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
assert length <= array.length : length + " > " + array.length;
|
assert length() <= array.length : length() + " > " + array.length;
|
||||||
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length));
|
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,198 @@
|
|||||||
|
package jdk.nashorn.internal.runtime.arrays;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import jdk.nashorn.internal.runtime.JSType;
|
||||||
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter to use for ArrayData where the length is not writable.
|
||||||
|
* The default behavior is just to ignore {@link ArrayData#setLength}
|
||||||
|
*/
|
||||||
|
final class LengthNotWritableFilter extends ArrayFilter {
|
||||||
|
private final SortedMap<Long, Object> extraElements; //elements with index >= length
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param underlying array
|
||||||
|
*/
|
||||||
|
LengthNotWritableFilter(final ArrayData underlying) {
|
||||||
|
this(underlying, new TreeMap<Long, Object>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private LengthNotWritableFilter(final ArrayData underlying, final SortedMap<Long, Object> extraElements) {
|
||||||
|
super(underlying);
|
||||||
|
this.extraElements = extraElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData copy() {
|
||||||
|
return new LengthNotWritableFilter(underlying.copy(), new TreeMap<>(extraElements));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean has(final int index) {
|
||||||
|
return super.has(index) || extraElements.containsKey((long)index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the length of the data array
|
||||||
|
*
|
||||||
|
* @param length the new length for the data array
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setLength(final long length) {
|
||||||
|
//empty - setting length for a LengthNotWritableFilter is always a nop
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData ensure(final long index) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData slice(final long from, final long to) {
|
||||||
|
//return array[from...to), or array[from...length] if undefined, in this case not as we are an ArrayData
|
||||||
|
return new LengthNotWritableFilter(underlying.slice(from, to), extraElements.subMap(from, to));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkAdd(final long index, final Object value) {
|
||||||
|
if (index >= length()) {
|
||||||
|
extraElements.put(index, value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object get(final long index) {
|
||||||
|
final Object obj = extraElements.get(index);
|
||||||
|
if (obj == null) {
|
||||||
|
return ScriptRuntime.UNDEFINED;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(final int index) {
|
||||||
|
if (index >= length()) {
|
||||||
|
return JSType.toInt32(get(index));
|
||||||
|
}
|
||||||
|
return underlying.getInt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIntOptimistic(final int index, final int programPoint) {
|
||||||
|
if (index >= length()) {
|
||||||
|
return JSType.toInt32Optimistic(get(index), programPoint);
|
||||||
|
}
|
||||||
|
return underlying.getIntOptimistic(index, programPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(final int index) {
|
||||||
|
if (index >= length()) {
|
||||||
|
return JSType.toLong(get(index));
|
||||||
|
}
|
||||||
|
return underlying.getLong(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLongOptimistic(final int index, final int programPoint) {
|
||||||
|
if (index >= length()) {
|
||||||
|
return JSType.toLongOptimistic(get(index), programPoint);
|
||||||
|
}
|
||||||
|
return underlying.getLongOptimistic(index, programPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDouble(final int index) {
|
||||||
|
if (index >= length()) {
|
||||||
|
return JSType.toNumber(get(index));
|
||||||
|
}
|
||||||
|
return underlying.getDouble(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDoubleOptimistic(final int index, final int programPoint) {
|
||||||
|
if (index >= length()) {
|
||||||
|
return JSType.toNumberOptimistic(get(index), programPoint);
|
||||||
|
}
|
||||||
|
return underlying.getDoubleOptimistic(index, programPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getObject(final int index) {
|
||||||
|
if (index >= length()) {
|
||||||
|
return get(index);
|
||||||
|
}
|
||||||
|
return underlying.getObject(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final Object value, final boolean strict) {
|
||||||
|
if (checkAdd(index, value)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
underlying = underlying.set(index, value, strict);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
|
if (checkAdd(index, value)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
underlying = underlying.set(index, value, strict);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
|
if (checkAdd(index, value)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
underlying = underlying.set(index, value, strict);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
|
if (checkAdd(index, value)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
underlying = underlying.set(index, value, strict);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData delete(final int index) {
|
||||||
|
extraElements.remove(index);
|
||||||
|
underlying = underlying.delete(index);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData delete(final long fromIndex, final long toIndex) {
|
||||||
|
for (final Iterator<Long> iter = extraElements.keySet().iterator(); iter.hasNext();) {
|
||||||
|
final long next = iter.next();
|
||||||
|
if (next >= fromIndex && next <= toIndex) {
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
if (next > toIndex) { //ordering guaranteed because TreeSet
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
underlying = underlying.delete(fromIndex, toIndex);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Long> indexIterator() {
|
||||||
|
final List<Long> keys = computeIteratorKeys();
|
||||||
|
keys.addAll(extraElements.keySet()); //even if they are outside length this is fine
|
||||||
|
return keys.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,7 +27,6 @@ package jdk.nashorn.internal.runtime.arrays;
|
|||||||
|
|
||||||
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
|
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
|
||||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -77,7 +76,7 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LongArrayData copy() {
|
public LongArrayData copy() {
|
||||||
return new LongArrayData(array.clone(), (int)length);
|
return new LongArrayData(array.clone(), (int)length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -86,10 +85,11 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object[] toObjectArray(final boolean trim) {
|
private Object[] toObjectArray(final boolean trim) {
|
||||||
assert length <= array.length : "length exceeds internal array size";
|
assert length() <= array.length : "length exceeds internal array size";
|
||||||
final Object[] oarray = new Object[trim ? (int)length : array.length];
|
final int len = (int)length();
|
||||||
|
final Object[] oarray = new Object[trim ? len : array.length];
|
||||||
|
|
||||||
for (int index = 0; index < length; index++) {
|
for (int index = 0; index < len; index++) {
|
||||||
oarray[index] = Long.valueOf(array[index]);
|
oarray[index] = Long.valueOf(array[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,16 +99,18 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
@Override
|
@Override
|
||||||
public Object asArrayOfType(final Class<?> componentType) {
|
public Object asArrayOfType(final Class<?> componentType) {
|
||||||
if (componentType == long.class) {
|
if (componentType == long.class) {
|
||||||
return array.length == length ? array.clone() : Arrays.copyOf(array, (int)length);
|
final int len = (int)length();
|
||||||
|
return array.length == len ? array.clone() : Arrays.copyOf(array, len);
|
||||||
}
|
}
|
||||||
return super.asArrayOfType(componentType);
|
return super.asArrayOfType(componentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private double[] toDoubleArray() {
|
private double[] toDoubleArray() {
|
||||||
assert length <= array.length : "length exceeds internal array size";
|
assert length() <= array.length : "length exceeds internal array size";
|
||||||
|
final int len = (int)length();
|
||||||
final double[] darray = new double[array.length];
|
final double[] darray = new double[array.length];
|
||||||
|
|
||||||
for (int index = 0; index < length; index++) {
|
for (int index = 0; index < len; index++) {
|
||||||
darray[index] = array[index];
|
darray[index] = array[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +122,7 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
if (type == Integer.class || type == Long.class) {
|
if (type == Integer.class || type == Long.class) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
final int len = (int)length;
|
final int len = (int)length();
|
||||||
if (type == Double.class) {
|
if (type == Double.class) {
|
||||||
return new NumberArrayData(toDoubleArray(), len);
|
return new NumberArrayData(toDoubleArray(), len);
|
||||||
}
|
}
|
||||||
@ -134,7 +136,7 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
final ArrayData newData = ensure(by + length - 1);
|
final ArrayData newData = ensure(by + length() - 1);
|
||||||
if (newData != this) {
|
if (newData != this) {
|
||||||
newData.shiftRight(by);
|
newData.shiftRight(by);
|
||||||
return newData;
|
return newData;
|
||||||
@ -179,14 +181,14 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final int value, final boolean strict) {
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final long value, final boolean strict) {
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +196,7 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
public ArrayData set(final int index, final double value, final boolean strict) {
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
if (JSType.isRepresentableAsLong(value)) {
|
if (JSType.isRepresentableAsLong(value)) {
|
||||||
array[index] = (long)value;
|
array[index] = (long)value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return convert(Double.class).set(index, value, strict);
|
return convert(Double.class).set(index, value, strict);
|
||||||
@ -265,7 +267,7 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean has(final int index) {
|
public boolean has(final int index) {
|
||||||
return 0 <= index && index < length;
|
return 0 <= index && index < length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -280,11 +282,12 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
if (length == 0) {
|
final int len = (int)length();
|
||||||
|
if (len == 0) {
|
||||||
return ScriptRuntime.UNDEFINED;
|
return ScriptRuntime.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int newLength = (int)length - 1;
|
final int newLength = len - 1;
|
||||||
final long elem = array[newLength];
|
final long elem = array[newLength];
|
||||||
array[newLength] = 0;
|
array[newLength] = 0;
|
||||||
setLength(newLength);
|
setLength(newLength);
|
||||||
@ -294,14 +297,14 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData slice(final long from, final long to) {
|
public ArrayData slice(final long from, final long to) {
|
||||||
final long start = from < 0 ? from + length : from;
|
final long start = from < 0 ? from + length() : from;
|
||||||
final long newLength = to - start;
|
final long newLength = to - start;
|
||||||
return new LongArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
|
return new LongArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ArrayData push(final boolean strict, final long item) {
|
public final ArrayData push(final boolean strict, final long item) {
|
||||||
final long len = length;
|
final long len = length();
|
||||||
final ArrayData newData = ensure(len);
|
final ArrayData newData = ensure(len);
|
||||||
if (newData == this) {
|
if (newData == this) {
|
||||||
array[(int)len] = item;
|
array[(int)len] = item;
|
||||||
@ -312,7 +315,7 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
|
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
|
||||||
final long oldLength = length;
|
final long oldLength = length();
|
||||||
final long newLength = oldLength - removed + added;
|
final long newLength = oldLength - removed + added;
|
||||||
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
|
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -345,20 +348,20 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long fastPush(final long arg) {
|
public long fastPush(final long arg) {
|
||||||
final int len = (int)length;
|
final int len = (int)length();
|
||||||
if (len == array.length) {
|
if (len == array.length) {
|
||||||
array = Arrays.copyOf(array, nextSize(len));
|
array = Arrays.copyOf(array, nextSize(len));
|
||||||
}
|
}
|
||||||
array[len] = arg;
|
array[len] = arg;
|
||||||
return ++length;
|
return increaseLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long fastPopLong() {
|
public long fastPopLong() {
|
||||||
if (length == 0) {
|
if (length() == 0) {
|
||||||
throw new ClassCastException();
|
throw new ClassCastException(); //undefined result
|
||||||
}
|
}
|
||||||
final int newLength = (int)--length;
|
final int newLength = (int)decreaseLength();
|
||||||
final long elem = array[newLength];
|
final long elem = array[newLength];
|
||||||
array[newLength] = 0;
|
array[newLength] = 0;
|
||||||
return elem;
|
return elem;
|
||||||
@ -376,8 +379,8 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
final int otherLength = (int)otherData.length;
|
final int otherLength = (int)otherData.length();
|
||||||
final int thisLength = (int)length;
|
final int thisLength = (int)length();
|
||||||
assert otherLength > 0 && thisLength > 0;
|
assert otherLength > 0 && thisLength > 0;
|
||||||
|
|
||||||
final long[] otherArray = ((LongArrayData)otherData).array;
|
final long[] otherArray = ((LongArrayData)otherData).array;
|
||||||
@ -392,13 +395,14 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
assert length <= array.length : length + " > " + array.length;
|
assert length() <= array.length : length() + " > " + array.length;
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).
|
final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).
|
||||||
append(": [");
|
append(": [");
|
||||||
for (int i = 0; i < length; i++) {
|
final int len = (int)length();
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
sb.append(array[i]).append('L'); //make sure L suffix is on elements, to discriminate this from IntArrayData.toString()
|
sb.append(array[i]).append('L'); //make sure L suffix is on elements, to discriminate this from IntArrayData.toString()
|
||||||
if (i + 1 < length) {
|
if (i + 1 < len) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
|
|||||||
/**
|
/**
|
||||||
* Filter class that wrap arrays that have been tagged non extensible
|
* Filter class that wrap arrays that have been tagged non extensible
|
||||||
*/
|
*/
|
||||||
public class NonExtensibleArrayFilter extends ArrayFilter {
|
final class NonExtensibleArrayFilter extends ArrayFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param underlying array
|
* @param underlying array
|
||||||
*/
|
*/
|
||||||
public NonExtensibleArrayFilter(final ArrayData underlying) {
|
NonExtensibleArrayFilter(final ArrayData underlying) {
|
||||||
super(underlying);
|
super(underlying);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ package jdk.nashorn.internal.runtime.arrays;
|
|||||||
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
|
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
|
||||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -76,7 +75,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NumberArrayData copy() {
|
public NumberArrayData copy() {
|
||||||
return new NumberArrayData(array.clone(), (int)length);
|
return new NumberArrayData(array.clone(), (int)length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -85,10 +84,11 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object[] toObjectArray(final boolean trim) {
|
private Object[] toObjectArray(final boolean trim) {
|
||||||
assert length <= array.length : "length exceeds internal array size";
|
assert length() <= array.length : "length exceeds internal array size";
|
||||||
final Object[] oarray = new Object[trim ? (int)length : array.length];
|
final int len = (int)length();
|
||||||
|
final Object[] oarray = new Object[trim ? len : array.length];
|
||||||
|
|
||||||
for (int index = 0; index < length; index++) {
|
for (int index = 0; index < len; index++) {
|
||||||
oarray[index] = Double.valueOf(array[index]);
|
oarray[index] = Double.valueOf(array[index]);
|
||||||
}
|
}
|
||||||
return oarray;
|
return oarray;
|
||||||
@ -96,8 +96,9 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object asArrayOfType(final Class<?> componentType) {
|
public Object asArrayOfType(final Class<?> componentType) {
|
||||||
if(componentType == double.class) {
|
if (componentType == double.class) {
|
||||||
return array.length == length ? array.clone() : Arrays.copyOf(array, (int)length);
|
final int len = (int)length();
|
||||||
|
return array.length == len ? array.clone() : Arrays.copyOf(array, len);
|
||||||
}
|
}
|
||||||
return super.asArrayOfType(componentType);
|
return super.asArrayOfType(componentType);
|
||||||
}
|
}
|
||||||
@ -105,7 +106,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
@Override
|
@Override
|
||||||
public ContinuousArrayData convert(final Class<?> type) {
|
public ContinuousArrayData convert(final Class<?> type) {
|
||||||
if (type != Double.class && type != Integer.class && type != Long.class) {
|
if (type != Double.class && type != Integer.class && type != Long.class) {
|
||||||
final int len = (int)length;
|
final int len = (int)length();
|
||||||
return new ObjectArrayData(toObjectArray(false), len);
|
return new ObjectArrayData(toObjectArray(false), len);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@ -118,7 +119,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
final ArrayData newData = ensure(by + length - 1);
|
final ArrayData newData = ensure(by + length() - 1);
|
||||||
if (newData != this) {
|
if (newData != this) {
|
||||||
newData.shiftRight(by);
|
newData.shiftRight(by);
|
||||||
return newData;
|
return newData;
|
||||||
@ -163,21 +164,21 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final int value, final boolean strict) {
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final long value, final boolean strict) {
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final double value, final boolean strict) {
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +242,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean has(final int index) {
|
public boolean has(final int index) {
|
||||||
return 0 <= index && index < length;
|
return 0 <= index && index < length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -256,11 +257,12 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
if (length == 0) {
|
final int len = (int)length();
|
||||||
|
if (len == 0) {
|
||||||
return UNDEFINED;
|
return UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int newLength = (int)length - 1;
|
final int newLength = len - 1;
|
||||||
final double elem = array[newLength];
|
final double elem = array[newLength];
|
||||||
array[newLength] = 0;
|
array[newLength] = 0;
|
||||||
setLength(newLength);
|
setLength(newLength);
|
||||||
@ -269,14 +271,14 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData slice(final long from, final long to) {
|
public ArrayData slice(final long from, final long to) {
|
||||||
final long start = from < 0 ? from + length : from;
|
final long start = from < 0 ? from + length() : from;
|
||||||
final long newLength = to - start;
|
final long newLength = to - start;
|
||||||
return new NumberArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
|
return new NumberArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ArrayData push(final boolean strict, final double item) {
|
public final ArrayData push(final boolean strict, final double item) {
|
||||||
final long len = length;
|
final long len = length();
|
||||||
final ArrayData newData = ensure(len);
|
final ArrayData newData = ensure(len);
|
||||||
if (newData == this) {
|
if (newData == this) {
|
||||||
array[(int)len] = item;
|
array[(int)len] = item;
|
||||||
@ -287,7 +289,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
|
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
|
||||||
final long oldLength = length;
|
final long oldLength = length();
|
||||||
final long newLength = oldLength - removed + added;
|
final long newLength = oldLength - removed + added;
|
||||||
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
|
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -325,21 +327,21 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long fastPush(final double arg) {
|
public long fastPush(final double arg) {
|
||||||
final int len = (int)length;
|
final int len = (int)length();
|
||||||
if (len == array.length) {
|
if (len == array.length) {
|
||||||
//note that fastpush never creates spares arrays, there is nothing to gain by that - it will just use even more memory
|
//note that fastpush never creates spares arrays, there is nothing to gain by that - it will just use even more memory
|
||||||
array = Arrays.copyOf(array, nextSize(len));
|
array = Arrays.copyOf(array, nextSize(len));
|
||||||
}
|
}
|
||||||
array[len] = arg;
|
array[len] = arg;
|
||||||
return ++length;
|
return increaseLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double fastPopDouble() {
|
public double fastPopDouble() {
|
||||||
if (length == 0) {
|
if (length() == 0) {
|
||||||
throw new ClassCastException();
|
throw new ClassCastException();
|
||||||
}
|
}
|
||||||
final int newLength = (int)--length;
|
final int newLength = (int)decreaseLength();
|
||||||
final double elem = array[newLength];
|
final double elem = array[newLength];
|
||||||
array[newLength] = 0;
|
array[newLength] = 0;
|
||||||
return elem;
|
return elem;
|
||||||
@ -352,8 +354,8 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
final int otherLength = (int)otherData.length;
|
final int otherLength = (int)otherData.length();
|
||||||
final int thisLength = (int)length;
|
final int thisLength = (int)length();
|
||||||
assert otherLength > 0 && thisLength > 0;
|
assert otherLength > 0 && thisLength > 0;
|
||||||
|
|
||||||
final double[] otherArray = ((NumberArrayData)otherData).array;
|
final double[] otherArray = ((NumberArrayData)otherData).array;
|
||||||
@ -368,7 +370,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
assert length <= array.length : length + " > " + array.length;
|
assert length() <= array.length : length() + " > " + array.length;
|
||||||
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length));
|
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
package jdk.nashorn.internal.runtime.arrays;
|
package jdk.nashorn.internal.runtime.arrays;
|
||||||
|
|
||||||
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
|
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -77,16 +76,16 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectArrayData copy() {
|
public ObjectArrayData copy() {
|
||||||
return new ObjectArrayData(array.clone(), (int)length);
|
return new ObjectArrayData(array.clone(), (int)length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] asObjectArray() {
|
public Object[] asObjectArray() {
|
||||||
return array.length == length ? array.clone() : asObjectArrayCopy();
|
return array.length == length() ? array.clone() : asObjectArrayCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object[] asObjectArrayCopy() {
|
private Object[] asObjectArrayCopy() {
|
||||||
final long len = length;
|
final long len = length();
|
||||||
assert len <= Integer.MAX_VALUE;
|
assert len <= Integer.MAX_VALUE;
|
||||||
final Object[] copy = new Object[(int)len];
|
final Object[] copy = new Object[(int)len];
|
||||||
System.arraycopy(array, 0, copy, 0, (int)len);
|
System.arraycopy(array, 0, copy, 0, (int)len);
|
||||||
@ -105,7 +104,7 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
final ArrayData newData = ensure(by + length - 1);
|
final ArrayData newData = ensure(by + length() - 1);
|
||||||
if (newData != this) {
|
if (newData != this) {
|
||||||
newData.shiftRight(by);
|
newData.shiftRight(by);
|
||||||
return newData;
|
return newData;
|
||||||
@ -137,28 +136,28 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final Object value, final boolean strict) {
|
public ArrayData set(final int index, final Object value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final int value, final boolean strict) {
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final long value, final boolean strict) {
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData set(final int index, final double value, final boolean strict) {
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
array[index] = value;
|
array[index] = value;
|
||||||
setLength(Math.max(index + 1, length));
|
setLength(Math.max(index + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +230,7 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean has(final int index) {
|
public boolean has(final int index) {
|
||||||
return 0 <= index && index < length;
|
return 0 <= index && index < length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -263,20 +262,20 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long fastPush(final Object arg) {
|
public long fastPush(final Object arg) {
|
||||||
final int len = (int)length;
|
final int len = (int)length();
|
||||||
if (len == array.length) {
|
if (len == array.length) {
|
||||||
array = Arrays.copyOf(array, nextSize(len));
|
array = Arrays.copyOf(array, nextSize(len));
|
||||||
}
|
}
|
||||||
array[len] = arg;
|
array[len] = arg;
|
||||||
return ++length;
|
return increaseLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object fastPopObject() {
|
public Object fastPopObject() {
|
||||||
if (length == 0) {
|
if (length() == 0) {
|
||||||
return ScriptRuntime.UNDEFINED;
|
return ScriptRuntime.UNDEFINED;
|
||||||
}
|
}
|
||||||
final int newLength = (int)--length;
|
final int newLength = (int)decreaseLength();
|
||||||
final Object elem = array[newLength];
|
final Object elem = array[newLength];
|
||||||
array[newLength] = ScriptRuntime.EMPTY;
|
array[newLength] = ScriptRuntime.EMPTY;
|
||||||
return elem;
|
return elem;
|
||||||
@ -284,11 +283,11 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
if (length == 0) {
|
if (length() == 0) {
|
||||||
return ScriptRuntime.UNDEFINED;
|
return ScriptRuntime.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int newLength = (int)length - 1;
|
final int newLength = (int)length() - 1;
|
||||||
final Object elem = array[newLength];
|
final Object elem = array[newLength];
|
||||||
setEmpty(newLength);
|
setEmpty(newLength);
|
||||||
setLength(newLength);
|
setLength(newLength);
|
||||||
@ -297,14 +296,14 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData slice(final long from, final long to) {
|
public ArrayData slice(final long from, final long to) {
|
||||||
final long start = from < 0 ? from + length : from;
|
final long start = from < 0 ? from + length() : from;
|
||||||
final long newLength = to - start;
|
final long newLength = to - start;
|
||||||
return new ObjectArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
|
return new ObjectArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData push(final boolean strict, final Object item) {
|
public ArrayData push(final boolean strict, final Object item) {
|
||||||
final long len = length;
|
final long len = length();
|
||||||
final ArrayData newData = ensure(len);
|
final ArrayData newData = ensure(len);
|
||||||
if (newData == this) {
|
if (newData == this) {
|
||||||
array[(int)len] = item;
|
array[(int)len] = item;
|
||||||
@ -315,7 +314,7 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
|
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
|
||||||
final long oldLength = length;
|
final long oldLength = length();
|
||||||
final long newLength = oldLength - removed + added;
|
final long newLength = oldLength - removed + added;
|
||||||
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
|
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@ -343,8 +342,8 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
final int otherLength = (int)otherData.length;
|
final int otherLength = (int)otherData.length();
|
||||||
final int thisLength = (int)length;
|
final int thisLength = (int)length();
|
||||||
assert otherLength > 0 && thisLength > 0;
|
assert otherLength > 0 && thisLength > 0;
|
||||||
|
|
||||||
final Object[] otherArray = ((ObjectArrayData)otherData).array;
|
final Object[] otherArray = ((ObjectArrayData)otherData).array;
|
||||||
@ -359,7 +358,7 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
assert length <= array.length : length + " > " + array.length;
|
assert length() <= array.length : length() + " > " + array.length;
|
||||||
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length));
|
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,21 +53,21 @@ class SparseArrayData extends ArrayData {
|
|||||||
|
|
||||||
SparseArrayData(final ArrayData underlying, final long length, final TreeMap<Long, Object> sparseMap) {
|
SparseArrayData(final ArrayData underlying, final long length, final TreeMap<Long, Object> sparseMap) {
|
||||||
super(length);
|
super(length);
|
||||||
assert underlying.length <= length;
|
assert underlying.length() <= length;
|
||||||
this.underlying = underlying;
|
this.underlying = underlying;
|
||||||
this.maxDenseLength = Math.max(MAX_DENSE_LENGTH, underlying.length);
|
this.maxDenseLength = Math.max(MAX_DENSE_LENGTH, underlying.length());
|
||||||
this.sparseMap = sparseMap;
|
this.sparseMap = sparseMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData copy() {
|
public ArrayData copy() {
|
||||||
return new SparseArrayData(underlying.copy(), length, new TreeMap<>(sparseMap));
|
return new SparseArrayData(underlying.copy(), length(), new TreeMap<>(sparseMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] asObjectArray() {
|
public Object[] asObjectArray() {
|
||||||
final int len = (int)Math.min(length, Integer.MAX_VALUE);
|
final int len = (int)Math.min(length(), Integer.MAX_VALUE);
|
||||||
final int underlyingLength = (int)Math.min(len, underlying.length);
|
final int underlyingLength = (int)Math.min(len, underlying.length());
|
||||||
final Object[] objArray = new Object[len];
|
final Object[] objArray = new Object[len];
|
||||||
|
|
||||||
for (int i = 0; i < underlyingLength; i++) {
|
for (int i = 0; i < underlyingLength; i++) {
|
||||||
@ -104,14 +104,15 @@ class SparseArrayData extends ArrayData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sparseMap = newSparseMap;
|
sparseMap = newSparseMap;
|
||||||
setLength(Math.max(length - by, 0));
|
setLength(Math.max(length() - by, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
final TreeMap<Long, Object> newSparseMap = new TreeMap<>();
|
final TreeMap<Long, Object> newSparseMap = new TreeMap<>();
|
||||||
if (underlying.length + by > maxDenseLength) {
|
final long len = underlying.length();
|
||||||
for (long i = maxDenseLength - by; i < underlying.length; i++) {
|
if (len + by > maxDenseLength) {
|
||||||
|
for (long i = maxDenseLength - by; i < len; i++) {
|
||||||
if (underlying.has((int) i)) {
|
if (underlying.has((int) i)) {
|
||||||
newSparseMap.put(Long.valueOf(i + by), underlying.getObject((int) i));
|
newSparseMap.put(Long.valueOf(i + by), underlying.getObject((int) i));
|
||||||
}
|
}
|
||||||
@ -127,23 +128,23 @@ class SparseArrayData extends ArrayData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sparseMap = newSparseMap;
|
sparseMap = newSparseMap;
|
||||||
setLength(length + by);
|
setLength(length() + by);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData ensure(final long safeIndex) {
|
public ArrayData ensure(final long safeIndex) {
|
||||||
if (safeIndex < maxDenseLength && underlying.length <= safeIndex) {
|
if (safeIndex < maxDenseLength && underlying.length() <= safeIndex) {
|
||||||
underlying = underlying.ensure(safeIndex);
|
underlying = underlying.ensure(safeIndex);
|
||||||
}
|
}
|
||||||
setLength(Math.max(safeIndex + 1, length));
|
setLength(Math.max(safeIndex + 1, length()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shrink(final long newLength) {
|
public ArrayData shrink(final long newLength) {
|
||||||
if (newLength < underlying.length) {
|
if (newLength < underlying.length()) {
|
||||||
underlying = underlying.shrink(newLength);
|
underlying = underlying.shrink(newLength);
|
||||||
underlying.setLength(newLength);
|
underlying.setLength(newLength);
|
||||||
sparseMap.clear();
|
sparseMap.clear();
|
||||||
@ -160,11 +161,11 @@ class SparseArrayData extends ArrayData {
|
|||||||
if (index >= 0 && index < maxDenseLength) {
|
if (index >= 0 && index < maxDenseLength) {
|
||||||
ensure(index);
|
ensure(index);
|
||||||
underlying = underlying.set(index, value, strict);
|
underlying = underlying.set(index, value, strict);
|
||||||
setLength(Math.max(underlying.length, length));
|
setLength(Math.max(underlying.length(), length()));
|
||||||
} else {
|
} else {
|
||||||
final Long longIndex = indexToKey(index);
|
final Long longIndex = indexToKey(index);
|
||||||
sparseMap.put(longIndex, value);
|
sparseMap.put(longIndex, value);
|
||||||
setLength(Math.max(longIndex + 1, length));
|
setLength(Math.max(longIndex + 1, length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -175,11 +176,11 @@ class SparseArrayData extends ArrayData {
|
|||||||
if (index >= 0 && index < maxDenseLength) {
|
if (index >= 0 && index < maxDenseLength) {
|
||||||
ensure(index);
|
ensure(index);
|
||||||
underlying = underlying.set(index, value, strict);
|
underlying = underlying.set(index, value, strict);
|
||||||
setLength(Math.max(underlying.length, length));
|
setLength(Math.max(underlying.length(), length()));
|
||||||
} else {
|
} else {
|
||||||
final Long longIndex = indexToKey(index);
|
final Long longIndex = indexToKey(index);
|
||||||
sparseMap.put(longIndex, value);
|
sparseMap.put(longIndex, value);
|
||||||
setLength(Math.max(longIndex + 1, length));
|
setLength(Math.max(longIndex + 1, length()));
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -189,11 +190,11 @@ class SparseArrayData extends ArrayData {
|
|||||||
if (index >= 0 && index < maxDenseLength) {
|
if (index >= 0 && index < maxDenseLength) {
|
||||||
ensure(index);
|
ensure(index);
|
||||||
underlying = underlying.set(index, value, strict);
|
underlying = underlying.set(index, value, strict);
|
||||||
setLength(Math.max(underlying.length, length));
|
setLength(Math.max(underlying.length(), length()));
|
||||||
} else {
|
} else {
|
||||||
final Long longIndex = indexToKey(index);
|
final Long longIndex = indexToKey(index);
|
||||||
sparseMap.put(longIndex, value);
|
sparseMap.put(longIndex, value);
|
||||||
setLength(Math.max(longIndex + 1, length));
|
setLength(Math.max(longIndex + 1, length()));
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -203,11 +204,11 @@ class SparseArrayData extends ArrayData {
|
|||||||
if (index >= 0 && index < maxDenseLength) {
|
if (index >= 0 && index < maxDenseLength) {
|
||||||
ensure(index);
|
ensure(index);
|
||||||
underlying = underlying.set(index, value, strict);
|
underlying = underlying.set(index, value, strict);
|
||||||
setLength(Math.max(underlying.length, length));
|
setLength(Math.max(underlying.length(), length()));
|
||||||
} else {
|
} else {
|
||||||
final Long longIndex = indexToKey(index);
|
final Long longIndex = indexToKey(index);
|
||||||
sparseMap.put(longIndex, value);
|
sparseMap.put(longIndex, value);
|
||||||
setLength(Math.max(longIndex + 1, length));
|
setLength(Math.max(longIndex + 1, length()));
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -294,7 +295,7 @@ class SparseArrayData extends ArrayData {
|
|||||||
@Override
|
@Override
|
||||||
public boolean has(final int index) {
|
public boolean has(final int index) {
|
||||||
if (index >= 0 && index < maxDenseLength) {
|
if (index >= 0 && index < maxDenseLength) {
|
||||||
return index < underlying.length && underlying.has(index);
|
return index < underlying.length() && underlying.has(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sparseMap.containsKey(indexToKey(index));
|
return sparseMap.containsKey(indexToKey(index));
|
||||||
@ -303,7 +304,7 @@ class SparseArrayData extends ArrayData {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData delete(final int index) {
|
public ArrayData delete(final int index) {
|
||||||
if (index >= 0 && index < maxDenseLength) {
|
if (index >= 0 && index < maxDenseLength) {
|
||||||
if (index < underlying.length) {
|
if (index < underlying.length()) {
|
||||||
underlying = underlying.delete(index);
|
underlying = underlying.delete(index);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -315,8 +316,8 @@ class SparseArrayData extends ArrayData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData delete(final long fromIndex, final long toIndex) {
|
public ArrayData delete(final long fromIndex, final long toIndex) {
|
||||||
if (fromIndex < maxDenseLength && fromIndex < underlying.length) {
|
if (fromIndex < maxDenseLength && fromIndex < underlying.length()) {
|
||||||
underlying = underlying.delete(fromIndex, Math.min(toIndex, underlying.length - 1));
|
underlying = underlying.delete(fromIndex, Math.min(toIndex, underlying.length() - 1));
|
||||||
}
|
}
|
||||||
if (toIndex >= maxDenseLength) {
|
if (toIndex >= maxDenseLength) {
|
||||||
sparseMap.subMap(fromIndex, true, toIndex, true).clear();
|
sparseMap.subMap(fromIndex, true, toIndex, true).clear();
|
||||||
@ -336,30 +337,34 @@ class SparseArrayData extends ArrayData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
if (length == 0) {
|
final long len = length();
|
||||||
|
final long underlyingLen = underlying.length();
|
||||||
|
if (len == 0) {
|
||||||
return ScriptRuntime.UNDEFINED;
|
return ScriptRuntime.UNDEFINED;
|
||||||
}
|
}
|
||||||
if (length == underlying.length) {
|
if (len == underlyingLen) {
|
||||||
final Object result = underlying.pop();
|
final Object result = underlying.pop();
|
||||||
setLength(underlying.length);
|
setLength(underlying.length());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
setLength(length - 1);
|
setLength(len - 1);
|
||||||
final Long key = Long.valueOf(length);
|
final Long key = Long.valueOf(len - 1);
|
||||||
return sparseMap.containsKey(key) ? sparseMap.remove(key) : ScriptRuntime.UNDEFINED;
|
return sparseMap.containsKey(key) ? sparseMap.remove(key) : ScriptRuntime.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData slice(final long from, final long to) {
|
public ArrayData slice(final long from, final long to) {
|
||||||
assert to <= length;
|
assert to <= length();
|
||||||
final long start = from < 0 ? (from + length) : from;
|
final long start = from < 0 ? (from + length()) : from;
|
||||||
final long newLength = to - start;
|
final long newLength = to - start;
|
||||||
|
|
||||||
|
final long underlyingLength = underlying.length();
|
||||||
|
|
||||||
if (start >= 0 && to <= maxDenseLength) {
|
if (start >= 0 && to <= maxDenseLength) {
|
||||||
if (newLength <= underlying.length) {
|
if (newLength <= underlyingLength) {
|
||||||
return underlying.slice(from, to);
|
return underlying.slice(from, to);
|
||||||
}
|
}
|
||||||
return underlying.slice(from, to).ensure(newLength - 1).delete(underlying.length, newLength);
|
return underlying.slice(from, to).ensure(newLength - 1).delete(underlyingLength, newLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayData sliced = EMPTY_ARRAY;
|
ArrayData sliced = EMPTY_ARRAY;
|
||||||
@ -369,13 +374,13 @@ class SparseArrayData extends ArrayData {
|
|||||||
sliced = sliced.set((int)(i - start), getObject((int)i), false);
|
sliced = sliced.set((int)(i - start), getObject((int)i), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert sliced.length == newLength;
|
assert sliced.length() == newLength;
|
||||||
return sliced;
|
return sliced;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long nextIndex(final long index) {
|
public long nextIndex(final long index) {
|
||||||
if (index < underlying.length - 1) {
|
if (index < underlying.length() - 1) {
|
||||||
return underlying.nextIndex(index);
|
return underlying.nextIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,6 +388,7 @@ class SparseArrayData extends ArrayData {
|
|||||||
if (nextKey != null) {
|
if (nextKey != null) {
|
||||||
return nextKey;
|
return nextKey;
|
||||||
}
|
}
|
||||||
return length;
|
|
||||||
|
return length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||||||
* @return element length
|
* @return element length
|
||||||
*/
|
*/
|
||||||
public final int getElementLength() {
|
public final int getElementLength() {
|
||||||
return (int)length;
|
return (int)length();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,7 +119,7 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean has(final int index) {
|
public final boolean has(final int index) {
|
||||||
return 0 <= index && index < length;
|
return 0 <= index && index < length();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,8 +39,7 @@ final class UndefinedArrayFilter extends ArrayFilter {
|
|||||||
|
|
||||||
UndefinedArrayFilter(final ArrayData underlying) {
|
UndefinedArrayFilter(final ArrayData underlying) {
|
||||||
super(underlying);
|
super(underlying);
|
||||||
|
this.undefined = new BitVector(underlying.length());
|
||||||
this.undefined = new BitVector(underlying.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -80,25 +79,24 @@ final class UndefinedArrayFilter extends ArrayFilter {
|
|||||||
@Override
|
@Override
|
||||||
public void shiftLeft(final int by) {
|
public void shiftLeft(final int by) {
|
||||||
super.shiftLeft(by);
|
super.shiftLeft(by);
|
||||||
undefined.shiftLeft(by, length);
|
undefined.shiftLeft(by, length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shiftRight(final int by) {
|
public ArrayData shiftRight(final int by) {
|
||||||
super.shiftRight(by);
|
super.shiftRight(by);
|
||||||
undefined.shiftRight(by, length);
|
undefined.shiftRight(by, length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData ensure(final long safeIndex) {
|
public ArrayData ensure(final long safeIndex) {
|
||||||
if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length) {
|
if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
|
||||||
return new SparseArrayData(this, safeIndex + 1);
|
return new SparseArrayData(this, safeIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.ensure(safeIndex);
|
super.ensure(safeIndex);
|
||||||
undefined.resize(length);
|
undefined.resize(length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -106,8 +104,7 @@ final class UndefinedArrayFilter extends ArrayFilter {
|
|||||||
@Override
|
@Override
|
||||||
public ArrayData shrink(final long newLength) {
|
public ArrayData shrink(final long newLength) {
|
||||||
super.shrink(newLength);
|
super.shrink(newLength);
|
||||||
undefined.resize(length);
|
undefined.resize(length());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +213,7 @@ final class UndefinedArrayFilter extends ArrayFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
final long index = length - 1;
|
final long index = length() - 1;
|
||||||
|
|
||||||
if (super.has((int)index)) {
|
if (super.has((int)index)) {
|
||||||
final boolean isUndefined = undefined.isSet(index);
|
final boolean isUndefined = undefined.isSet(index);
|
||||||
@ -233,7 +230,7 @@ final class UndefinedArrayFilter extends ArrayFilter {
|
|||||||
final ArrayData newArray = underlying.slice(from, to);
|
final ArrayData newArray = underlying.slice(from, to);
|
||||||
final UndefinedArrayFilter newFilter = new UndefinedArrayFilter(newArray);
|
final UndefinedArrayFilter newFilter = new UndefinedArrayFilter(newArray);
|
||||||
newFilter.getUndefined().copy(undefined);
|
newFilter.getUndefined().copy(undefined);
|
||||||
newFilter.getUndefined().shiftLeft(from, newFilter.length);
|
newFilter.getUndefined().shiftLeft(from, newFilter.length());
|
||||||
|
|
||||||
return newFilter;
|
return newFilter;
|
||||||
}
|
}
|
||||||
|
225
nashorn/test/script/basic/JDK-8035312.js
Normal file
225
nashorn/test/script/basic/JDK-8035312.js
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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-8035312 push to frozen array must not increase length property
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
* @fork
|
||||||
|
* @option -Dnashorn.debug=true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function printArrayDataClass(x) {
|
||||||
|
if (typeof Debug !== 'undefined') {
|
||||||
|
print(Debug.getArrayDataClass(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function gpush(x, elem) {
|
||||||
|
try {
|
||||||
|
print("Pushing " + elem + " to " + x);
|
||||||
|
x.push(elem);
|
||||||
|
} catch (e) {
|
||||||
|
print("caught error" + e);
|
||||||
|
}
|
||||||
|
print("\tarray is now [" + x + "] length is = " + x.length);
|
||||||
|
print();
|
||||||
|
printArrayDataClass(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
function gpop(x) {
|
||||||
|
try {
|
||||||
|
print("Popping from " + x);
|
||||||
|
x.pop();
|
||||||
|
} catch (e) {
|
||||||
|
if (!(e instanceof TypeError)) {
|
||||||
|
print("e of wrong type " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print("\tarray is now [" + x + "] length is = " + x.length);
|
||||||
|
print();
|
||||||
|
printArrayDataClass(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkArray(x) {
|
||||||
|
print();
|
||||||
|
print(">>> Push test");
|
||||||
|
|
||||||
|
var olen = x.length;
|
||||||
|
gpush(x, 0);
|
||||||
|
|
||||||
|
print("x.length === " + x.length + " (should be " + olen + ")");
|
||||||
|
print("x[3] === " + x[3] + " (should be 0)");
|
||||||
|
print("x[4] === " + x[4] + " (should be undefined)");
|
||||||
|
|
||||||
|
print();
|
||||||
|
print(">>> Pop test");
|
||||||
|
gpop(x);
|
||||||
|
gpop(x);
|
||||||
|
print("x.length === " + x.length + " (should be " + olen + ")");
|
||||||
|
print("x === " + x);
|
||||||
|
|
||||||
|
for (var i = 0 ; i < 5; i++) {
|
||||||
|
gpop(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
print("x.length === " + x.length + " (should be " + olen + ")");
|
||||||
|
print("x === " + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
print("*** Freezing");
|
||||||
|
var frozen = [1,2,3];
|
||||||
|
Object.freeze(frozen);
|
||||||
|
checkArray(frozen);
|
||||||
|
printArrayDataClass(frozen);
|
||||||
|
|
||||||
|
//so far so good
|
||||||
|
|
||||||
|
print();
|
||||||
|
print("*** Other length not writable issues");
|
||||||
|
var lengthNotWritable = [1,2,3];
|
||||||
|
Object.defineProperty(lengthNotWritable, "length", { writable: false });
|
||||||
|
checkArray(lengthNotWritable);
|
||||||
|
printArrayDataClass(lengthNotWritable);
|
||||||
|
|
||||||
|
function set(array, from, to, stride) {
|
||||||
|
//add three elements
|
||||||
|
for (var i = from; i < to; i+=stride) {
|
||||||
|
try {
|
||||||
|
print("Writing " + i);
|
||||||
|
array[i] = i;
|
||||||
|
printArrayDataClass(array);
|
||||||
|
} catch (e) {
|
||||||
|
print(e instanceof TypeError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//define empty array with non writable length
|
||||||
|
var arr = [1];
|
||||||
|
Object.defineProperty(arr, "length", { writable: false });
|
||||||
|
|
||||||
|
var olen2 = arr.length;
|
||||||
|
|
||||||
|
set(arr, 0, 3, 1);
|
||||||
|
|
||||||
|
if (arr.length != olen2) {
|
||||||
|
throw new ("error: " + arr.length + " != " + olen2);
|
||||||
|
}
|
||||||
|
|
||||||
|
print();
|
||||||
|
print("array writing 0-3, with 1 stride, array = " + arr);
|
||||||
|
print("length = " + arr.length + ", but elements are: " + arr[0] + " " + arr[1] + " " + arr[2]);
|
||||||
|
print();
|
||||||
|
|
||||||
|
//do the same but sparse/deleted range
|
||||||
|
var arr2 = [1];
|
||||||
|
Object.defineProperty(arr2, "length", { writable: false });
|
||||||
|
|
||||||
|
print("initial length = " + arr2.length);
|
||||||
|
var olen3 = arr2.length;
|
||||||
|
|
||||||
|
set(arr2, 0, 30, 3);
|
||||||
|
|
||||||
|
if (arr2.length != olen3) {
|
||||||
|
throw new ("error: " + arr2.length + " != " + olen3);
|
||||||
|
}
|
||||||
|
|
||||||
|
print();
|
||||||
|
var larger = 20;
|
||||||
|
print("array writing 0-" + larger + ", with 3 stride, array = " + arr2);
|
||||||
|
print("length = " + arr2.length + ", but elements are: " + arr2[0] + " " + arr2[1] + " " + arr2[2]);
|
||||||
|
|
||||||
|
for (var i = 0; i < larger; i++) {
|
||||||
|
if (arr2[i] === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
print(arr2[i] + " has length " + arr2.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
print();
|
||||||
|
var elem = 0x7fffffff - 10;
|
||||||
|
printArrayDataClass(arr2);
|
||||||
|
print("adding a new element high up in the array");
|
||||||
|
print("length before element was added " + arr2.length);
|
||||||
|
print("putting sparse at " + elem);
|
||||||
|
arr2[elem] = "sparse";
|
||||||
|
print("length after element was added " + arr2.length + " should be the same");
|
||||||
|
printArrayDataClass(arr2);
|
||||||
|
|
||||||
|
print();
|
||||||
|
print("Printing arr2 - this will fail if length is > 28 and it is " + arr2.length);
|
||||||
|
print("arr2 = [" + arr2 + "]");
|
||||||
|
print("new length that should not be writable = " + arr2.length);
|
||||||
|
print(arr2[elem] === "sparse");
|
||||||
|
print(arr2[elem]);
|
||||||
|
for (var i = 0; i < larger; i++) {
|
||||||
|
print(arr2[i]);
|
||||||
|
}
|
||||||
|
for (var key in arr2) {
|
||||||
|
print(key + ":" + arr2[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//issues reported by sundar - generic setter doesn't go through push/pop bulkable
|
||||||
|
|
||||||
|
function sundarExample2(arr, _writable) {
|
||||||
|
print("Checking if push works for bulkable non bulkable arrays - Setting length property not allowed");
|
||||||
|
arr[0] = "bar";
|
||||||
|
print(arr.length + " should be 1"); // should be 1
|
||||||
|
print(arr[0] + " should be bar");
|
||||||
|
print("["+ arr + "] should be [bar]");
|
||||||
|
|
||||||
|
// Object.defineProperty(arr, "length", { configurable: _writable });
|
||||||
|
Object.defineProperty(arr, "length", { writable: _writable });
|
||||||
|
arr[1] = "baz";
|
||||||
|
|
||||||
|
if (_writable) {
|
||||||
|
print(arr.length + " should be 2");
|
||||||
|
print(arr[0] + " should be bar");
|
||||||
|
print(arr[1] + " should be baz");
|
||||||
|
print("["+ arr + "] should be [bar,baz]");
|
||||||
|
} else {
|
||||||
|
print(arr.length + " should STILL be 1");
|
||||||
|
print(arr[0] + " should be bar");
|
||||||
|
print(arr[1] + " should be baz");
|
||||||
|
print("["+ arr + "] should be [bar]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var newArr1 = [];
|
||||||
|
sundarExample2(newArr1, false);
|
||||||
|
print();
|
||||||
|
try {
|
||||||
|
sundarExample2(newArr1, true);
|
||||||
|
print("should not get here");
|
||||||
|
} catch (e) {
|
||||||
|
if (!(e instanceof TypeError)) {
|
||||||
|
print("Wrong exception");
|
||||||
|
}
|
||||||
|
print("got TypeError when redefining length, as expected")
|
||||||
|
}
|
||||||
|
print();
|
||||||
|
|
||||||
|
sundarExample2([], true);
|
||||||
|
print("Done");
|
186
nashorn/test/script/basic/JDK-8035312.js.EXPECTED
Normal file
186
nashorn/test/script/basic/JDK-8035312.js.EXPECTED
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
*** Freezing
|
||||||
|
|
||||||
|
>>> Push test
|
||||||
|
Pushing 0 to 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
x.length === 3 (should be 3)
|
||||||
|
x[3] === undefined (should be 0)
|
||||||
|
x[4] === undefined (should be undefined)
|
||||||
|
|
||||||
|
>>> Pop test
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
x.length === 3 (should be 3)
|
||||||
|
x === 1,2,3
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
x.length === 3 (should be 3)
|
||||||
|
x === 1,2,3
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
|
||||||
|
|
||||||
|
*** Other length not writable issues
|
||||||
|
|
||||||
|
>>> Push test
|
||||||
|
Pushing 0 to 1,2,3
|
||||||
|
caught errorTypeError: "length" is not a writable property of [object Array]
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
x.length === 3 (should be 3)
|
||||||
|
x[3] === 0 (should be 0)
|
||||||
|
x[4] === undefined (should be undefined)
|
||||||
|
|
||||||
|
>>> Pop test
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
x.length === 3 (should be 3)
|
||||||
|
x === 1,2,3
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Popping from 1,2,3
|
||||||
|
array is now [1,2,3] length is = 3
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
x.length === 3 (should be 3)
|
||||||
|
x === 1,2,3
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 0
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 1
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 2
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
|
||||||
|
array writing 0-3, with 1 stride, array = 0
|
||||||
|
length = 1, but elements are: 0 undefined 2
|
||||||
|
|
||||||
|
initial length = 1
|
||||||
|
Writing 0
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 3
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 6
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 9
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 12
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 15
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 18
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 21
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 24
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
Writing 27
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
|
||||||
|
array writing 0-20, with 3 stride, array = 0
|
||||||
|
length = 1, but elements are: 0 undefined undefined
|
||||||
|
0 has length 1
|
||||||
|
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
adding a new element high up in the array
|
||||||
|
length before element was added 1
|
||||||
|
putting sparse at 2147483637
|
||||||
|
length after element was added 1 should be the same
|
||||||
|
class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
|
||||||
|
|
||||||
|
Printing arr2 - this will fail if length is > 28 and it is 1
|
||||||
|
arr2 = [0]
|
||||||
|
new length that should not be writable = 1
|
||||||
|
true
|
||||||
|
sparse
|
||||||
|
0
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
undefined
|
||||||
|
0:0
|
||||||
|
2147483637:sparse
|
||||||
|
Checking if push works for bulkable non bulkable arrays - Setting length property not allowed
|
||||||
|
1 should be 1
|
||||||
|
bar should be bar
|
||||||
|
[bar] should be [bar]
|
||||||
|
1 should STILL be 1
|
||||||
|
bar should be bar
|
||||||
|
baz should be baz
|
||||||
|
[bar] should be [bar]
|
||||||
|
|
||||||
|
Checking if push works for bulkable non bulkable arrays - Setting length property not allowed
|
||||||
|
1 should be 1
|
||||||
|
bar should be bar
|
||||||
|
[bar] should be [bar]
|
||||||
|
got TypeError when redefining length, as expected
|
||||||
|
|
||||||
|
Checking if push works for bulkable non bulkable arrays - Setting length property not allowed
|
||||||
|
1 should be 1
|
||||||
|
bar should be bar
|
||||||
|
[bar] should be [bar]
|
||||||
|
2 should be 2
|
||||||
|
bar should be bar
|
||||||
|
baz should be baz
|
||||||
|
[bar,baz] should be [bar,baz]
|
||||||
|
Done
|
65
nashorn/test/script/basic/JDK-8035312_2.js
Normal file
65
nashorn/test/script/basic/JDK-8035312_2.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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-8035312_2 - length setter and iterators
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict"
|
||||||
|
|
||||||
|
function printArray(a,n) {
|
||||||
|
print("PRINT_ARRAY CALLED: length = " + a.length);
|
||||||
|
print();
|
||||||
|
|
||||||
|
print("INDEXED");
|
||||||
|
for (var x = 0; x<n; x++) {
|
||||||
|
print("\t" + x + ":"+a[x]);
|
||||||
|
}
|
||||||
|
print("KEYS");
|
||||||
|
for (var key in a) {
|
||||||
|
print("\t" + key + ";" + a[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var b = [1,2,3];
|
||||||
|
|
||||||
|
Object.defineProperty(b, "length", { writable: false });
|
||||||
|
var high = 8;
|
||||||
|
b[high] = high;
|
||||||
|
|
||||||
|
printArray(b, high + 5);
|
||||||
|
|
||||||
|
var c = [1,2,3];
|
||||||
|
c[high] = high;
|
||||||
|
print();
|
||||||
|
print("element[" + high + "]: " + c.length + " " + c[high]);
|
||||||
|
print("Resetting length");
|
||||||
|
c.length = 3;
|
||||||
|
print("element[" + high + "]: " + c.length + " " + c[high]);
|
||||||
|
print();
|
||||||
|
|
||||||
|
printArray(c, high + 5);
|
||||||
|
print();
|
47
nashorn/test/script/basic/JDK-8035312_2.js.EXPECTED
Normal file
47
nashorn/test/script/basic/JDK-8035312_2.js.EXPECTED
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
PRINT_ARRAY CALLED: length = 3
|
||||||
|
|
||||||
|
INDEXED
|
||||||
|
0:1
|
||||||
|
1:2
|
||||||
|
2:3
|
||||||
|
3:undefined
|
||||||
|
4:undefined
|
||||||
|
5:undefined
|
||||||
|
6:undefined
|
||||||
|
7:undefined
|
||||||
|
8:8
|
||||||
|
9:undefined
|
||||||
|
10:undefined
|
||||||
|
11:undefined
|
||||||
|
12:undefined
|
||||||
|
KEYS
|
||||||
|
0;1
|
||||||
|
1;2
|
||||||
|
2;3
|
||||||
|
8;8
|
||||||
|
|
||||||
|
element[8]: 9 8
|
||||||
|
Resetting length
|
||||||
|
element[8]: 3 undefined
|
||||||
|
|
||||||
|
PRINT_ARRAY CALLED: length = 3
|
||||||
|
|
||||||
|
INDEXED
|
||||||
|
0:1
|
||||||
|
1:2
|
||||||
|
2:3
|
||||||
|
3:undefined
|
||||||
|
4:undefined
|
||||||
|
5:undefined
|
||||||
|
6:undefined
|
||||||
|
7:undefined
|
||||||
|
8:undefined
|
||||||
|
9:undefined
|
||||||
|
10:undefined
|
||||||
|
11:undefined
|
||||||
|
12:undefined
|
||||||
|
KEYS
|
||||||
|
0;1
|
||||||
|
1;2
|
||||||
|
2;3
|
||||||
|
|
43
nashorn/test/script/basic/JDK-8035312_3.js
Normal file
43
nashorn/test/script/basic/JDK-8035312_3.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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-8035312_3 - sparse array, non writable length
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var b = [1,2,3];
|
||||||
|
|
||||||
|
Object.defineProperty(b, "length", { writable: false });
|
||||||
|
var high = 23534343;
|
||||||
|
b[high-10] = high-10;
|
||||||
|
|
||||||
|
print(b[high-10]);
|
||||||
|
|
||||||
|
var c = [1,2,3];
|
||||||
|
c[high-10] = high-10;
|
||||||
|
c.length = 3;
|
||||||
|
print(c);
|
||||||
|
print(c[high-10]);
|
3
nashorn/test/script/basic/JDK-8035312_3.js.EXPECTED
Normal file
3
nashorn/test/script/basic/JDK-8035312_3.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
23534333
|
||||||
|
1,2,3
|
||||||
|
undefined
|
59
nashorn/test/script/basic/JDK-8035312_4.js
Normal file
59
nashorn/test/script/basic/JDK-8035312_4.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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-8035312_4 - pushes and pops for non writable length
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var b = [1,2,3];
|
||||||
|
Object.defineProperty(b, "length", { writable: false });
|
||||||
|
|
||||||
|
try {
|
||||||
|
b.push(4);
|
||||||
|
} catch (e) {
|
||||||
|
print("length = " + b.length);
|
||||||
|
print("i caught an error");
|
||||||
|
}
|
||||||
|
print(b);
|
||||||
|
print(b[3]);
|
||||||
|
print("length = " + b.length);
|
||||||
|
|
||||||
|
var c = [1,2,3];
|
||||||
|
Object.defineProperty(c, "length", { writable: false });
|
||||||
|
|
||||||
|
for (var i = 0; i < 5; i++) {
|
||||||
|
try {
|
||||||
|
c.pop();
|
||||||
|
} catch (e) {
|
||||||
|
print("length = " + c.length);
|
||||||
|
print("I caught an error");
|
||||||
|
print(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print(c);
|
||||||
|
print(c[3]);
|
||||||
|
print("length = " + b.length);
|
23
nashorn/test/script/basic/JDK-8035312_4.js.EXPECTED
Normal file
23
nashorn/test/script/basic/JDK-8035312_4.js.EXPECTED
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
length = 3
|
||||||
|
i caught an error
|
||||||
|
1,2,3
|
||||||
|
4
|
||||||
|
length = 3
|
||||||
|
length = 3
|
||||||
|
I caught an error
|
||||||
|
1,2,
|
||||||
|
length = 3
|
||||||
|
I caught an error
|
||||||
|
1,2,
|
||||||
|
length = 3
|
||||||
|
I caught an error
|
||||||
|
1,2,
|
||||||
|
length = 3
|
||||||
|
I caught an error
|
||||||
|
1,2,
|
||||||
|
length = 3
|
||||||
|
I caught an error
|
||||||
|
1,2,
|
||||||
|
1,2,
|
||||||
|
undefined
|
||||||
|
length = 3
|
60
nashorn/test/script/basic/JDK-8035312_5.js
Normal file
60
nashorn/test/script/basic/JDK-8035312_5.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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-8035312_5 - pushes and pops for frozen array
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var b = [1,2,3];
|
||||||
|
Object.freeze(b);
|
||||||
|
|
||||||
|
try {
|
||||||
|
b.push(4);
|
||||||
|
} catch (e) {
|
||||||
|
print("length = " + b.length);
|
||||||
|
print("i caught an error");
|
||||||
|
}
|
||||||
|
print(b);
|
||||||
|
print(b[3]);
|
||||||
|
print("length = " + b.length);
|
||||||
|
|
||||||
|
var c = [1,2,3];
|
||||||
|
Object.freeze(c);
|
||||||
|
|
||||||
|
for (var i = 0; i < 5; i++) {
|
||||||
|
try {
|
||||||
|
c.pop();
|
||||||
|
} catch (e) {
|
||||||
|
print("length = " + c.length);
|
||||||
|
print("I caught an error");
|
||||||
|
print(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print(c);
|
||||||
|
print(c[3]);
|
||||||
|
print("length = " + b.length);
|
||||||
|
|
6
nashorn/test/script/basic/JDK-8035312_5.js.EXPECTED
Normal file
6
nashorn/test/script/basic/JDK-8035312_5.js.EXPECTED
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
1,2,3
|
||||||
|
undefined
|
||||||
|
length = 3
|
||||||
|
1,2,3
|
||||||
|
undefined
|
||||||
|
length = 3
|
103
nashorn/test/script/basic/JDK-8062799.js
Normal file
103
nashorn/test/script/basic/JDK-8062799.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 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-8062799: Binary logical expressions can have numeric types
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var inspect = Java.type("jdk.nashorn.test.tools.StaticTypeInspector").inspect;
|
||||||
|
|
||||||
|
var b = true;
|
||||||
|
var i = 1;
|
||||||
|
var l = 4294967296;
|
||||||
|
var d = 2.1;
|
||||||
|
var o = "foo";
|
||||||
|
|
||||||
|
print(inspect(b || b, "b || b"));
|
||||||
|
print(inspect(b || i, "b || i"));
|
||||||
|
print(inspect(b || l, "b || l"));
|
||||||
|
print(inspect(b || d, "b || d"));
|
||||||
|
print(inspect(b || o, "b || o"));
|
||||||
|
|
||||||
|
print(inspect(i || b, "i || b"));
|
||||||
|
print(inspect(i || i, "i || i"));
|
||||||
|
print(inspect(i || l, "i || l"));
|
||||||
|
print(inspect(i || d, "i || d"));
|
||||||
|
print(inspect(i || o, "i || o"));
|
||||||
|
|
||||||
|
print(inspect(l || b, "l || b"));
|
||||||
|
print(inspect(l || i, "l || i"));
|
||||||
|
print(inspect(l || l, "l || l"));
|
||||||
|
print(inspect(l || d, "l || d"));
|
||||||
|
print(inspect(l || o, "l || o"));
|
||||||
|
|
||||||
|
print(inspect(d || b, "d || b"));
|
||||||
|
print(inspect(d || i, "d || i"));
|
||||||
|
print(inspect(d || l, "d || l"));
|
||||||
|
print(inspect(d || d, "d || d"));
|
||||||
|
print(inspect(d || o, "d || o"));
|
||||||
|
|
||||||
|
print(inspect(o || b, "o || b"));
|
||||||
|
print(inspect(o || i, "o || i"));
|
||||||
|
print(inspect(o || l, "o || l"));
|
||||||
|
print(inspect(o || d, "o || d"));
|
||||||
|
print(inspect(o || o, "o || o"));
|
||||||
|
|
||||||
|
print(inspect(b && b, "b && b"));
|
||||||
|
print(inspect(b && i, "b && i"));
|
||||||
|
print(inspect(b && l, "b && l"));
|
||||||
|
print(inspect(b && d, "b && d"));
|
||||||
|
print(inspect(b && o, "b && o"));
|
||||||
|
|
||||||
|
print(inspect(i && b, "i && b"));
|
||||||
|
print(inspect(i && i, "i && i"));
|
||||||
|
print(inspect(i && l, "i && l"));
|
||||||
|
print(inspect(i && d, "i && d"));
|
||||||
|
print(inspect(i && o, "i && o"));
|
||||||
|
|
||||||
|
print(inspect(l && b, "l && b"));
|
||||||
|
print(inspect(l && i, "l && i"));
|
||||||
|
print(inspect(l && l, "l && l"));
|
||||||
|
print(inspect(l && d, "l && d"));
|
||||||
|
print(inspect(l && o, "l && o"));
|
||||||
|
|
||||||
|
print(inspect(d && b, "d && b"));
|
||||||
|
print(inspect(d && i, "d && i"));
|
||||||
|
print(inspect(d && l, "d && l"));
|
||||||
|
print(inspect(d && d, "d && d"));
|
||||||
|
print(inspect(d && o, "d && o"));
|
||||||
|
|
||||||
|
print(inspect(o && b, "o && b"));
|
||||||
|
print(inspect(o && i, "o && i"));
|
||||||
|
print(inspect(o && l, "o && l"));
|
||||||
|
print(inspect(o && d, "o && d"));
|
||||||
|
print(inspect(o && o, "o && o"));
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
50
nashorn/test/script/basic/JDK-8062799.js.EXPECTED
Normal file
50
nashorn/test/script/basic/JDK-8062799.js.EXPECTED
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
b || b: boolean
|
||||||
|
b || i: boolean
|
||||||
|
b || l: boolean
|
||||||
|
b || d: boolean
|
||||||
|
b || o: boolean
|
||||||
|
i || b: int
|
||||||
|
i || i: int
|
||||||
|
i || l: long
|
||||||
|
i || d: double
|
||||||
|
i || o: int
|
||||||
|
l || b: long
|
||||||
|
l || i: long
|
||||||
|
l || l: long
|
||||||
|
l || d: double
|
||||||
|
l || o: long
|
||||||
|
d || b: double
|
||||||
|
d || i: double
|
||||||
|
d || l: double
|
||||||
|
d || d: double
|
||||||
|
d || o: double
|
||||||
|
o || b: object
|
||||||
|
o || i: object
|
||||||
|
o || l: object
|
||||||
|
o || d: object
|
||||||
|
o || o: object
|
||||||
|
b && b: boolean
|
||||||
|
b && i: int
|
||||||
|
b && l: long
|
||||||
|
b && d: double
|
||||||
|
b && o: object
|
||||||
|
i && b: boolean
|
||||||
|
i && i: int
|
||||||
|
i && l: long
|
||||||
|
i && d: double
|
||||||
|
i && o: object
|
||||||
|
l && b: boolean
|
||||||
|
l && i: long
|
||||||
|
l && l: long
|
||||||
|
l && d: double
|
||||||
|
l && o: object
|
||||||
|
d && b: boolean
|
||||||
|
d && i: double
|
||||||
|
d && l: double
|
||||||
|
d && d: double
|
||||||
|
d && o: object
|
||||||
|
o && b: boolean
|
||||||
|
o && i: int
|
||||||
|
o && l: long
|
||||||
|
o && d: double
|
||||||
|
o && o: object
|
46
nashorn/test/script/basic/JDK-8062937.js
Normal file
46
nashorn/test/script/basic/JDK-8062937.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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-8062937 - GlobalConstants produces wrong result with defineProperty and index setters
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var x = 1;
|
||||||
|
for (var i = 2; i < 5; i++) {
|
||||||
|
print(x);
|
||||||
|
Object.defineProperty(this, "x", {value: i});
|
||||||
|
}
|
||||||
|
print(x);
|
||||||
|
|
||||||
|
print();
|
||||||
|
|
||||||
|
var name = "y";
|
||||||
|
var y = 1;
|
||||||
|
for (var i = 2; i < 5; i++) {
|
||||||
|
print(y);
|
||||||
|
this[name] = i;
|
||||||
|
}
|
||||||
|
print(y);
|
9
nashorn/test/script/basic/JDK-8062937.js.EXPECTED
Normal file
9
nashorn/test/script/basic/JDK-8062937.js.EXPECTED
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
@ -1,6 +1,6 @@
|
|||||||
1,2,3,4,5,6
|
1,2,3,4,5,6
|
||||||
first: true
|
first: true
|
||||||
1,2,3,4,5,6,7
|
1,2,3,4,5,6
|
||||||
1,2,3,,,,4711.17,dingo!,4,5,6
|
1,2,3,,,,4711.17,dingo!,4,5,6
|
||||||
second: true
|
second: true
|
||||||
1,2,3,,,,4711.17,dingo!,4,5,6,7
|
1,2,3,,,,4711.17,dingo!,4,5,6
|
||||||
|
Loading…
Reference in New Issue
Block a user