diff options
Diffstat (limited to 'src/jdk/nashorn/internal/objects/NativeArray.java')
-rw-r--r-- | src/jdk/nashorn/internal/objects/NativeArray.java | 79 |
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)) { |