lagergren@1095: /* lagergren@1095: * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. lagergren@1095: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. lagergren@1095: * lagergren@1095: * This code is free software; you can redistribute it and/or modify it lagergren@1095: * under the terms of the GNU General Public License version 2 only, as lagergren@1095: * published by the Free Software Foundation. lagergren@1095: * lagergren@1095: * This code is distributed in the hope that it will be useful, but WITHOUT lagergren@1095: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or lagergren@1095: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License lagergren@1095: * version 2 for more details (a copy is included in the LICENSE file that lagergren@1095: * accompanied this code). lagergren@1095: * lagergren@1095: * You should have received a copy of the GNU General Public License version lagergren@1095: * 2 along with this work; if not, write to the Free Software Foundation, lagergren@1095: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. lagergren@1095: * lagergren@1095: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA lagergren@1095: * or visit www.oracle.com if you need additional information or have any lagergren@1095: * questions. lagergren@1095: */ lagergren@1095: lagergren@1095: /** lagergren@1095: * JDK-8035312 push to frozen array must not increase length property lagergren@1095: * lagergren@1095: * @test lagergren@1095: * @run lagergren@1095: * @fork lagergren@1095: * @option -Dnashorn.debug=true lagergren@1095: */ lagergren@1095: lagergren@1095: function printArrayDataClass(x) { lagergren@1095: if (typeof Debug !== 'undefined') { lagergren@1095: print(Debug.getArrayDataClass(x)); lagergren@1095: } lagergren@1095: } lagergren@1095: lagergren@1095: function gpush(x, elem) { lagergren@1095: try { lagergren@1095: print("Pushing " + elem + " to " + x); lagergren@1095: x.push(elem); lagergren@1095: } catch (e) { lagergren@1095: print("caught error" + e); lagergren@1095: } lagergren@1095: print("\tarray is now [" + x + "] length is = " + x.length); lagergren@1095: print(); lagergren@1095: printArrayDataClass(x); lagergren@1095: } lagergren@1095: lagergren@1095: function gpop(x) { lagergren@1095: try { lagergren@1095: print("Popping from " + x); lagergren@1095: x.pop(); lagergren@1095: } catch (e) { lagergren@1095: if (!(e instanceof TypeError)) { lagergren@1095: print("e of wrong type " + e); lagergren@1095: } lagergren@1095: } lagergren@1095: print("\tarray is now [" + x + "] length is = " + x.length); lagergren@1095: print(); lagergren@1095: printArrayDataClass(x); lagergren@1095: } lagergren@1095: lagergren@1095: function checkArray(x) { lagergren@1095: print(); lagergren@1095: print(">>> Push test"); lagergren@1095: lagergren@1095: var olen = x.length; lagergren@1095: gpush(x, 0); lagergren@1095: lagergren@1095: print("x.length === " + x.length + " (should be " + olen + ")"); lagergren@1095: print("x[3] === " + x[3] + " (should be 0)"); lagergren@1095: print("x[4] === " + x[4] + " (should be undefined)"); lagergren@1095: lagergren@1095: print(); lagergren@1095: print(">>> Pop test"); lagergren@1095: gpop(x); lagergren@1095: gpop(x); lagergren@1095: print("x.length === " + x.length + " (should be " + olen + ")"); lagergren@1095: print("x === " + x); lagergren@1095: lagergren@1095: for (var i = 0 ; i < 5; i++) { lagergren@1095: gpop(x); lagergren@1095: } lagergren@1095: lagergren@1095: print("x.length === " + x.length + " (should be " + olen + ")"); lagergren@1095: print("x === " + x); lagergren@1095: } lagergren@1095: lagergren@1095: print("*** Freezing"); lagergren@1095: var frozen = [1,2,3]; lagergren@1095: Object.freeze(frozen); lagergren@1095: checkArray(frozen); lagergren@1095: printArrayDataClass(frozen); lagergren@1095: lagergren@1095: //so far so good lagergren@1095: lagergren@1095: print(); lagergren@1095: print("*** Other length not writable issues"); lagergren@1095: var lengthNotWritable = [1,2,3]; lagergren@1095: Object.defineProperty(lengthNotWritable, "length", { writable: false }); lagergren@1095: checkArray(lengthNotWritable); lagergren@1095: printArrayDataClass(lengthNotWritable); lagergren@1095: lagergren@1095: function set(array, from, to, stride) { lagergren@1095: //add three elements lagergren@1095: for (var i = from; i < to; i+=stride) { lagergren@1095: try { lagergren@1095: print("Writing " + i); lagergren@1095: array[i] = i; lagergren@1095: printArrayDataClass(array); lagergren@1095: } catch (e) { lagergren@1095: print(e instanceof TypeError); lagergren@1095: } lagergren@1095: } lagergren@1095: } lagergren@1095: lagergren@1095: //define empty array with non writable length lagergren@1095: var arr = [1]; lagergren@1095: Object.defineProperty(arr, "length", { writable: false }); lagergren@1095: lagergren@1095: var olen2 = arr.length; lagergren@1095: lagergren@1095: set(arr, 0, 3, 1); lagergren@1095: lagergren@1095: if (arr.length != olen2) { lagergren@1095: throw new ("error: " + arr.length + " != " + olen2); lagergren@1095: } lagergren@1095: lagergren@1095: print(); lagergren@1095: print("array writing 0-3, with 1 stride, array = " + arr); lagergren@1095: print("length = " + arr.length + ", but elements are: " + arr[0] + " " + arr[1] + " " + arr[2]); lagergren@1095: print(); lagergren@1095: lagergren@1095: //do the same but sparse/deleted range lagergren@1095: var arr2 = [1]; lagergren@1095: Object.defineProperty(arr2, "length", { writable: false }); lagergren@1095: lagergren@1095: print("initial length = " + arr2.length); lagergren@1095: var olen3 = arr2.length; lagergren@1095: lagergren@1095: set(arr2, 0, 30, 3); lagergren@1095: lagergren@1095: if (arr2.length != olen3) { lagergren@1095: throw new ("error: " + arr2.length + " != " + olen3); lagergren@1095: } lagergren@1095: lagergren@1095: print(); lagergren@1095: var larger = 20; lagergren@1095: print("array writing 0-" + larger + ", with 3 stride, array = " + arr2); lagergren@1095: print("length = " + arr2.length + ", but elements are: " + arr2[0] + " " + arr2[1] + " " + arr2[2]); lagergren@1095: lagergren@1095: for (var i = 0; i < larger; i++) { lagergren@1095: if (arr2[i] === undefined) { lagergren@1095: continue; lagergren@1095: } lagergren@1095: print(arr2[i] + " has length " + arr2.length); lagergren@1095: } lagergren@1095: lagergren@1095: print(); lagergren@1095: var elem = 0x7fffffff - 10; lagergren@1095: printArrayDataClass(arr2); lagergren@1095: print("adding a new element high up in the array"); lagergren@1095: print("length before element was added " + arr2.length); lagergren@1095: print("putting sparse at " + elem); lagergren@1095: arr2[elem] = "sparse"; lagergren@1095: print("length after element was added " + arr2.length + " should be the same"); lagergren@1095: printArrayDataClass(arr2); lagergren@1095: lagergren@1095: print(); lagergren@1095: print("Printing arr2 - this will fail if length is > 28 and it is " + arr2.length); lagergren@1095: print("arr2 = [" + arr2 + "]"); lagergren@1095: print("new length that should not be writable = " + arr2.length); lagergren@1095: print(arr2[elem] === "sparse"); lagergren@1095: print(arr2[elem]); lagergren@1095: for (var i = 0; i < larger; i++) { lagergren@1095: print(arr2[i]); lagergren@1095: } lagergren@1095: for (var key in arr2) { lagergren@1095: print(key + ":" + arr2[key]); lagergren@1095: } lagergren@1095: lagergren@1095: //issues reported by sundar - generic setter doesn't go through push/pop bulkable lagergren@1095: lagergren@1095: function sundarExample2(arr, _writable) { lagergren@1095: print("Checking if push works for bulkable non bulkable arrays - Setting length property not allowed"); lagergren@1095: arr[0] = "bar"; lagergren@1095: print(arr.length + " should be 1"); // should be 1 lagergren@1095: print(arr[0] + " should be bar"); lagergren@1095: print("["+ arr + "] should be [bar]"); lagergren@1095: lagergren@1095: // Object.defineProperty(arr, "length", { configurable: _writable }); lagergren@1095: Object.defineProperty(arr, "length", { writable: _writable }); lagergren@1095: arr[1] = "baz"; lagergren@1095: lagergren@1095: if (_writable) { lagergren@1095: print(arr.length + " should be 2"); lagergren@1095: print(arr[0] + " should be bar"); lagergren@1095: print(arr[1] + " should be baz"); lagergren@1095: print("["+ arr + "] should be [bar,baz]"); lagergren@1095: } else { lagergren@1095: print(arr.length + " should STILL be 1"); lagergren@1095: print(arr[0] + " should be bar"); lagergren@1095: print(arr[1] + " should be baz"); lagergren@1095: print("["+ arr + "] should be [bar]"); lagergren@1095: } lagergren@1095: } lagergren@1095: lagergren@1095: var newArr1 = []; lagergren@1095: sundarExample2(newArr1, false); lagergren@1095: print(); lagergren@1095: try { lagergren@1095: sundarExample2(newArr1, true); lagergren@1095: print("should not get here"); lagergren@1095: } catch (e) { lagergren@1095: if (!(e instanceof TypeError)) { lagergren@1095: print("Wrong exception"); lagergren@1095: } lagergren@1095: print("got TypeError when redefining length, as expected") lagergren@1095: } lagergren@1095: print(); lagergren@1095: lagergren@1095: sundarExample2([], true); lagergren@1095: print("Done");