UndefinedArrayFilter.java revision 1101:be3f5ca1edbf
1231990Smp/* 259243Sobrien * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 359243Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 459243Sobrien * 559243Sobrien * This code is free software; you can redistribute it and/or modify it 659243Sobrien * under the terms of the GNU General Public License version 2 only, as 759243Sobrien * published by the Free Software Foundation. Oracle designates this 859243Sobrien * particular file as subject to the "Classpath" exception as provided 959243Sobrien * by Oracle in the LICENSE file that accompanied this code. 1059243Sobrien * 1159243Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT 1259243Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1359243Sobrien * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1459243Sobrien * version 2 for more details (a copy is included in the LICENSE file that 1559243Sobrien * accompanied this code). 1659243Sobrien * 17100616Smp * You should have received a copy of the GNU General Public License version 1859243Sobrien * 2 along with this work; if not, write to the Free Software Foundation, 1959243Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2059243Sobrien * 2159243Sobrien * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2259243Sobrien * or visit www.oracle.com if you need additional information or have any 2359243Sobrien * questions. 2459243Sobrien */ 2559243Sobrien 2659243Sobrienpackage jdk.nashorn.internal.runtime.arrays; 2759243Sobrien 2859243Sobrienimport static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 2959243Sobrienimport java.lang.reflect.Array; 3059243Sobrienimport jdk.nashorn.internal.runtime.BitVector; 3159243Sobrienimport jdk.nashorn.internal.runtime.UnwarrantedOptimismException; 3259243Sobrien 3359243Sobrien/** 3459243Sobrien * This filter handles the presence of undefined array elements. 35231990Smp */ 3659243Sobrienfinal class UndefinedArrayFilter extends ArrayFilter { 3759243Sobrien /** Bit vector tracking undefines. */ 3859243Sobrien private final BitVector undefined; 3959243Sobrien 4059243Sobrien UndefinedArrayFilter(final ArrayData underlying) { 4169408Sache super(underlying); 4259243Sobrien this.undefined = new BitVector(underlying.length()); 43167465Smp } 44167465Smp 4569408Sache @Override 4659243Sobrien public ArrayData copy() { 4759243Sobrien final UndefinedArrayFilter copy = new UndefinedArrayFilter(underlying.copy()); 4859243Sobrien copy.getUndefined().copy(undefined); 4959243Sobrien return copy; 5059243Sobrien } 5159243Sobrien 5259243Sobrien @Override 5359243Sobrien public Object[] asObjectArray() { 5459243Sobrien final Object[] value = super.asObjectArray(); 5559243Sobrien 5659243Sobrien for (int i = 0; i < value.length; i++) { 5759243Sobrien if (undefined.isSet(i)) { 58145479Smp value[i] = UNDEFINED; 59145479Smp } 60145479Smp } 61145479Smp 62145479Smp return value; 63145479Smp } 64167465Smp 6559243Sobrien @Override 66167465Smp public Object asArrayOfType(final Class<?> componentType) { 67167465Smp final Object value = super.asArrayOfType(componentType); 68167465Smp final Object undefValue = convertUndefinedValue(componentType); 6959243Sobrien final int l = Array.getLength(value); 70167465Smp for (int i = 0; i < l; i++) { 71167465Smp if (undefined.isSet(i)) { 72167465Smp Array.set(value, i,undefValue); 7359243Sobrien } 74167465Smp } 75167465Smp 7659243Sobrien return value; 77167465Smp } 78167465Smp 7959243Sobrien @Override 8059243Sobrien public void shiftLeft(final int by) { 8159243Sobrien super.shiftLeft(by); 8259243Sobrien undefined.shiftLeft(by, length()); 8359243Sobrien } 8459243Sobrien 8559243Sobrien @Override 86167465Smp public ArrayData shiftRight(final int by) { 87167465Smp super.shiftRight(by); 88167465Smp undefined.shiftRight(by, length()); 8961524Sobrien return this; 9061524Sobrien } 9161524Sobrien 9261524Sobrien @Override 9361524Sobrien public ArrayData ensure(final long safeIndex) { 9459243Sobrien if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) { 9559243Sobrien return new SparseArrayData(this, safeIndex + 1); 9659243Sobrien } 9759243Sobrien 9859243Sobrien super.ensure(safeIndex); 99167465Smp undefined.resize(length()); 10059243Sobrien 101167465Smp return this; 102167465Smp } 103167465Smp 104145479Smp @Override 105145479Smp public ArrayData shrink(final long newLength) { 10659243Sobrien super.shrink(newLength); 10759243Sobrien undefined.resize(length()); 10859243Sobrien return this; 109167465Smp } 110167465Smp 11159243Sobrien @Override 112167465Smp public ArrayData set(final int index, final Object value, final boolean strict) { 11359243Sobrien undefined.clear(index); 114167465Smp 11559243Sobrien if (value == UNDEFINED) { 11659243Sobrien undefined.set(index); 11759243Sobrien return this; 11859243Sobrien } 11959243Sobrien 12059243Sobrien return super.set(index, value, strict); 121231990Smp } 12259243Sobrien 12359243Sobrien @Override 12459243Sobrien public ArrayData set(final int index, final int value, final boolean strict) { 125167465Smp undefined.clear(index); 12659243Sobrien 127167465Smp return super.set(index, value, strict); 12859243Sobrien } 12959243Sobrien 130167465Smp @Override 13159243Sobrien public ArrayData set(final int index, final long value, final boolean strict) { 13259243Sobrien undefined.clear(index); 13359243Sobrien 13459243Sobrien return super.set(index, value, strict); 13559243Sobrien } 136167465Smp 137167465Smp @Override 13859243Sobrien public ArrayData set(final int index, final double value, final boolean strict) { 139167465Smp undefined.clear(index); 14059243Sobrien 14159243Sobrien return super.set(index, value, strict); 14259243Sobrien } 143167465Smp 14459243Sobrien @Override 145167465Smp public int getInt(final int index) { 14659243Sobrien if (undefined.isSet(index)) { 14759243Sobrien return 0; 14859243Sobrien } 14959243Sobrien 150167465Smp return super.getInt(index); 15159243Sobrien } 15259243Sobrien 15359243Sobrien @Override 15459243Sobrien public int getIntOptimistic(final int index, final int programPoint) { 15559243Sobrien if (undefined.isSet(index)) { 15659243Sobrien throw new UnwarrantedOptimismException(UNDEFINED, programPoint); 15759243Sobrien } 15859243Sobrien 15959243Sobrien return super.getIntOptimistic(index, programPoint); 16059243Sobrien } 16159243Sobrien 162167465Smp @Override 16359243Sobrien public long getLong(final int index) { 16459243Sobrien if (undefined.isSet(index)) { 16559243Sobrien return 0L; 166167465Smp } 16759243Sobrien 16859243Sobrien return super.getLong(index); 16959243Sobrien } 170167465Smp 17159243Sobrien @Override 17259243Sobrien public long getLongOptimistic(final int index, final int programPoint) { 17359243Sobrien if (undefined.isSet(index)) { 17459243Sobrien throw new UnwarrantedOptimismException(UNDEFINED, programPoint); 17559243Sobrien } 17659243Sobrien 177231990Smp return super.getLongOptimistic(index, programPoint); 17859243Sobrien } 179167465Smp 180167465Smp @Override 181167465Smp public double getDouble(final int index) { 182167465Smp if (undefined.isSet(index)) { 18359243Sobrien return Double.NaN; 18459243Sobrien } 18559243Sobrien 18659243Sobrien return super.getDouble(index); 187167465Smp } 18859243Sobrien 18959243Sobrien @Override 19059243Sobrien public double getDoubleOptimistic(final int index, final int programPoint) { 19159243Sobrien if (undefined.isSet(index)) { 19259243Sobrien throw new UnwarrantedOptimismException(UNDEFINED, programPoint); 193167465Smp } 19459243Sobrien 195167465Smp return super.getDoubleOptimistic(index, programPoint); 19659243Sobrien } 19759243Sobrien 19859243Sobrien @Override 19959243Sobrien public Object getObject(final int index) { 20059243Sobrien if (undefined.isSet(index)) { 201167465Smp return UNDEFINED; 202167465Smp } 203167465Smp 204167465Smp return super.getObject(index); 205167465Smp } 206167465Smp 20759243Sobrien @Override 20859243Sobrien public ArrayData delete(final int index) { 209167465Smp undefined.clear(index); 210167465Smp 211167465Smp return super.delete(index); 21259243Sobrien } 21359243Sobrien 21459243Sobrien @Override 21559243Sobrien public Object pop() { 21659243Sobrien final long index = length() - 1; 21759243Sobrien 21859243Sobrien if (super.has((int)index)) { 21959243Sobrien final boolean isUndefined = undefined.isSet(index); 22059243Sobrien final Object value = super.pop(); 22159243Sobrien 22259243Sobrien return isUndefined ? UNDEFINED : value; 22359243Sobrien } 224167465Smp 225167465Smp return super.pop(); 226167465Smp } 227167465Smp 22859243Sobrien @Override 229167465Smp public ArrayData slice(final long from, final long to) { 23059243Sobrien final ArrayData newArray = underlying.slice(from, to); 23159243Sobrien final UndefinedArrayFilter newFilter = new UndefinedArrayFilter(newArray); 23259243Sobrien newFilter.getUndefined().copy(undefined); 23359243Sobrien newFilter.getUndefined().shiftLeft(from, newFilter.length()); 23459243Sobrien 23559243Sobrien return newFilter; 23659243Sobrien } 23759243Sobrien 238100616Smp private BitVector getUndefined() { 239100616Smp return undefined; 24059243Sobrien } 24159243Sobrien} 24259243Sobrien