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;
27
28 import java.util.AbstractList;
29 import java.util.Deque;
30 import java.util.Iterator;
31 import java.util.ListIterator;
32 import java.util.NoSuchElementException;
33 import java.util.RandomAccess;
34 import java.util.concurrent.Callable;
35 import jdk.nashorn.api.scripting.JSObject;
36 import jdk.nashorn.internal.runtime.linker.Bootstrap;
37 import jdk.nashorn.internal.runtime.linker.InvokeByName;
38
39 /**
40 * An adapter that can wrap any ECMAScript Array-like object (that adheres to the array rules for the property
41 * {@code length} and having conforming {@code push}, {@code pop}, {@code shift}, {@code unshift}, and {@code splice}
42 * methods) and expose it as both a Java list and double-ended queue. While script arrays aren't necessarily efficient
43 * as dequeues, it's still slightly more efficient to be able to translate dequeue operations into pushes, pops, shifts,
44 * and unshifts, than to blindly translate all list's add/remove operations into splices. Also, it is conceivable that a
45 * custom script object that implements an Array-like API can have a background data representation that is optimized
46 * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@code pop} operate at the end of the
47 * array, while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue
48 * {@link #push(Object)} and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script
49 * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and
50 * {@code pop}.
51 */
52 public abstract class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
53 // These add to the back and front of the list
54 private static final Object PUSH = new Object();
55 private static InvokeByName getPUSH() {
118 }
119 });
120 }
121
122 /** wrapped object */
123 protected final Object obj;
124
125 // allow subclasses only in this package
126 ListAdapter(final Object obj) {
127 this.obj = obj;
128 }
129
130 /**
131 * Factory to create a ListAdapter for a given script object.
132 *
133 * @param obj script object to wrap as a ListAdapter
134 * @return A ListAdapter wrapper object
135 */
136 public static ListAdapter create(final Object obj) {
137 if (obj instanceof ScriptObject) {
138 return new ScriptObjectListAdapter((ScriptObject)obj);
139 } else if (obj instanceof JSObject) {
140 return new JSObjectListAdapter((JSObject)obj);
141 } else {
142 throw new IllegalArgumentException("ScriptObject or JSObject expected");
143 }
144 }
145
146 @Override
147 public final Object get(final int index) {
148 checkRange(index);
149 return getAt(index);
150 }
151
152 /**
153 * Get object at an index
154 * @param index index in list
155 * @return object
156 */
157 protected abstract Object getAt(final int index);
158
|
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;
27
28 import java.util.AbstractList;
29 import java.util.Deque;
30 import java.util.Iterator;
31 import java.util.ListIterator;
32 import java.util.NoSuchElementException;
33 import java.util.RandomAccess;
34 import java.util.concurrent.Callable;
35 import jdk.nashorn.api.scripting.JSObject;
36 import jdk.nashorn.api.scripting.ScriptObjectMirror;
37 import jdk.nashorn.internal.runtime.linker.Bootstrap;
38 import jdk.nashorn.internal.runtime.linker.InvokeByName;
39
40 /**
41 * An adapter that can wrap any ECMAScript Array-like object (that adheres to the array rules for the property
42 * {@code length} and having conforming {@code push}, {@code pop}, {@code shift}, {@code unshift}, and {@code splice}
43 * methods) and expose it as both a Java list and double-ended queue. While script arrays aren't necessarily efficient
44 * as dequeues, it's still slightly more efficient to be able to translate dequeue operations into pushes, pops, shifts,
45 * and unshifts, than to blindly translate all list's add/remove operations into splices. Also, it is conceivable that a
46 * custom script object that implements an Array-like API can have a background data representation that is optimized
47 * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@code pop} operate at the end of the
48 * array, while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue
49 * {@link #push(Object)} and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script
50 * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and
51 * {@code pop}.
52 */
53 public abstract class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
54 // These add to the back and front of the list
55 private static final Object PUSH = new Object();
56 private static InvokeByName getPUSH() {
119 }
120 });
121 }
122
123 /** wrapped object */
124 protected final Object obj;
125
126 // allow subclasses only in this package
127 ListAdapter(final Object obj) {
128 this.obj = obj;
129 }
130
131 /**
132 * Factory to create a ListAdapter for a given script object.
133 *
134 * @param obj script object to wrap as a ListAdapter
135 * @return A ListAdapter wrapper object
136 */
137 public static ListAdapter create(final Object obj) {
138 if (obj instanceof ScriptObject) {
139 final Object mirror = ScriptObjectMirror.wrap(obj, Context.getGlobal());
140 return new JSObjectListAdapter((JSObject)mirror);
141 } else if (obj instanceof JSObject) {
142 return new JSObjectListAdapter((JSObject)obj);
143 } else {
144 throw new IllegalArgumentException("ScriptObject or JSObject expected");
145 }
146 }
147
148 @Override
149 public final Object get(final int index) {
150 checkRange(index);
151 return getAt(index);
152 }
153
154 /**
155 * Get object at an index
156 * @param index index in list
157 * @return object
158 */
159 protected abstract Object getAt(final int index);
160
|