📄 nativearray.java
字号:
} return ScriptRuntime.wrapNumber(na.length); } } long length = getLengthProperty(cx, thisObj); for (int i = 0; i < args.length; i++) { setElem(cx, thisObj, length + i, args[i]); } length += args.length; Object lengthObj = setLengthProperty(cx, thisObj, length); /* * If JS1.2, follow Perl4 by returning the last thing pushed. * Otherwise, return the new array length. */ if (cx.getLanguageVersion() == Context.VERSION_1_2) // if JS1.2 && no arguments, return undefined. return args.length == 0 ? Undefined.instance : args[args.length - 1]; else return lengthObj; } private static Object js_pop(Context cx, Scriptable thisObj, Object[] args) { Object result; if (thisObj instanceof NativeArray) { NativeArray na = (NativeArray) thisObj; if (na.denseOnly && na.length > 0) { na.length--; result = na.dense[(int)na.length]; na.dense[(int)na.length] = NOT_FOUND; return result; } } long length = getLengthProperty(cx, thisObj); if (length > 0) { length--; // Get the to-be-deleted property's value. result = getElem(cx, thisObj, length); // We don't need to delete the last property, because // setLength does that for us. } else { result = Undefined.instance; } // necessary to match js even when length < 0; js pop will give a // length property to any target it is called on. setLengthProperty(cx, thisObj, length); return result; } private static Object js_shift(Context cx, Scriptable thisObj, Object[] args) { if (thisObj instanceof NativeArray) { NativeArray na = (NativeArray) thisObj; if (na.denseOnly && na.length > 0) { na.length--; Object result = na.dense[0]; System.arraycopy(na.dense, 1, na.dense, 0, (int)na.length); na.dense[(int)na.length] = NOT_FOUND; return result; } } Object result; long length = getLengthProperty(cx, thisObj); if (length > 0) { long i = 0; length--; // Get the to-be-deleted property's value. result = getElem(cx, thisObj, i); /* * Slide down the array above the first element. Leave i * set to point to the last element. */ if (length > 0) { for (i = 1; i <= length; i++) { Object temp = getElem(cx, thisObj, i); setElem(cx, thisObj, i - 1, temp); } } // We don't need to delete the last property, because // setLength does that for us. } else { result = Undefined.instance; } setLengthProperty(cx, thisObj, length); return result; } private static Object js_unshift(Context cx, Scriptable thisObj, Object[] args) { if (thisObj instanceof NativeArray) { NativeArray na = (NativeArray) thisObj; if (na.denseOnly && na.ensureCapacity((int)na.length + args.length)) { System.arraycopy(na.dense, 0, na.dense, args.length, (int) na.length); for (int i = 0; i < args.length; i++) { na.dense[i] = args[i]; } na.length += args.length; return ScriptRuntime.wrapNumber(na.length); } } long length = getLengthProperty(cx, thisObj); int argc = args.length; if (args.length > 0) { /* Slide up the array to make room for args at the bottom */ if (length > 0) { for (long last = length - 1; last >= 0; last--) { Object temp = getElem(cx, thisObj, last); setElem(cx, thisObj, last + argc, temp); } } /* Copy from argv to the bottom of the array. */ for (int i = 0; i < args.length; i++) { setElem(cx, thisObj, i, args[i]); } /* Follow Perl by returning the new array length. */ length += args.length; return setLengthProperty(cx, thisObj, length); } return ScriptRuntime.wrapNumber(length); } private static Object js_splice(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { NativeArray na = null; boolean denseMode = false; if (thisObj instanceof NativeArray) { na = (NativeArray) thisObj; denseMode = na.denseOnly; } /* create an empty Array to return. */ scope = getTopLevelScope(scope); int argc = args.length; if (argc == 0) return ScriptRuntime.newObject(cx, scope, "Array", null); long length = getLengthProperty(cx, thisObj); /* Convert the first argument into a starting index. */ long begin = toSliceIndex(ScriptRuntime.toInteger(args[0]), length); argc--; /* Convert the second argument into count */ long count; if (args.length == 1) { count = length - begin; } else { double dcount = ScriptRuntime.toInteger(args[1]); if (dcount < 0) { count = 0; } else if (dcount > (length - begin)) { count = length - begin; } else { count = (long)dcount; } argc--; } long end = begin + count; /* If there are elements to remove, put them into the return value. */ Object result; if (count != 0) { if (count == 1 && (cx.getLanguageVersion() == Context.VERSION_1_2)) { /* * JS lacks "list context", whereby in Perl one turns the * single scalar that's spliced out into an array just by * assigning it to @single instead of $single, or by using it * as Perl push's first argument, for instance. * * JS1.2 emulated Perl too closely and returned a non-Array for * the single-splice-out case, requiring callers to test and * wrap in [] if necessary. So JS1.3, default, and other * versions all return an array of length 1 for uniformity. */ result = getElem(cx, thisObj, begin); } else { if (denseMode) { int intLen = (int) (end - begin); Object[] copy = new Object[intLen]; System.arraycopy(na.dense, (int) begin, copy, 0, intLen); result = cx.newArray(scope, copy); } else { Scriptable resultArray = ScriptRuntime.newObject(cx, scope, "Array", null); for (long last = begin; last != end; last++) { Object temp = getElem(cx, thisObj, last); setElem(cx, resultArray, last - begin, temp); } result = resultArray; } } } else { // (count == 0) if (cx.getLanguageVersion() == Context.VERSION_1_2) { /* Emulate C JS1.2; if no elements are removed, return undefined. */ result = Undefined.instance; } else { result = ScriptRuntime.newObject(cx, scope, "Array", null); } } /* Find the direction (up or down) to copy and make way for argv. */ long delta = argc - count; if (denseMode && length + delta < Integer.MAX_VALUE && na.ensureCapacity((int) (length + delta))) { System.arraycopy(na.dense, (int) end, na.dense, (int) (begin + argc), (int) (length - end)); if (argc > 0) { System.arraycopy(args, 2, na.dense, (int) begin, argc); } if (delta < 0) { Arrays.fill(na.dense, (int) (length + delta), (int) length, NOT_FOUND); } na.length = length + delta; return result; } if (delta > 0) { for (long last = length - 1; last >= end; last--) { Object temp = getElem(cx, thisObj, last); setElem(cx, thisObj, last + delta, temp); } } else if (delta < 0) { for (long last = end; last < length; last++) { Object temp = getElem(cx, thisObj, last); setElem(cx, thisObj, last + delta, temp); } } /* Copy from argv into the hole to complete the splice. */ int argoffset = args.length - argc; for (int i = 0; i < argc; i++) { setElem(cx, thisObj, begin + i, args[i + argoffset]); } /* Update length in case we deleted elements from the end. */ setLengthProperty(cx, thisObj, length + delta); return result; } /* * See Ecma 262v3 15.4.4.4 */ private static Scriptable js_concat(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { // create an empty Array to return. scope = getTopLevelScope(scope); Function ctor = ScriptRuntime.getExistingCtor(cx, scope, "Array"); Scriptable result = ctor.construct(cx, scope, ScriptRuntime.emptyArgs); if (thisObj instanceof NativeArray && result instanceof NativeArray) { NativeArray denseThis = (NativeArray) thisObj; NativeArray denseResult = (NativeArray) result; if (denseThis.denseOnly && denseResult.denseOnly) { // First calculate length of resulting array boolean canUseDense = true; int length = (int) denseThis.length; for (int i = 0; i < args.length && canUseDense; i++) { if (ScriptRuntime.instanceOf(args[i], ctor, cx)) { // only try to use dense approach for Array-like // objects that are actually NativeArrays canUseDense = args[i] instanceof NativeArray; length += ((NativeArray) args[i]).length; } else { length++; } } if (canUseDense && denseResult.ensureCapacity(length)) { System.arraycopy(denseThis.dense, 0, denseResult.dense, 0, (int) denseThis.length); int cursor = (int) denseThis.length; for (int i = 0; i < args.length && canUseDense; i++) { if (args[i] instanceof NativeArray) { NativeArray arg = (NativeArray) args[i]; System.arraycopy(arg.dense, 0, denseResult.dense, cursor, (int)arg.length); cursor += (int)arg.length; } else { denseResult.dense[cursor++] = args[i]; } } denseResult.length = length; return result; } } } long length; long slot = 0; /* Put the target in the result array; only add it as an array * if it looks like one. */ if (ScriptRuntime.instanceOf(thisObj, ctor, cx)) { length = getLengthProperty(cx, thisObj); // Copy from the target object into the result for (slot = 0; slot < length; slot++) { Object temp = getElem(cx, thisObj, slot); setElem(cx, result, slot, temp); } } else { setElem(cx, result, slot++, thisObj); } /* Copy from the arguments into the result. If any argument * has a numeric length property, treat it as an array and add * elements separately; otherwise, just copy the argument. */ for (int i = 0; i < args.length; i++) { if (ScriptRuntime.instanceOf(args[i], ctor, cx)) { // ScriptRuntime.instanceOf => instanceof Scriptable Scriptable arg = (Scriptable)args[i]; length = getLengthProperty(cx, arg); for (long j = 0; j < length; j++, slot++) { Object temp = getElem(cx, arg, j); setElem(cx, result, slot, temp); } } else { setElem(cx, result, slot++, args[i]); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -