226 lines
5.9 KiB
JavaScript
226 lines
5.9 KiB
JavaScript
|
/*
|
||
|
* 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");
|