1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nashorn.internal.runtime.arrays;
  27 
  28 import jdk.nashorn.internal.codegen.types.Type;
  29 import jdk.nashorn.internal.runtime.ScriptRuntime;
  30 import jdk.nashorn.internal.runtime.Undefined;
  31 import jdk.nashorn.internal.runtime.linker.Bootstrap;
  32 
  33 /**
  34  * Base class for array filters. Implements all core routines so that the
  35  * filter only has to implement those needed.
  36  */
  37 abstract class ArrayFilter extends ArrayData {
  38     /** Underlying array. */
  39     protected ArrayData underlying;
  40 
  41     ArrayFilter(final ArrayData underlying) {
  42         super(underlying.length());
  43         this.underlying = underlying;
  44     }
  45 
  46     /**
  47      * Get the underlying {@link ArrayData} that this filter wraps
  48      * @return array data
  49      */
  50     protected ArrayData getUnderlying() {
  51         return underlying;
  52     }
  53 
  54     @Override
  55     public void setLength(final long length) {
  56         super.setLength(length);
  57         underlying.setLength(length);
  58     }
  59 
  60     @Override
  61     public Object[] asObjectArray() {
  62         return underlying.asObjectArray();
  63     }
  64 
  65     @Override
  66     public Object asArrayOfType(final Class<?> componentType) {
  67         return underlying.asArrayOfType(componentType);
  68     }
  69 
  70     @Override
  71     public ArrayData shiftLeft(final int by) {
  72         underlying.shiftLeft(by);
  73         setLength(underlying.length());
  74         return this;
  75     }
  76 
  77     @Override
  78     public ArrayData shiftRight(final int by) {
  79         underlying = underlying.shiftRight(by);
  80         setLength(underlying.length());
  81         return this;
  82     }
  83 
  84     @Override
  85     public ArrayData ensure(final long safeIndex) {
  86         underlying = underlying.ensure(safeIndex);
  87         setLength(underlying.length());
  88         return this;
  89     }
  90 
  91     @Override
  92     public ArrayData shrink(final long newLength) {
  93         underlying = underlying.shrink(newLength);
  94         setLength(underlying.length());
  95         return this;
  96     }
  97 
  98     @Override
  99     public ArrayData set(final int index, final Object value, final boolean strict) {
 100         underlying = underlying.set(index, value, strict);
 101         setLength(underlying.length());
 102         return this;
 103     }
 104 
 105     @Override
 106     public ArrayData set(final int index, final int value, final boolean strict) {
 107         underlying = underlying.set(index, value, strict);
 108         setLength(underlying.length());
 109         return this;
 110     }
 111 
 112     @Override
 113     public ArrayData set(final int index, final double value, final boolean strict) {
 114         underlying = underlying.set(index, value, strict);
 115         setLength(underlying.length());
 116         return this;
 117     }
 118 
 119     @Override
 120     public ArrayData setEmpty(final int index) {
 121         underlying.setEmpty(index);
 122         return this;
 123     }
 124 
 125     @Override
 126     public ArrayData setEmpty(final long lo, final long hi) {
 127         underlying.setEmpty(lo, hi);
 128         return this;
 129     }
 130 
 131     @Override
 132     public Type getOptimisticType() {
 133         return underlying.getOptimisticType();
 134     }
 135 
 136     @Override
 137     public int getInt(final int index) {
 138         return underlying.getInt(index);
 139     }
 140 
 141     @Override
 142     public int getIntOptimistic(final int index, final int programPoint) {
 143         return underlying.getIntOptimistic(index, programPoint);
 144     }
 145 
 146     @Override
 147     public double getDouble(final int index) {
 148         return underlying.getDouble(index);
 149     }
 150 
 151     @Override
 152     public double getDoubleOptimistic(final int index, final int programPoint) {
 153         return underlying.getDoubleOptimistic(index, programPoint);
 154     }
 155 
 156     @Override
 157     public Object getObject(final int index) {
 158         return underlying.getObject(index);
 159     }
 160 
 161     @Override
 162     public boolean has(final int index) {
 163         return underlying.has(index);
 164     }
 165 
 166     @Override
 167     public ArrayData delete(final int index) {
 168         underlying = underlying.delete(index);
 169         setLength(underlying.length());
 170         return this;
 171     }
 172 
 173     @Override
 174     public ArrayData delete(final long from, final long to) {
 175         underlying = underlying.delete(from, to);
 176         setLength(underlying.length());
 177         return this;
 178     }
 179 
 180     @Override
 181     public ArrayData convert(final Class<?> type) {
 182         underlying = underlying.convert(type);
 183         setLength(underlying.length());
 184         return this;
 185     }
 186 
 187     @Override
 188     public Object pop() {
 189         final Object value = underlying.pop();
 190         setLength(underlying.length());
 191         return value;
 192     }
 193 
 194     @Override
 195     public long nextIndex(final long index) {
 196         return underlying.nextIndex(index);
 197     }
 198 
 199     static Object convertUndefinedValue(final Class<?> targetType) {
 200         return invoke(Bootstrap.getLinkerServices().getTypeConverter(Undefined.class, targetType),
 201                 ScriptRuntime.UNDEFINED);
 202     }
 203 }