📄 nativearray.java
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Mike McCabe * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.javascript;import java.util.Arrays;/** * This class implements the Array native object. * @author Norris Boyd * @author Mike McCabe */public class NativeArray extends IdScriptableObject{ static final long serialVersionUID = 7331366857676127338L; /* * Optimization possibilities and open issues: * - Long vs. double schizophrenia. I suspect it might be better * to use double throughout. * * - Functions that need a new Array call "new Array" in the * current scope rather than using a hardwired constructor; * "Array" could be redefined. It turns out that js calls the * equivalent of "new Array" in the current scope, except that it * always gets at least an object back, even when Array == null. */ private static final Object ARRAY_TAG = new Object(); private static final Integer NEGATIVE_ONE = new Integer(-1); static void init(Scriptable scope, boolean sealed) { NativeArray obj = new NativeArray(0); obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } static int getMaximumInitialCapacity() { return maximumInitialCapacity; } static void setMaximumInitialCapacity(int maximumInitialCapacity) { NativeArray.maximumInitialCapacity = maximumInitialCapacity; } public NativeArray(long lengthArg) { denseOnly = lengthArg <= maximumInitialCapacity; if (denseOnly) { int intLength = (int) lengthArg; if (intLength < DEFAULT_INITIAL_CAPACITY) intLength = DEFAULT_INITIAL_CAPACITY; dense = new Object[intLength]; Arrays.fill(dense, Scriptable.NOT_FOUND); } length = lengthArg; } public NativeArray(Object[] array) { denseOnly = true; dense = array; length = array.length; } public String getClassName() { return "Array"; } private static final int Id_length = 1, MAX_INSTANCE_ID = 1; protected int getMaxInstanceId() { return MAX_INSTANCE_ID; } protected int findInstanceIdInfo(String s) { if (s.equals("length")) { return instanceIdInfo(DONTENUM | PERMANENT, Id_length); } return super.findInstanceIdInfo(s); } protected String getInstanceIdName(int id) { if (id == Id_length) { return "length"; } return super.getInstanceIdName(id); } protected Object getInstanceIdValue(int id) { if (id == Id_length) { return ScriptRuntime.wrapNumber(length); } return super.getInstanceIdValue(id); } protected void setInstanceIdValue(int id, Object value) { if (id == Id_length) { setLength(value); return; } super.setInstanceIdValue(id, value); } protected void fillConstructorProperties(IdFunctionObject ctor) { addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_join, "join", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_reverse, "reverse", 1); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_sort, "sort", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_push, "push", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_pop, "pop", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_shift, "shift", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_unshift, "unshift", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_splice, "splice", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_concat, "concat", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_slice, "slice", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_indexOf, "indexOf", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_lastIndexOf, "lastIndexOf", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_every, "every", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_filter, "filter", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_forEach, "forEach", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_map, "map", 2); addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_some, "some", 2); super.fillConstructorProperties(ctor); } protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_constructor: arity=1; s="constructor"; break; case Id_toString: arity=0; s="toString"; break; case Id_toLocaleString: arity=1; s="toLocaleString"; break; case Id_toSource: arity=0; s="toSource"; break; case Id_join: arity=1; s="join"; break; case Id_reverse: arity=0; s="reverse"; break; case Id_sort: arity=1; s="sort"; break; case Id_push: arity=1; s="push"; break; case Id_pop: arity=1; s="pop"; break; case Id_shift: arity=1; s="shift"; break; case Id_unshift: arity=1; s="unshift"; break; case Id_splice: arity=1; s="splice"; break; case Id_concat: arity=1; s="concat"; break; case Id_slice: arity=1; s="slice"; break; case Id_indexOf: arity=1; s="indexOf"; break; case Id_lastIndexOf: arity=1; s="lastIndexOf"; break; case Id_every: arity=1; s="every"; break; case Id_filter: arity=1; s="filter"; break; case Id_forEach: arity=1; s="forEach"; break; case Id_map: arity=1; s="map"; break; case Id_some: arity=1; s="some"; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(ARRAY_TAG, id, s, arity); } public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(ARRAY_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); again: for (;;) { switch (id) { case ConstructorId_join: case ConstructorId_reverse: case ConstructorId_sort: case ConstructorId_push: case ConstructorId_pop: case ConstructorId_shift: case ConstructorId_unshift: case ConstructorId_splice: case ConstructorId_concat: case ConstructorId_slice: case ConstructorId_indexOf: case ConstructorId_lastIndexOf: case ConstructorId_every: case ConstructorId_filter: case ConstructorId_forEach: case ConstructorId_map: case ConstructorId_some: { thisObj = ScriptRuntime.toObject(scope, args[0]); Object[] newArgs = new Object[args.length-1]; for (int i=0; i < newArgs.length; i++) newArgs[i] = args[i+1]; args = newArgs; id = -id; continue again; } case Id_constructor: { boolean inNewExpr = (thisObj == null); if (!inNewExpr) { // IdFunctionObject.construct will set up parent, proto return f.construct(cx, scope, args); } return jsConstructor(cx, scope, args); } case Id_toString: return toStringHelper(cx, scope, thisObj, cx.hasFeature(Context.FEATURE_TO_STRING_AS_SOURCE), false); case Id_toLocaleString: return toStringHelper(cx, scope, thisObj, false, true); case Id_toSource: return toStringHelper(cx, scope, thisObj, true, false); case Id_join: return js_join(cx, thisObj, args); case Id_reverse: return js_reverse(cx, thisObj, args); case Id_sort: return js_sort(cx, scope, thisObj, args); case Id_push: return js_push(cx, thisObj, args); case Id_pop: return js_pop(cx, thisObj, args); case Id_shift: return js_shift(cx, thisObj, args); case Id_unshift: return js_unshift(cx, thisObj, args); case Id_splice: return js_splice(cx, scope, thisObj, args); case Id_concat: return js_concat(cx, scope, thisObj, args); case Id_slice: return js_slice(cx, thisObj, args); case Id_indexOf: return indexOfHelper(cx, thisObj, args, false); case Id_lastIndexOf: return indexOfHelper(cx, thisObj, args, true); case Id_every: case Id_filter: case Id_forEach: case Id_map: case Id_some: return iterativeMethod(cx, id, scope, thisObj, args); } throw new IllegalArgumentException(String.valueOf(id)); } } public Object get(int index, Scriptable start) { if (!denseOnly && isGetterOrSetter(null, index, false)) return super.get(index, start); if (dense != null && 0 <= index && index < dense.length) return dense[index]; return super.get(index, start); } public boolean has(int index, Scriptable start) { if (!denseOnly && isGetterOrSetter(null, index, false)) return super.has(index, start); if (dense != null && 0 <= index && index < dense.length) return dense[index] != NOT_FOUND; return super.has(index, start); } // if id is an array index (ECMA 15.4.0), return the number, // otherwise return -1L private static long toArrayIndex(String id) { double d = ScriptRuntime.toNumber(id); if (d == d) { long index = ScriptRuntime.toUint32(d); if (index == d && index != 4294967295L) { // Assume that ScriptRuntime.toString(index) is the same // as java.lang.Long.toString(index) for long
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -