aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/objects/NativeArray.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/objects/NativeArray.java')
-rw-r--r--src/jdk/nashorn/internal/objects/NativeArray.java79
1 files changed, 62 insertions, 17 deletions
diff --git a/src/jdk/nashorn/internal/objects/NativeArray.java b/src/jdk/nashorn/internal/objects/NativeArray.java
index 37b6355b..67b9f1f1 100644
--- a/src/jdk/nashorn/internal/objects/NativeArray.java
+++ b/src/jdk/nashorn/internal/objects/NativeArray.java
@@ -372,9 +372,7 @@ public final class NativeArray extends ScriptObject {
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object isArray(final Object self, final Object arg) {
- return isArray(arg) || (arg == Global.instance().getArrayPrototype())
- || (arg instanceof NativeRegExpExecResult)
- || (arg instanceof JSObject && ((JSObject)arg).isArray());
+ return isArray(arg) || (arg instanceof JSObject && ((JSObject)arg).isArray());
}
/**
@@ -403,6 +401,26 @@ public final class NativeArray extends ScriptObject {
}
}
+ /**
+ * Prototype length getter
+ * @param self self reference
+ * @return the length of the object
+ */
+ @Getter(name = "length", where = Where.PROTOTYPE, attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+ public static Object getProtoLength(final Object self) {
+ return length(self); // Same as instance getter but we can't make nasgen use the same method for prototype
+ }
+
+ /**
+ * Prototype length setter
+ * @param self self reference
+ * @param length new length property
+ */
+ @Setter(name = "length", where = Where.PROTOTYPE, attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+ public static void setProtoLength(final Object self, final Object length) {
+ length(self, length); // Same as instance setter but we can't make nasgen use the same method for prototype
+ }
+
static long validLength(final Object length, final boolean reject) {
final double doubleLength = JSType.toNumber(length);
if (!Double.isNaN(doubleLength) && JSType.isRepresentableAsLong(doubleLength)) {
@@ -1007,19 +1025,42 @@ public final class NativeArray extends ScriptObject {
final long actualStart = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);
final long actualDeleteCount = Math.min(Math.max(JSType.toLong(deleteCount), 0), len - actualStart);
- final NativeArray array = new NativeArray(actualDeleteCount);
+ NativeArray returnValue;
- for (long k = 0; k < actualDeleteCount; k++) {
- final long from = actualStart + k;
+ if (actualStart <= Integer.MAX_VALUE && actualDeleteCount <= Integer.MAX_VALUE && bulkable(sobj)) {
+ try {
+ returnValue = new NativeArray(sobj.getArray().fastSplice((int)actualStart, (int)actualDeleteCount, items.length));
+
+ // Since this is a dense bulkable array we can use faster defineOwnProperty to copy new elements
+ int k = (int) actualStart;
+ for (int i = 0; i < items.length; i++, k++) {
+ sobj.defineOwnProperty(k, items[i]);
+ }
+ } catch (UnsupportedOperationException uoe) {
+ returnValue = slowSplice(sobj, actualStart, actualDeleteCount, items, len);
+ }
+ } else {
+ returnValue = slowSplice(sobj, actualStart, actualDeleteCount, items, len);
+ }
+
+ return returnValue;
+ }
+
+ private static NativeArray slowSplice(final ScriptObject sobj, final long start, final long deleteCount, final Object[] items, final long len) {
+
+ final NativeArray array = new NativeArray(deleteCount);
+
+ for (long k = 0; k < deleteCount; k++) {
+ final long from = start + k;
if (sobj.has(from)) {
array.defineOwnProperty(ArrayIndex.getArrayIndex(k), sobj.get(from));
}
}
- if (items.length < actualDeleteCount) {
- for (long k = actualStart; k < (len - actualDeleteCount); k++) {
- final long from = k + actualDeleteCount;
+ if (items.length < deleteCount) {
+ for (long k = start; k < (len - deleteCount); k++) {
+ final long from = k + deleteCount;
final long to = k + items.length;
if (sobj.has(from)) {
@@ -1029,12 +1070,12 @@ public final class NativeArray extends ScriptObject {
}
}
- for (long k = len; k > (len - actualDeleteCount + items.length); k--) {
+ for (long k = len; k > (len - deleteCount + items.length); k--) {
sobj.delete(k - 1, true);
}
- } else if (items.length > actualDeleteCount) {
- for (long k = len - actualDeleteCount; k > actualStart; k--) {
- final long from = k + actualDeleteCount - 1;
+ } else if (items.length > deleteCount) {
+ for (long k = len - deleteCount; k > start; k--) {
+ final long from = k + deleteCount - 1;
final long to = k + items.length - 1;
if (sobj.has(from)) {
@@ -1046,12 +1087,12 @@ public final class NativeArray extends ScriptObject {
}
}
- long k = actualStart;
+ long k = start;
for (int i = 0; i < items.length; i++, k++) {
sobj.set(k, items[i], true);
}
- final long newLength = len - actualDeleteCount + items.length;
+ final long newLength = len - deleteCount + items.length;
sobj.set("length", newLength, true);
return array;
@@ -1122,12 +1163,16 @@ public final class NativeArray extends ScriptObject {
try {
final ScriptObject sobj = (ScriptObject)Global.toObject(self);
final long len = JSType.toUint32(sobj.getLength());
- final long n = JSType.toLong(fromIndex);
+ if (len == 0) {
+ return -1;
+ }
- if (len == 0 || n >= len) {
+ final long n = JSType.toLong(fromIndex);
+ if (n >= len) {
return -1;
}
+
for (long k = Math.max(0, (n < 0) ? (len - Math.abs(n)) : n); k < len; k++) {
if (sobj.has(k)) {
if (ScriptRuntime.EQ_STRICT(sobj.get(k), searchElement)) {