📄 arrayprototype.cpp
字号:
if (begin < 0) begin = 0; } double end; if (args.at(exec, 1).isUndefined()) end = length; else { end = args.at(exec, 1).toInteger(exec); if (end < 0) { end += length; if (end < 0) end = 0; } else { if (end > length) end = length; } } int n = 0; int b = static_cast<int>(begin); int e = static_cast<int>(end); for (int k = b; k < e; k++, n++) { if (JSValuePtr v = getProperty(exec, thisObj, k)) resObj->put(exec, n, v); } resObj->setLength(n); return result;}JSValuePtr arrayProtoFuncSort(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ JSObject* thisObj = thisValue.toThisObject(exec); JSValuePtr function = args.at(exec, 0); CallData callData; CallType callType = function.getCallData(callData); if (thisObj->classInfo() == &JSArray::info) { if (isNumericCompareFunction(callType, callData)) asArray(thisObj)->sortNumeric(exec, function, callType, callData); else if (callType != CallTypeNone) asArray(thisObj)->sort(exec, function, callType, callData); else asArray(thisObj)->sort(exec); return thisObj; } unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (!length) return thisObj; // "Min" sort. Not the fastest, but definitely less code than heapsort // or quicksort, and much less swapping than bubblesort/insertionsort. for (unsigned i = 0; i < length - 1; ++i) { JSValuePtr iObj = thisObj->get(exec, i); unsigned themin = i; JSValuePtr minObj = iObj; for (unsigned j = i + 1; j < length; ++j) { JSValuePtr jObj = thisObj->get(exec, j); double compareResult; if (jObj.isUndefined()) compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1) else if (minObj.isUndefined()) compareResult = -1; else if (callType != CallTypeNone) { ArgList l; l.append(jObj); l.append(minObj); compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l).toNumber(exec); } else compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1; if (compareResult < 0) { themin = j; minObj = jObj; } } // Swap themin and i if (themin > i) { thisObj->put(exec, i, minObj); thisObj->put(exec, themin, iObj); } } return thisObj;}JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ JSObject* thisObj = thisValue.toThisObject(exec); // 15.4.4.12 JSArray* resObj = constructEmptyArray(exec); JSValuePtr result = resObj; unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (!args.size()) return jsUndefined(); int begin = args.at(exec, 0).toUInt32(exec); if (begin < 0) begin = std::max<int>(begin + length, 0); else begin = std::min<int>(begin, length); unsigned deleteCount; if (args.size() > 1) deleteCount = std::min<int>(std::max<int>(args.at(exec, 1).toUInt32(exec), 0), length - begin); else deleteCount = length - begin; for (unsigned k = 0; k < deleteCount; k++) { if (JSValuePtr v = getProperty(exec, thisObj, k + begin)) resObj->put(exec, k, v); } resObj->setLength(deleteCount); unsigned additionalArgs = std::max<int>(args.size() - 2, 0); if (additionalArgs != deleteCount) { if (additionalArgs < deleteCount) { for (unsigned k = begin; k < length - deleteCount; ++k) { if (JSValuePtr v = getProperty(exec, thisObj, k + deleteCount)) thisObj->put(exec, k + additionalArgs, v); else thisObj->deleteProperty(exec, k + additionalArgs); } for (unsigned k = length; k > length - deleteCount + additionalArgs; --k) thisObj->deleteProperty(exec, k - 1); } else { for (unsigned k = length - deleteCount; (int)k > begin; --k) { if (JSValuePtr obj = getProperty(exec, thisObj, k + deleteCount - 1)) thisObj->put(exec, k + additionalArgs - 1, obj); else thisObj->deleteProperty(exec, k + additionalArgs - 1); } } } for (unsigned k = 0; k < additionalArgs; ++k) thisObj->put(exec, k + begin, args.at(exec, k + 2)); putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs)); return result;}JSValuePtr arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ JSObject* thisObj = thisValue.toThisObject(exec); // 15.4.4.13 unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); unsigned nrArgs = args.size(); if (nrArgs) { for (unsigned k = length; k > 0; --k) { if (JSValuePtr v = getProperty(exec, thisObj, k - 1)) thisObj->put(exec, k + nrArgs - 1, v); else thisObj->deleteProperty(exec, k + nrArgs - 1); } } for (unsigned k = 0; k < nrArgs; ++k) thisObj->put(exec, k, args.at(exec, k)); JSValuePtr result = jsNumber(exec, length + nrArgs); putProperty(exec, thisObj, exec->propertyNames().length, result); return result;}JSValuePtr arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ JSObject* thisObj = thisValue.toThisObject(exec); JSValuePtr function = args.at(exec, 0); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return throwError(exec, TypeError); JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec); JSArray* resultArray = constructEmptyArray(exec); unsigned filterIndex = 0; unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); for (unsigned k = 0; k < length && !exec->hadException(); ++k) { PropertySlot slot(thisObj); if (!thisObj->getPropertySlot(exec, k, slot)) continue; JSValuePtr v = slot.getValue(exec, k); ArgList eachArguments; eachArguments.append(v); eachArguments.append(jsNumber(exec, k)); eachArguments.append(thisObj); JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments); if (result.toBoolean(exec)) resultArray->put(exec, filterIndex++, v); } return resultArray;}JSValuePtr arrayProtoFuncMap(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ JSObject* thisObj = thisValue.toThisObject(exec); JSValuePtr function = args.at(exec, 0); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return throwError(exec, TypeError); JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec); unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); JSArray* resultArray = constructEmptyArray(exec, length); for (unsigned k = 0; k < length && !exec->hadException(); ++k) { PropertySlot slot(thisObj); if (!thisObj->getPropertySlot(exec, k, slot)) continue; JSValuePtr v = slot.getValue(exec, k); ArgList eachArguments; eachArguments.append(v); eachArguments.append(jsNumber(exec, k)); eachArguments.append(thisObj); JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments); resultArray->put(exec, k, result); } return resultArray;}// Documentation for these three is available at:// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:someJSValuePtr arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ JSObject* thisObj = thisValue.toThisObject(exec); JSValuePtr function = args.at(exec, 0); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return throwError(exec, TypeError); JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec); JSValuePtr result = jsBoolean(true); unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); for (unsigned k = 0; k < length && !exec->hadException(); ++k) { PropertySlot slot(thisObj); if (!thisObj->getPropertySlot(exec, k, slot)) continue; ArgList eachArguments; eachArguments.append(slot.getValue(exec, k)); eachArguments.append(jsNumber(exec, k)); eachArguments.append(thisObj); bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec); if (!predicateResult) { result = jsBoolean(false); break; } } return result;}JSValuePtr arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ JSObject* thisObj = thisValue.toThisObject(exec); JSValuePtr function = args.at(exec, 0); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return throwError(exec, TypeError); JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec); unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); for (unsigned k = 0; k < length && !exec->hadException(); ++k) { PropertySlot slot(thisObj); if (!thisObj->getPropertySlot(exec, k, slot)) continue; ArgList eachArguments; eachArguments.append(slot.getValue(exec, k)); eachArguments.append(jsNumber(exec, k)); eachArguments.append(thisObj); call(exec, function, callType, callData, applyThis, eachArguments); } return jsUndefined();}JSValuePtr arrayProtoFuncSome(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ JSObject* thisObj = thisValue.toThisObject(exec); JSValuePtr function = args.at(exec, 0); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return throwError(exec, TypeError); JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec); JSValuePtr result = jsBoolean(false); unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); for (unsigned k = 0; k < length && !exec->hadException(); ++k) { PropertySlot slot(thisObj); if (!thisObj->getPropertySlot(exec, k, slot)) continue; ArgList eachArguments; eachArguments.append(slot.getValue(exec, k)); eachArguments.append(jsNumber(exec, k)); eachArguments.append(thisObj); bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec); if (predicateResult) { result = jsBoolean(true); break; } } return result;}JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ // JavaScript 1.5 Extension by Mozilla // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf JSObject* thisObj = thisValue.toThisObject(exec); unsigned index = 0; double d = args.at(exec, 1).toInteger(exec); unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (d < 0) d += length; if (d > 0) { if (d > length) index = length; else index = static_cast<unsigned>(d); } JSValuePtr searchElement = args.at(exec, 0); for (; index < length; ++index) { JSValuePtr e = getProperty(exec, thisObj, index); if (!e) continue; if (JSValuePtr::strictEqual(searchElement, e)) return jsNumber(exec, index); } return jsNumber(exec, -1);}JSValuePtr arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ // JavaScript 1.6 Extension by Mozilla // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf JSObject* thisObj = thisValue.toThisObject(exec); unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); int index = length - 1; double d = args.at(exec, 1).toIntegerPreserveNaN(exec); if (d < 0) { d += length; if (d < 0) return jsNumber(exec, -1); } if (d < length) index = static_cast<int>(d); JSValuePtr searchElement = args.at(exec, 0); for (; index >= 0; --index) { JSValuePtr e = getProperty(exec, thisObj, index); if (!e) continue; if (JSValuePtr::strictEqual(searchElement, e)) return jsNumber(exec, index); } return jsNumber(exec, -1);}} // namespace JSC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -