source: webkit/trunk/JavaScriptCore/runtime/JSArray.cpp@ 40046

Last change on this file since 40046 was 40046, checked in by [email protected], 16 years ago

JavaScriptCore:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • API/JSCallbackFunction.cpp: (JSC::JSCallbackFunction::call):
  • API/JSCallbackObjectFunctions.h: (JSC::::call): (JSC::::toNumber): (JSC::::toString):
  • API/JSObjectRef.cpp: (JSObjectSetPrototype):
  • API/JSValueRef.cpp: (JSValueGetType): (JSValueIsUndefined): (JSValueIsNull): (JSValueIsBoolean): (JSValueIsNumber): (JSValueIsString): (JSValueIsObject): (JSValueIsObjectOfClass): (JSValueToBoolean): (JSValueToNumber): (JSValueToStringCopy): (JSValueToObject):
  • bytecode/CodeBlock.cpp: (JSC::valueToSourceString): (JSC::CodeBlock::mark):
  • bytecode/CodeBlock.h: (JSC::CodeBlock::isKnownNotImmediate):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitEqualityOp): (JSC::keyForImmediateSwitch):
  • interpreter/Interpreter.cpp: (JSC::jsLess): (JSC::jsLessEq): (JSC::jsAddSlowCase): (JSC::jsAdd): (JSC::jsTypeStringForValue): (JSC::jsIsObjectType): (JSC::jsIsFunctionType): (JSC::isNotObject): (JSC::Interpreter::callEval): (JSC::Interpreter::throwException): (JSC::cachePrototypeChain): (JSC::Interpreter::tryCachePutByID): (JSC::countPrototypeChainEntriesAndCheckForProxies): (JSC::Interpreter::tryCacheGetByID): (JSC::Interpreter::privateExecute): (JSC::Interpreter::tryCTICachePutByID): (JSC::Interpreter::tryCTICacheGetByID): (JSC::Interpreter::cti_op_convert_this): (JSC::Interpreter::cti_op_add): (JSC::Interpreter::cti_op_pre_inc): (JSC::Interpreter::cti_op_put_by_id_generic): (JSC::Interpreter::cti_op_get_by_id_generic): (JSC::Interpreter::cti_op_put_by_id): (JSC::Interpreter::cti_op_put_by_id_second): (JSC::Interpreter::cti_op_put_by_id_fail): (JSC::Interpreter::cti_op_get_by_id): (JSC::Interpreter::cti_op_get_by_id_second): (JSC::Interpreter::cti_op_get_by_id_self_fail): (JSC::Interpreter::cti_op_get_by_id_proto_list): (JSC::Interpreter::cti_op_get_by_id_proto_list_full): (JSC::Interpreter::cti_op_get_by_id_proto_fail): (JSC::Interpreter::cti_op_get_by_id_array_fail): (JSC::Interpreter::cti_op_get_by_id_string_fail): (JSC::Interpreter::cti_op_instanceof): (JSC::Interpreter::cti_op_del_by_id): (JSC::Interpreter::cti_op_mul): (JSC::Interpreter::cti_op_call_JSFunction): (JSC::Interpreter::cti_op_call_NotJSFunction): (JSC::Interpreter::cti_op_construct_JSConstruct): (JSC::Interpreter::cti_op_construct_NotJSConstruct): (JSC::Interpreter::cti_op_get_by_val): (JSC::Interpreter::cti_op_get_by_val_byte_array): (JSC::Interpreter::cti_op_sub): (JSC::Interpreter::cti_op_put_by_val): (JSC::Interpreter::cti_op_put_by_val_array): (JSC::Interpreter::cti_op_put_by_val_byte_array): (JSC::Interpreter::cti_op_loop_if_true): (JSC::Interpreter::cti_op_negate): (JSC::Interpreter::cti_op_div): (JSC::Interpreter::cti_op_pre_dec): (JSC::Interpreter::cti_op_not): (JSC::Interpreter::cti_op_jtrue): (JSC::Interpreter::cti_op_post_inc): (JSC::Interpreter::cti_op_lshift): (JSC::Interpreter::cti_op_bitand): (JSC::Interpreter::cti_op_rshift): (JSC::Interpreter::cti_op_bitnot): (JSC::Interpreter::cti_op_mod): (JSC::Interpreter::cti_op_post_dec): (JSC::Interpreter::cti_op_urshift): (JSC::Interpreter::cti_op_bitxor): (JSC::Interpreter::cti_op_bitor): (JSC::Interpreter::cti_op_push_scope): (JSC::Interpreter::cti_op_is_undefined): (JSC::Interpreter::cti_op_is_boolean): (JSC::Interpreter::cti_op_is_number): (JSC::Interpreter::cti_op_to_jsnumber): (JSC::Interpreter::cti_op_in): (JSC::Interpreter::cti_op_put_by_index): (JSC::Interpreter::cti_op_switch_imm): (JSC::Interpreter::cti_op_switch_char): (JSC::Interpreter::cti_op_switch_string): (JSC::Interpreter::cti_op_del_by_val): (JSC::Interpreter::cti_op_put_getter): (JSC::Interpreter::cti_op_put_setter): (JSC::Interpreter::cti_op_new_error):
  • interpreter/Interpreter.h: (JSC::Interpreter::isJSArray): (JSC::Interpreter::isJSString): (JSC::Interpreter::isJSByteArray):
  • interpreter/Register.h: (JSC::Register::marked): (JSC::Register::mark):
  • jit/JITInlineMethods.h: (JSC::JIT::getConstantOperandImmediateInt): (JSC::JIT::isOperandConstantImmediateInt):
  • jsc.cpp: (functionPrint): (functionDebug): (functionRun): (functionLoad): (runWithScripts): (runInteractive):
  • parser/Nodes.cpp: (JSC::processClauseList):
  • profiler/ProfileGenerator.cpp: (JSC::ProfileGenerator::addParentForConsoleStart):
  • profiler/Profiler.cpp: (JSC::Profiler::createCallIdentifier):
  • runtime/ArrayConstructor.cpp: (JSC::constructArrayWithSizeQuirk):
  • runtime/ArrayPrototype.cpp: (JSC::arrayProtoFuncToString): (JSC::arrayProtoFuncToLocaleString): (JSC::arrayProtoFuncJoin): (JSC::arrayProtoFuncConcat): (JSC::arrayProtoFuncPop): (JSC::arrayProtoFuncPush): (JSC::arrayProtoFuncReverse): (JSC::arrayProtoFuncShift): (JSC::arrayProtoFuncSlice): (JSC::arrayProtoFuncSort): (JSC::arrayProtoFuncSplice): (JSC::arrayProtoFuncUnShift): (JSC::arrayProtoFuncFilter): (JSC::arrayProtoFuncMap): (JSC::arrayProtoFuncEvery): (JSC::arrayProtoFuncForEach): (JSC::arrayProtoFuncSome): (JSC::arrayProtoFuncIndexOf): (JSC::arrayProtoFuncLastIndexOf):
  • runtime/BooleanConstructor.cpp: (JSC::constructBoolean): (JSC::callBooleanConstructor):
  • runtime/BooleanPrototype.cpp: (JSC::booleanProtoFuncToString): (JSC::booleanProtoFuncValueOf):
  • runtime/Collector.cpp: (JSC::Heap::protect): (JSC::Heap::unprotect): (JSC::Heap::heap): (JSC::Heap::collect): (JSC::typeName):
  • runtime/Completion.cpp: (JSC::evaluate):
  • runtime/DateConstructor.cpp: (JSC::constructDate): (JSC::dateParse): (JSC::dateUTC):
  • runtime/DateInstance.h: (JSC::DateInstance::internalNumber):
  • runtime/DatePrototype.cpp: (JSC::formatLocaleDate): (JSC::fillStructuresUsingTimeArgs): (JSC::fillStructuresUsingDateArgs): (JSC::dateProtoFuncToString): (JSC::dateProtoFuncToUTCString): (JSC::dateProtoFuncToDateString): (JSC::dateProtoFuncToTimeString): (JSC::dateProtoFuncToLocaleString): (JSC::dateProtoFuncToLocaleDateString): (JSC::dateProtoFuncToLocaleTimeString): (JSC::dateProtoFuncGetTime): (JSC::dateProtoFuncGetFullYear): (JSC::dateProtoFuncGetUTCFullYear): (JSC::dateProtoFuncToGMTString): (JSC::dateProtoFuncGetMonth): (JSC::dateProtoFuncGetUTCMonth): (JSC::dateProtoFuncGetDate): (JSC::dateProtoFuncGetUTCDate): (JSC::dateProtoFuncGetDay): (JSC::dateProtoFuncGetUTCDay): (JSC::dateProtoFuncGetHours): (JSC::dateProtoFuncGetUTCHours): (JSC::dateProtoFuncGetMinutes): (JSC::dateProtoFuncGetUTCMinutes): (JSC::dateProtoFuncGetSeconds): (JSC::dateProtoFuncGetUTCSeconds): (JSC::dateProtoFuncGetMilliSeconds): (JSC::dateProtoFuncGetUTCMilliseconds): (JSC::dateProtoFuncGetTimezoneOffset): (JSC::dateProtoFuncSetTime): (JSC::setNewValueFromTimeArgs): (JSC::setNewValueFromDateArgs): (JSC::dateProtoFuncSetYear): (JSC::dateProtoFuncGetYear):
  • runtime/ErrorConstructor.cpp: (JSC::constructError):
  • runtime/ErrorPrototype.cpp: (JSC::errorProtoFuncToString):
  • runtime/ExceptionHelpers.cpp: (JSC::createError): (JSC::createErrorMessage):
  • runtime/FunctionConstructor.cpp: (JSC::constructFunction):
  • runtime/FunctionPrototype.cpp: (JSC::functionProtoFuncToString): (JSC::functionProtoFuncApply): (JSC::functionProtoFuncCall):
  • runtime/GetterSetter.cpp: (JSC::GetterSetter::toObject):
  • runtime/JSActivation.cpp: (JSC::JSActivation::getOwnPropertySlot):
  • runtime/JSArray.cpp: (JSC::JSArray::put): (JSC::JSArray::mark): (JSC::JSArray::sort): (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key): (JSC::JSArray::compactForSorting):
  • runtime/JSByteArray.h: (JSC::JSByteArray::setIndex):
  • runtime/JSCell.h: (JSC::asCell):
  • runtime/JSFunction.cpp: (JSC::JSFunction::call): (JSC::JSFunction::construct):
  • runtime/JSGlobalObject.cpp: (JSC::markIfNeeded): (JSC::lastInPrototypeChain):
  • runtime/JSGlobalObjectFunctions.cpp: (JSC::encode): (JSC::decode): (JSC::globalFuncEval): (JSC::globalFuncParseInt): (JSC::globalFuncParseFloat): (JSC::globalFuncIsNaN): (JSC::globalFuncIsFinite): (JSC::globalFuncEscape): (JSC::globalFuncUnescape): (JSC::globalFuncJSCPrint):
  • runtime/JSImmediate.cpp: (JSC::JSImmediate::toThisObject): (JSC::JSImmediate::toObject): (JSC::JSImmediate::prototype): (JSC::JSImmediate::toString):
  • runtime/JSImmediate.h:
  • runtime/JSObject.cpp: (JSC::JSObject::mark): (JSC::JSObject::put): (JSC::callDefaultValueFunction): (JSC::JSObject::getPrimitiveNumber): (JSC::JSObject::defineGetter): (JSC::JSObject::defineSetter): (JSC::JSObject::lookupGetter): (JSC::JSObject::lookupSetter): (JSC::JSObject::hasInstance): (JSC::JSObject::toNumber): (JSC::JSObject::toString):
  • runtime/JSObject.h: (JSC::JSObject::JSObject): (JSC::JSObject::inlineGetOwnPropertySlot): (JSC::JSObject::getOwnPropertySlotForWrite): (JSC::JSObject::getPropertySlot): (JSC::JSValuePtr::get):
  • runtime/JSPropertyNameIterator.h: (JSC::JSPropertyNameIterator::create):
  • runtime/JSString.cpp: (JSC::JSString::getOwnPropertySlot):
  • runtime/JSValue.h:
  • runtime/JSWrapperObject.cpp: (JSC::JSWrapperObject::mark):
  • runtime/JSWrapperObject.h: (JSC::JSWrapperObject::setInternalValue):
  • runtime/MathObject.cpp: (JSC::mathProtoFuncAbs): (JSC::mathProtoFuncACos): (JSC::mathProtoFuncASin): (JSC::mathProtoFuncATan): (JSC::mathProtoFuncATan2): (JSC::mathProtoFuncCeil): (JSC::mathProtoFuncCos): (JSC::mathProtoFuncExp): (JSC::mathProtoFuncFloor): (JSC::mathProtoFuncLog): (JSC::mathProtoFuncMax): (JSC::mathProtoFuncMin): (JSC::mathProtoFuncPow): (JSC::mathProtoFuncRound): (JSC::mathProtoFuncSin): (JSC::mathProtoFuncSqrt): (JSC::mathProtoFuncTan):
  • runtime/NativeErrorConstructor.cpp: (JSC::NativeErrorConstructor::NativeErrorConstructor): (JSC::NativeErrorConstructor::construct):
  • runtime/NumberConstructor.cpp: (JSC::constructWithNumberConstructor): (JSC::callNumberConstructor):
  • runtime/NumberPrototype.cpp: (JSC::numberProtoFuncToString): (JSC::numberProtoFuncToLocaleString): (JSC::numberProtoFuncValueOf): (JSC::numberProtoFuncToFixed): (JSC::numberProtoFuncToExponential): (JSC::numberProtoFuncToPrecision):
  • runtime/ObjectConstructor.cpp: (JSC::constructObject):
  • runtime/ObjectPrototype.cpp: (JSC::objectProtoFuncValueOf): (JSC::objectProtoFuncHasOwnProperty): (JSC::objectProtoFuncIsPrototypeOf): (JSC::objectProtoFuncDefineGetter): (JSC::objectProtoFuncDefineSetter): (JSC::objectProtoFuncLookupGetter): (JSC::objectProtoFuncLookupSetter): (JSC::objectProtoFuncPropertyIsEnumerable): (JSC::objectProtoFuncToLocaleString): (JSC::objectProtoFuncToString):
  • runtime/Operations.h: (JSC::JSValuePtr::equalSlowCaseInline): (JSC::JSValuePtr::strictEqual): (JSC::JSValuePtr::strictEqualSlowCaseInline):
  • runtime/Protect.h: (JSC::gcProtect): (JSC::gcUnprotect):
  • runtime/RegExpConstructor.cpp: (JSC::setRegExpConstructorInput): (JSC::setRegExpConstructorMultiline): (JSC::constructRegExp):
  • runtime/RegExpObject.cpp: (JSC::setRegExpObjectLastIndex): (JSC::RegExpObject::match):
  • runtime/RegExpPrototype.cpp: (JSC::regExpProtoFuncTest): (JSC::regExpProtoFuncExec): (JSC::regExpProtoFuncCompile): (JSC::regExpProtoFuncToString):
  • runtime/StringConstructor.cpp: (JSC::stringFromCharCodeSlowCase): (JSC::stringFromCharCode): (JSC::constructWithStringConstructor): (JSC::callStringConstructor):
  • runtime/StringPrototype.cpp: (JSC::stringProtoFuncReplace): (JSC::stringProtoFuncToString): (JSC::stringProtoFuncCharAt): (JSC::stringProtoFuncCharCodeAt): (JSC::stringProtoFuncConcat): (JSC::stringProtoFuncIndexOf): (JSC::stringProtoFuncLastIndexOf): (JSC::stringProtoFuncMatch): (JSC::stringProtoFuncSearch): (JSC::stringProtoFuncSlice): (JSC::stringProtoFuncSplit): (JSC::stringProtoFuncSubstr): (JSC::stringProtoFuncSubstring): (JSC::stringProtoFuncToLowerCase): (JSC::stringProtoFuncToUpperCase): (JSC::stringProtoFuncLocaleCompare): (JSC::stringProtoFuncBig): (JSC::stringProtoFuncSmall): (JSC::stringProtoFuncBlink): (JSC::stringProtoFuncBold): (JSC::stringProtoFuncFixed): (JSC::stringProtoFuncItalics): (JSC::stringProtoFuncStrike): (JSC::stringProtoFuncSub): (JSC::stringProtoFuncSup): (JSC::stringProtoFuncFontcolor): (JSC::stringProtoFuncFontsize): (JSC::stringProtoFuncAnchor): (JSC::stringProtoFuncLink):
  • runtime/Structure.cpp: (JSC::Structure::Structure): (JSC::Structure::getEnumerablePropertyNames): (JSC::Structure::createCachedPrototypeChain):
  • runtime/Structure.h: (JSC::Structure::mark):
  • runtime/StructureChain.cpp: (JSC::StructureChain::StructureChain):

JavaScriptGlue:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • JSUtils.cpp: (KJSValueToJSObject): (KJSValueToCFTypeInternal):
  • JSValueWrapper.cpp: (JSValueWrapper::JSObjectCopyPropertyNames): (JSValueWrapper::JSObjectCopyProperty): (JSValueWrapper::JSObjectSetProperty): (JSValueWrapper::JSObjectCallFunction): (JSValueWrapper::JSObjectMark):
  • UserObjectImp.cpp: (UserObjectImp::getOwnPropertySlot):

WebCore:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSAudioConstructor.cpp: (WebCore::constructAudio):
  • bindings/js/JSCanvasRenderingContext2DCustom.cpp: (WebCore::toHTMLCanvasStyle): (WebCore::JSCanvasRenderingContext2D::setFillColor): (WebCore::JSCanvasRenderingContext2D::setStrokeColor): (WebCore::JSCanvasRenderingContext2D::strokeRect): (WebCore::JSCanvasRenderingContext2D::drawImage): (WebCore::JSCanvasRenderingContext2D::drawImageFromRect): (WebCore::JSCanvasRenderingContext2D::setShadow): (WebCore::JSCanvasRenderingContext2D::createPattern): (WebCore::JSCanvasRenderingContext2D::putImageData): (WebCore::JSCanvasRenderingContext2D::fillText): (WebCore::JSCanvasRenderingContext2D::strokeText):
  • bindings/js/JSClipboardCustom.cpp: (WebCore::JSClipboard::clearData): (WebCore::JSClipboard::getData): (WebCore::JSClipboard::setData): (WebCore::JSClipboard::setDragImage):
  • bindings/js/JSCustomPositionCallback.cpp: (WebCore::JSCustomPositionCallback::handleEvent):
  • bindings/js/JSCustomPositionErrorCallback.cpp: (WebCore::JSCustomPositionErrorCallback::handleEvent):
  • bindings/js/JSCustomSQLStatementCallback.cpp: (WebCore::JSCustomSQLStatementCallback::handleEvent):
  • bindings/js/JSCustomSQLStatementErrorCallback.cpp: (WebCore::JSCustomSQLStatementErrorCallback::handleEvent):
  • bindings/js/JSCustomSQLTransactionCallback.cpp: (WebCore::JSCustomSQLTransactionCallback::handleEvent):
  • bindings/js/JSCustomSQLTransactionErrorCallback.cpp: (WebCore::JSCustomSQLTransactionErrorCallback::handleEvent):
  • bindings/js/JSCustomVoidCallback.cpp: (WebCore::JSCustomVoidCallback::handleEvent): (WebCore::toVoidCallback):
  • bindings/js/JSCustomXPathNSResolver.cpp: (WebCore::JSCustomXPathNSResolver::create): (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
  • bindings/js/JSDOMApplicationCacheCustom.cpp: (WebCore::JSDOMApplicationCache::hasItem): (WebCore::JSDOMApplicationCache::add): (WebCore::JSDOMApplicationCache::remove): (WebCore::JSDOMApplicationCache::addEventListener): (WebCore::JSDOMApplicationCache::removeEventListener):
  • bindings/js/JSDOMBinding.cpp: (WebCore::valueToStringWithNullCheck): (WebCore::valueToStringWithUndefinedOrNullCheck): (WebCore::reportException):
  • bindings/js/JSDOMGlobalObject.cpp: (WebCore::JSDOMGlobalObject::findJSEventListener): (WebCore::JSDOMGlobalObject::findOrCreateJSEventListener): (WebCore::JSDOMGlobalObject::findJSUnprotectedEventListener): (WebCore::JSDOMGlobalObject::findOrCreateJSUnprotectedEventListener):
  • bindings/js/JSDOMStringListCustom.cpp: (WebCore::JSDOMStringList::item):
  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::getOwnPropertySlot): (windowProtoFuncOpen): (WebCore::toJSDOMWindow):
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::setLocation): (WebCore::JSDOMWindow::postMessage): (WebCore::setTimeoutOrInterval): (WebCore::JSDOMWindow::clearTimeout): (WebCore::JSDOMWindow::clearInterval): (WebCore::JSDOMWindow::atob): (WebCore::JSDOMWindow::btoa): (WebCore::JSDOMWindow::addEventListener): (WebCore::JSDOMWindow::removeEventListener): (WebCore::toDOMWindow):
  • bindings/js/JSDatabaseCustom.cpp: (WebCore::JSDatabase::changeVersion): (WebCore::JSDatabase::transaction):
  • bindings/js/JSDocumentCustom.cpp: (WebCore::JSDocument::setLocation):
  • bindings/js/JSElementCustom.cpp: (WebCore::JSElement::setAttribute): (WebCore::JSElement::setAttributeNS):
  • bindings/js/JSEventListener.cpp: (WebCore::JSAbstractEventListener::handleEvent): (WebCore::JSLazyEventListener::parseCode):
  • bindings/js/JSEventTargetNodeCustom.cpp: (WebCore::JSEventTargetNode::addEventListener): (WebCore::JSEventTargetNode::removeEventListener):
  • bindings/js/JSGeolocationCustom.cpp: (WebCore::createPositionOptions): (WebCore::JSGeolocation::getCurrentPosition): (WebCore::JSGeolocation::watchPosition):
  • bindings/js/JSHTMLCollectionCustom.cpp: (WebCore::callHTMLCollection): (WebCore::JSHTMLCollection::canGetItemsForName): (WebCore::JSHTMLCollection::item): (WebCore::JSHTMLCollection::namedItem):
  • bindings/js/JSHTMLDocumentCustom.cpp: (WebCore::JSHTMLDocument::open): (WebCore::writeHelper):
  • bindings/js/JSHTMLOptionsCollectionCustom.cpp: (WebCore::JSHTMLOptionsCollection::setLength): (WebCore::JSHTMLOptionsCollection::add):
  • bindings/js/JSHTMLSelectElementCustom.cpp: (WebCore::JSHTMLSelectElement::remove): (WebCore::selectIndexSetter):
  • bindings/js/JSImageConstructor.cpp: (WebCore::constructImage):
  • bindings/js/JSInspectedObjectWrapper.cpp: (WebCore::JSInspectedObjectWrapper::wrap): (WebCore::JSInspectedObjectWrapper::prepareIncomingValue):
  • bindings/js/JSInspectorCallbackWrapper.cpp: (WebCore::JSInspectorCallbackWrapper::wrap):
  • bindings/js/JSJavaScriptCallFrameCustom.cpp: (WebCore::JSJavaScriptCallFrame::evaluate):
  • bindings/js/JSLocationCustom.cpp: (WebCore::JSLocation::setHref): (WebCore::JSLocation::setProtocol): (WebCore::JSLocation::setHost): (WebCore::JSLocation::setHostname): (WebCore::JSLocation::setPort): (WebCore::JSLocation::setPathname): (WebCore::JSLocation::setSearch): (WebCore::JSLocation::setHash): (WebCore::JSLocation::replace): (WebCore::JSLocation::assign):
  • bindings/js/JSMessageChannelConstructor.cpp: (WebCore::JSMessageChannelConstructor::mark):
  • bindings/js/JSMessagePortCustom.cpp: (WebCore::JSMessagePort::startConversation): (WebCore::JSMessagePort::addEventListener): (WebCore::JSMessagePort::removeEventListener):
  • bindings/js/JSNodeFilterCondition.cpp: (WebCore::JSNodeFilterCondition::mark): (WebCore::JSNodeFilterCondition::acceptNode):
  • bindings/js/JSNodeFilterCondition.h:
  • bindings/js/JSNodeFilterCustom.cpp: (WebCore::toNodeFilter):
  • bindings/js/JSNodeListCustom.cpp: (WebCore::callNodeList):
  • bindings/js/JSOptionConstructor.cpp: (WebCore::constructHTMLOptionElement):
  • bindings/js/JSQuarantinedObjectWrapper.cpp: (WebCore::JSQuarantinedObjectWrapper::asWrapper): (WebCore::JSQuarantinedObjectWrapper::construct):
  • bindings/js/JSSQLResultSetRowListCustom.cpp: (WebCore::JSSQLResultSetRowList::item):
  • bindings/js/JSSQLTransactionCustom.cpp: (WebCore::JSSQLTransaction::executeSql):
  • bindings/js/JSSVGElementInstanceCustom.cpp: (WebCore::JSSVGElementInstance::addEventListener): (WebCore::JSSVGElementInstance::removeEventListener):
  • bindings/js/JSSVGLengthCustom.cpp: (WebCore::JSSVGLength::convertToSpecifiedUnits):
  • bindings/js/JSSVGMatrixCustom.cpp: (WebCore::JSSVGMatrix::translate): (WebCore::JSSVGMatrix::scale): (WebCore::JSSVGMatrix::scaleNonUniform): (WebCore::JSSVGMatrix::rotate): (WebCore::JSSVGMatrix::rotateFromVector): (WebCore::JSSVGMatrix::skewX): (WebCore::JSSVGMatrix::skewY):
  • bindings/js/JSSVGPathSegListCustom.cpp: (WebCore::JSSVGPathSegList::getItem): (WebCore::JSSVGPathSegList::insertItemBefore): (WebCore::JSSVGPathSegList::replaceItem): (WebCore::JSSVGPathSegList::removeItem):
  • bindings/js/JSSVGPointListCustom.cpp: (WebCore::JSSVGPointList::getItem): (WebCore::JSSVGPointList::insertItemBefore): (WebCore::JSSVGPointList::replaceItem): (WebCore::JSSVGPointList::removeItem):
  • bindings/js/JSSVGTransformListCustom.cpp: (WebCore::JSSVGTransformList::getItem): (WebCore::JSSVGTransformList::insertItemBefore): (WebCore::JSSVGTransformList::replaceItem): (WebCore::JSSVGTransformList::removeItem):
  • bindings/js/JSStorageCustom.cpp: (WebCore::JSStorage::deleteProperty): (WebCore::JSStorage::customPut):
  • bindings/js/JSWebKitCSSMatrixConstructor.cpp: (WebCore::constructWebKitCSSMatrix):
  • bindings/js/JSWorkerConstructor.cpp: (WebCore::constructWorker):
  • bindings/js/JSWorkerContextCustom.cpp: (WebCore::JSWorkerContext::addEventListener): (WebCore::JSWorkerContext::removeEventListener):
  • bindings/js/JSWorkerCustom.cpp: (WebCore::JSWorker::addEventListener): (WebCore::JSWorker::removeEventListener):
  • bindings/js/JSXMLHttpRequestCustom.cpp: (WebCore::JSXMLHttpRequest::open): (WebCore::JSXMLHttpRequest::setRequestHeader): (WebCore::JSXMLHttpRequest::send): (WebCore::JSXMLHttpRequest::getResponseHeader): (WebCore::JSXMLHttpRequest::overrideMimeType): (WebCore::JSXMLHttpRequest::addEventListener): (WebCore::JSXMLHttpRequest::removeEventListener):
  • bindings/js/JSXMLHttpRequestUploadCustom.cpp: (WebCore::JSXMLHttpRequestUpload::addEventListener): (WebCore::JSXMLHttpRequestUpload::removeEventListener):
  • bindings/js/JSXSLTProcessorCustom.cpp: (WebCore::JSXSLTProcessor::importStylesheet): (WebCore::JSXSLTProcessor::transformToFragment): (WebCore::JSXSLTProcessor::transformToDocument): (WebCore::JSXSLTProcessor::setParameter): (WebCore::JSXSLTProcessor::getParameter): (WebCore::JSXSLTProcessor::removeParameter):
  • bindings/js/ScheduledAction.cpp: (WebCore::ScheduledAction::executeFunctionInContext):
  • bindings/js/ScriptCallStack.cpp: (WebCore::ScriptCallStack::initialize):
  • bindings/js/ScriptController.cpp: (WebCore::ScriptController::createScriptObjectForPluginElement):
  • bindings/js/ScriptValue.cpp: (WebCore::ScriptValue::getString): (WebCore::ScriptValue::isNull): (WebCore::ScriptValue::isUndefined):
  • bindings/objc/WebScriptObject.mm: (-[WebScriptObject callWebScriptMethod:withArguments:]): (+[WebScriptObject _convertValueToObjcValue:originRootObject:rootObject:]):
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp: (_NPN_InvokeDefault): (_NPN_Invoke): (_NPN_HasMethod): (_NPN_Construct):
  • bridge/c/c_utility.cpp: (JSC::Bindings::convertValueToNPVariant):
  • bridge/jni/jni_instance.cpp: (JavaInstance::invokeMethod):
  • bridge/jni/jni_jsobject.mm: (JavaJSObject::call): (JavaJSObject::convertValueToJObject):
  • bridge/jni/jni_runtime.cpp: (JavaField::dispatchValueFromInstance): (JavaField::valueFromInstance): (JavaField::dispatchSetValueToInstance): (JavaField::setValueToInstance):
  • bridge/jni/jni_utility.cpp: (JSC::Bindings::convertArrayInstanceToJavaArray): (JSC::Bindings::convertValueToJValue):
  • bridge/objc/objc_runtime.mm: (JSC::Bindings::callObjCFallbackObject):
  • bridge/objc/objc_utility.mm: (JSC::Bindings::convertValueToObjcValue):
  • bridge/runtime_method.cpp: (JSC::callRuntimeMethod):
  • bridge/runtime_object.cpp: (JSC::RuntimeObjectImp::getOwnPropertySlot): (JSC::callRuntimeConstructor):

WebKit/mac:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • Plugins/Hosted/NetscapePluginInstanceProxy.mm: (WebKit::NetscapePluginInstanceProxy::invoke): (WebKit::NetscapePluginInstanceProxy::hasMethod): (WebKit::NetscapePluginInstanceProxy::marshalValue):
  • WebView/WebFrame.mm: (-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]):
  • WebView/WebView.mm: (aeDescFromJSValue):

WebKit/win:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • WebScriptCallFrame.cpp: (WebScriptCallFrame::jsValueToString):
  • WebView.cpp: (WebView::stringByEvaluatingJavaScriptFromString):

WebKit/wx:

2009-01-19 Sam Weinig <[email protected]>

Rubber-stamped by Gavin Barraclough.

Remove temporary operator-> from JSValuePtr.

  • WebFrame.cpp: (wxWebFrame::RunScript):
  • Property svn:eol-style set to native
File size: 34.1 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2003 Peter Kelly ([email protected])
5 * Copyright (C) 2006 Alexey Proskuryakov ([email protected])
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#include "config.h"
24#include "JSArray.h"
25
26#include "ArrayPrototype.h"
27#include "PropertyNameArray.h"
28#include <wtf/AVLTree.h>
29#include <wtf/Assertions.h>
30#include <Operations.h>
31
32#define CHECK_ARRAY_CONSISTENCY 0
33
34using namespace std;
35using namespace WTF;
36
37namespace JSC {
38
39ASSERT_CLASS_FITS_IN_CELL(JSArray);
40
41// Overview of JSArray
42//
43// Properties of JSArray objects may be stored in one of three locations:
44// * The regular JSObject property map.
45// * A storage vector.
46// * A sparse map of array entries.
47//
48// Properties with non-numeric identifiers, with identifiers that are not representable
49// as an unsigned integer, or where the value is greater than MAX_ARRAY_INDEX
50// (specifically, this is only one property - the value 0xFFFFFFFFU as an unsigned 32-bit
51// integer) are not considered array indices and will be stored in the JSObject property map.
52//
53// All properties with a numeric identifer, representable as an unsigned integer i,
54// where (i <= MAX_ARRAY_INDEX), are an array index and will be stored in either the
55// storage vector or the sparse map. An array index i will be handled in the following
56// fashion:
57//
58// * Where (i < MIN_SPARSE_ARRAY_INDEX) the value will be stored in the storage vector.
59// * Where (MIN_SPARSE_ARRAY_INDEX <= i <= MAX_STORAGE_VECTOR_INDEX) the value will either
60// be stored in the storage vector or in the sparse array, depending on the density of
61// data that would be stored in the vector (a vector being used where at least
62// (1 / minDensityMultiplier) of the entries would be populated).
63// * Where (MAX_STORAGE_VECTOR_INDEX < i <= MAX_ARRAY_INDEX) the value will always be stored
64// in the sparse array.
65
66// The definition of MAX_STORAGE_VECTOR_LENGTH is dependant on the definition storageSize
67// function below - the MAX_STORAGE_VECTOR_LENGTH limit is defined such that the storage
68// size calculation cannot overflow. (sizeof(ArrayStorage) - sizeof(JSValuePtr)) +
69// (vectorLength * sizeof(JSValuePtr)) must be <= 0xFFFFFFFFU (which is maximum value of size_t).
70#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(JSValuePtr))) / sizeof(JSValuePtr))
71
72// These values have to be macros to be used in max() and min() without introducing
73// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
74#define MIN_SPARSE_ARRAY_INDEX 10000U
75#define MAX_STORAGE_VECTOR_INDEX (MAX_STORAGE_VECTOR_LENGTH - 1)
76// 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer.
77#define MAX_ARRAY_INDEX 0xFFFFFFFEU
78
79// Our policy for when to use a vector and when to use a sparse map.
80// For all array indices under MIN_SPARSE_ARRAY_INDEX, we always use a vector.
81// When indices greater than MIN_SPARSE_ARRAY_INDEX are involved, we use a vector
82// as long as it is 1/8 full. If more sparse than that, we use a map.
83static const unsigned minDensityMultiplier = 8;
84
85const ClassInfo JSArray::info = {"Array", 0, 0, 0};
86
87static inline size_t storageSize(unsigned vectorLength)
88{
89 ASSERT(vectorLength <= MAX_STORAGE_VECTOR_LENGTH);
90
91 // MAX_STORAGE_VECTOR_LENGTH is defined such that provided (vectorLength <= MAX_STORAGE_VECTOR_LENGTH)
92 // - as asserted above - the following calculation cannot overflow.
93 size_t size = (sizeof(ArrayStorage) - sizeof(JSValuePtr)) + (vectorLength * sizeof(JSValuePtr));
94 // Assertion to detect integer overflow in previous calculation (should not be possible, provided that
95 // MAX_STORAGE_VECTOR_LENGTH is correctly defined).
96 ASSERT(((size - (sizeof(ArrayStorage) - sizeof(JSValuePtr))) / sizeof(JSValuePtr) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValuePtr))));
97
98 return size;
99}
100
101static inline unsigned increasedVectorLength(unsigned newLength)
102{
103 ASSERT(newLength <= MAX_STORAGE_VECTOR_LENGTH);
104
105 // Mathematically equivalent to:
106 // increasedLength = (newLength * 3 + 1) / 2;
107 // or:
108 // increasedLength = (unsigned)ceil(newLength * 1.5));
109 // This form is not prone to internal overflow.
110 unsigned increasedLength = newLength + (newLength >> 1) + (newLength & 1);
111 ASSERT(increasedLength >= newLength);
112
113 return min(increasedLength, MAX_STORAGE_VECTOR_LENGTH);
114}
115
116static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues)
117{
118 return length / minDensityMultiplier <= numValues;
119}
120
121#if !CHECK_ARRAY_CONSISTENCY
122
123inline void JSArray::checkConsistency(ConsistencyCheckType)
124{
125}
126
127#endif
128
129JSArray::JSArray(PassRefPtr<Structure> structure)
130 : JSObject(structure)
131{
132 unsigned initialCapacity = 0;
133
134 m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
135 m_fastAccessCutoff = 0;
136 m_storage->m_vectorLength = initialCapacity;
137 m_storage->m_length = 0;
138
139 checkConsistency();
140}
141
142JSArray::JSArray(PassRefPtr<Structure> structure, unsigned initialLength)
143 : JSObject(structure)
144{
145 unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
146
147 m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
148 m_fastAccessCutoff = 0;
149 m_storage->m_vectorLength = initialCapacity;
150 m_storage->m_length = initialLength;
151
152 Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValuePtr));
153
154 checkConsistency();
155}
156
157JSArray::JSArray(ExecState* exec, PassRefPtr<Structure> structure, const ArgList& list)
158 : JSObject(structure)
159{
160 unsigned length = list.size();
161
162 m_fastAccessCutoff = length;
163
164 ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(length)));
165
166 storage->m_vectorLength = length;
167 storage->m_numValuesInVector = length;
168 storage->m_sparseValueMap = 0;
169 storage->m_length = length;
170
171 size_t i = 0;
172 ArgList::const_iterator end = list.end();
173 for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i)
174 storage->m_vector[i] = (*it).jsValue(exec);
175
176 m_storage = storage;
177
178 // When the array is created non-empty, its cells are filled, so it's really no worse than
179 // a property map. Therefore don't report extra memory cost.
180
181 checkConsistency();
182}
183
184JSArray::~JSArray()
185{
186 checkConsistency(DestructorConsistencyCheck);
187
188 delete m_storage->m_sparseValueMap;
189 fastFree(m_storage);
190}
191
192bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
193{
194 ArrayStorage* storage = m_storage;
195
196 if (i >= storage->m_length) {
197 if (i > MAX_ARRAY_INDEX)
198 return getOwnPropertySlot(exec, Identifier::from(exec, i), slot);
199 return false;
200 }
201
202 if (i < storage->m_vectorLength) {
203 JSValuePtr& valueSlot = storage->m_vector[i];
204 if (valueSlot) {
205 slot.setValueSlot(&valueSlot);
206 return true;
207 }
208 } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
209 if (i >= MIN_SPARSE_ARRAY_INDEX) {
210 SparseArrayValueMap::iterator it = map->find(i);
211 if (it != map->end()) {
212 slot.setValueSlot(&it->second);
213 return true;
214 }
215 }
216 }
217
218 return false;
219}
220
221bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
222{
223 if (propertyName == exec->propertyNames().length) {
224 slot.setValue(jsNumber(exec, length()));
225 return true;
226 }
227
228 bool isArrayIndex;
229 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
230 if (isArrayIndex)
231 return JSArray::getOwnPropertySlot(exec, i, slot);
232
233 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
234}
235
236// ECMA 15.4.5.1
237void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
238{
239 bool isArrayIndex;
240 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
241 if (isArrayIndex) {
242 put(exec, i, value);
243 return;
244 }
245
246 if (propertyName == exec->propertyNames().length) {
247 unsigned newLength = value.toUInt32(exec);
248 if (value.toNumber(exec) != static_cast<double>(newLength)) {
249 throwError(exec, RangeError, "Invalid array length.");
250 return;
251 }
252 setLength(newLength);
253 return;
254 }
255
256 JSObject::put(exec, propertyName, value, slot);
257}
258
259void JSArray::put(ExecState* exec, unsigned i, JSValuePtr value)
260{
261 checkConsistency();
262
263 unsigned length = m_storage->m_length;
264 if (i >= length && i <= MAX_ARRAY_INDEX) {
265 length = i + 1;
266 m_storage->m_length = length;
267 }
268
269 if (i < m_storage->m_vectorLength) {
270 JSValuePtr& valueSlot = m_storage->m_vector[i];
271 if (valueSlot) {
272 valueSlot = value;
273 checkConsistency();
274 return;
275 }
276 valueSlot = value;
277 if (++m_storage->m_numValuesInVector == m_storage->m_length)
278 m_fastAccessCutoff = m_storage->m_length;
279 checkConsistency();
280 return;
281 }
282
283 putSlowCase(exec, i, value);
284}
285
286NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValuePtr value)
287{
288 ArrayStorage* storage = m_storage;
289 SparseArrayValueMap* map = storage->m_sparseValueMap;
290
291 if (i >= MIN_SPARSE_ARRAY_INDEX) {
292 if (i > MAX_ARRAY_INDEX) {
293 PutPropertySlot slot;
294 put(exec, Identifier::from(exec, i), value, slot);
295 return;
296 }
297
298 // We miss some cases where we could compact the storage, such as a large array that is being filled from the end
299 // (which will only be compacted as we reach indices that are less than cutoff) - but this makes the check much faster.
300 if ((i > MAX_STORAGE_VECTOR_INDEX) || !isDenseEnoughForVector(i + 1, storage->m_numValuesInVector + 1)) {
301 if (!map) {
302 map = new SparseArrayValueMap;
303 storage->m_sparseValueMap = map;
304 }
305 map->set(i, value);
306 return;
307 }
308 }
309
310 // We have decided that we'll put the new item into the vector.
311 // Fast case is when there is no sparse map, so we can increase the vector size without moving values from it.
312 if (!map || map->isEmpty()) {
313 if (increaseVectorLength(i + 1)) {
314 storage = m_storage;
315 storage->m_vector[i] = value;
316 if (++storage->m_numValuesInVector == storage->m_length)
317 m_fastAccessCutoff = storage->m_length;
318 checkConsistency();
319 } else
320 throwOutOfMemoryError(exec);
321 return;
322 }
323
324 // Decide how many values it would be best to move from the map.
325 unsigned newNumValuesInVector = storage->m_numValuesInVector + 1;
326 unsigned newVectorLength = increasedVectorLength(i + 1);
327 for (unsigned j = max(storage->m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
328 newNumValuesInVector += map->contains(j);
329 if (i >= MIN_SPARSE_ARRAY_INDEX)
330 newNumValuesInVector -= map->contains(i);
331 if (isDenseEnoughForVector(newVectorLength, newNumValuesInVector)) {
332 unsigned proposedNewNumValuesInVector = newNumValuesInVector;
333 // If newVectorLength is already the maximum - MAX_STORAGE_VECTOR_LENGTH - then do not attempt to grow any further.
334 while (newVectorLength < MAX_STORAGE_VECTOR_LENGTH) {
335 unsigned proposedNewVectorLength = increasedVectorLength(newVectorLength + 1);
336 for (unsigned j = max(newVectorLength, MIN_SPARSE_ARRAY_INDEX); j < proposedNewVectorLength; ++j)
337 proposedNewNumValuesInVector += map->contains(j);
338 if (!isDenseEnoughForVector(proposedNewVectorLength, proposedNewNumValuesInVector))
339 break;
340 newVectorLength = proposedNewVectorLength;
341 newNumValuesInVector = proposedNewNumValuesInVector;
342 }
343 }
344
345 storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength)));
346 if (!storage) {
347 throwOutOfMemoryError(exec);
348 return;
349 }
350
351 unsigned vectorLength = storage->m_vectorLength;
352 if (newNumValuesInVector == storage->m_numValuesInVector + 1) {
353 for (unsigned j = vectorLength; j < newVectorLength; ++j)
354 storage->m_vector[j] = noValue();
355 if (i > MIN_SPARSE_ARRAY_INDEX)
356 map->remove(i);
357 } else {
358 for (unsigned j = vectorLength; j < max(vectorLength, MIN_SPARSE_ARRAY_INDEX); ++j)
359 storage->m_vector[j] = noValue();
360 for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
361 storage->m_vector[j] = map->take(j);
362 }
363
364 storage->m_vector[i] = value;
365
366 storage->m_vectorLength = newVectorLength;
367 storage->m_numValuesInVector = newNumValuesInVector;
368
369 m_storage = storage;
370
371 checkConsistency();
372}
373
374bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName)
375{
376 bool isArrayIndex;
377 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
378 if (isArrayIndex)
379 return deleteProperty(exec, i);
380
381 if (propertyName == exec->propertyNames().length)
382 return false;
383
384 return JSObject::deleteProperty(exec, propertyName);
385}
386
387bool JSArray::deleteProperty(ExecState* exec, unsigned i)
388{
389 checkConsistency();
390
391 ArrayStorage* storage = m_storage;
392
393 if (i < storage->m_vectorLength) {
394 JSValuePtr& valueSlot = storage->m_vector[i];
395 if (!valueSlot) {
396 checkConsistency();
397 return false;
398 }
399 valueSlot = noValue();
400 --storage->m_numValuesInVector;
401 if (m_fastAccessCutoff > i)
402 m_fastAccessCutoff = i;
403 checkConsistency();
404 return true;
405 }
406
407 if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
408 if (i >= MIN_SPARSE_ARRAY_INDEX) {
409 SparseArrayValueMap::iterator it = map->find(i);
410 if (it != map->end()) {
411 map->remove(it);
412 checkConsistency();
413 return true;
414 }
415 }
416 }
417
418 checkConsistency();
419
420 if (i > MAX_ARRAY_INDEX)
421 return deleteProperty(exec, Identifier::from(exec, i));
422
423 return false;
424}
425
426void JSArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
427{
428 // FIXME: Filling PropertyNameArray with an identifier for every integer
429 // is incredibly inefficient for large arrays. We need a different approach,
430 // which almost certainly means a different structure for PropertyNameArray.
431
432 ArrayStorage* storage = m_storage;
433
434 unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
435 for (unsigned i = 0; i < usedVectorLength; ++i) {
436 if (storage->m_vector[i])
437 propertyNames.add(Identifier::from(exec, i));
438 }
439
440 if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
441 SparseArrayValueMap::iterator end = map->end();
442 for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
443 propertyNames.add(Identifier::from(exec, it->first));
444 }
445
446 JSObject::getPropertyNames(exec, propertyNames);
447}
448
449bool JSArray::increaseVectorLength(unsigned newLength)
450{
451 // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map
452 // to the vector. Callers have to account for that, because they can do it more efficiently.
453
454 ArrayStorage* storage = m_storage;
455
456 unsigned vectorLength = storage->m_vectorLength;
457 ASSERT(newLength > vectorLength);
458 ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX);
459 unsigned newVectorLength = increasedVectorLength(newLength);
460
461 storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength)));
462 if (!storage)
463 return false;
464
465 storage->m_vectorLength = newVectorLength;
466
467 for (unsigned i = vectorLength; i < newVectorLength; ++i)
468 storage->m_vector[i] = noValue();
469
470 m_storage = storage;
471 return true;
472}
473
474void JSArray::setLength(unsigned newLength)
475{
476 checkConsistency();
477
478 ArrayStorage* storage = m_storage;
479
480 unsigned length = m_storage->m_length;
481
482 if (newLength < length) {
483 if (m_fastAccessCutoff > newLength)
484 m_fastAccessCutoff = newLength;
485
486 unsigned usedVectorLength = min(length, storage->m_vectorLength);
487 for (unsigned i = newLength; i < usedVectorLength; ++i) {
488 JSValuePtr& valueSlot = storage->m_vector[i];
489 bool hadValue = valueSlot;
490 valueSlot = noValue();
491 storage->m_numValuesInVector -= hadValue;
492 }
493
494 if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
495 SparseArrayValueMap copy = *map;
496 SparseArrayValueMap::iterator end = copy.end();
497 for (SparseArrayValueMap::iterator it = copy.begin(); it != end; ++it) {
498 if (it->first >= newLength)
499 map->remove(it->first);
500 }
501 if (map->isEmpty()) {
502 delete map;
503 storage->m_sparseValueMap = 0;
504 }
505 }
506 }
507
508 m_storage->m_length = newLength;
509
510 checkConsistency();
511}
512
513JSValuePtr JSArray::pop()
514{
515 checkConsistency();
516
517 unsigned length = m_storage->m_length;
518 if (!length)
519 return jsUndefined();
520
521 --length;
522
523 JSValuePtr result;
524
525 if (m_fastAccessCutoff > length) {
526 JSValuePtr& valueSlot = m_storage->m_vector[length];
527 result = valueSlot;
528 ASSERT(result);
529 valueSlot = noValue();
530 --m_storage->m_numValuesInVector;
531 m_fastAccessCutoff = length;
532 } else if (length < m_storage->m_vectorLength) {
533 JSValuePtr& valueSlot = m_storage->m_vector[length];
534 result = valueSlot;
535 valueSlot = noValue();
536 if (result)
537 --m_storage->m_numValuesInVector;
538 else
539 result = jsUndefined();
540 } else {
541 result = jsUndefined();
542 if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {
543 SparseArrayValueMap::iterator it = map->find(length);
544 if (it != map->end()) {
545 result = it->second;
546 map->remove(it);
547 if (map->isEmpty()) {
548 delete map;
549 m_storage->m_sparseValueMap = 0;
550 }
551 }
552 }
553 }
554
555 m_storage->m_length = length;
556
557 checkConsistency();
558
559 return result;
560}
561
562void JSArray::push(ExecState* exec, JSValuePtr value)
563{
564 checkConsistency();
565
566 if (m_storage->m_length < m_storage->m_vectorLength) {
567 ASSERT(!m_storage->m_vector[m_storage->m_length]);
568 m_storage->m_vector[m_storage->m_length] = value;
569 if (++m_storage->m_numValuesInVector == ++m_storage->m_length)
570 m_fastAccessCutoff = m_storage->m_length;
571 checkConsistency();
572 return;
573 }
574
575 if (m_storage->m_length < MIN_SPARSE_ARRAY_INDEX) {
576 SparseArrayValueMap* map = m_storage->m_sparseValueMap;
577 if (!map || map->isEmpty()) {
578 if (increaseVectorLength(m_storage->m_length + 1)) {
579 m_storage->m_vector[m_storage->m_length] = value;
580 if (++m_storage->m_numValuesInVector == ++m_storage->m_length)
581 m_fastAccessCutoff = m_storage->m_length;
582 checkConsistency();
583 return;
584 }
585 checkConsistency();
586 throwOutOfMemoryError(exec);
587 return;
588 }
589 }
590
591 putSlowCase(exec, m_storage->m_length++, value);
592}
593
594void JSArray::mark()
595{
596 JSObject::mark();
597
598 ArrayStorage* storage = m_storage;
599
600 unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
601 for (unsigned i = 0; i < usedVectorLength; ++i) {
602 JSValuePtr value = storage->m_vector[i];
603 if (value && !value.marked())
604 value.mark();
605 }
606
607 if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
608 SparseArrayValueMap::iterator end = map->end();
609 for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
610 JSValuePtr value = it->second;
611 if (!value.marked())
612 value.mark();
613 }
614 }
615}
616
617typedef std::pair<JSValuePtr, UString> ArrayQSortPair;
618
619static int compareByStringPairForQSort(const void* a, const void* b)
620{
621 const ArrayQSortPair* va = static_cast<const ArrayQSortPair*>(a);
622 const ArrayQSortPair* vb = static_cast<const ArrayQSortPair*>(b);
623 return compare(va->second, vb->second);
624}
625
626void JSArray::sort(ExecState* exec)
627{
628 unsigned lengthNotIncludingUndefined = compactForSorting();
629 if (m_storage->m_sparseValueMap) {
630 throwOutOfMemoryError(exec);
631 return;
632 }
633
634 if (!lengthNotIncludingUndefined)
635 return;
636
637 // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that.
638 // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary
639 // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return
640 // random or otherwise changing results, effectively making compare function inconsistent.
641
642 Vector<ArrayQSortPair> values(lengthNotIncludingUndefined);
643 if (!values.begin()) {
644 throwOutOfMemoryError(exec);
645 return;
646 }
647
648 for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
649 JSValuePtr value = m_storage->m_vector[i];
650 ASSERT(!value.isUndefined());
651 values[i].first = value;
652 }
653
654 // FIXME: While calling these toString functions, the array could be mutated.
655 // In that case, objects pointed to by values in this vector might get garbage-collected!
656
657 // FIXME: The following loop continues to call toString on subsequent values even after
658 // a toString call raises an exception.
659
660 for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
661 values[i].second = values[i].first.toString(exec);
662
663 if (exec->hadException())
664 return;
665
666 // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather
667 // than O(N log N).
668
669#if HAVE(MERGESORT)
670 mergesort(values.begin(), values.size(), sizeof(ArrayQSortPair), compareByStringPairForQSort);
671#else
672 // FIXME: The qsort library function is likely to not be a stable sort.
673 // ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort.
674 qsort(values.begin(), values.size(), sizeof(ArrayQSortPair), compareByStringPairForQSort);
675#endif
676
677 // FIXME: If the toString function changed the length of the array, this might be
678 // modifying the vector incorrectly.
679
680 for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
681 m_storage->m_vector[i] = values[i].first;
682
683 checkConsistency(SortConsistencyCheck);
684}
685
686struct AVLTreeNodeForArrayCompare {
687 JSValuePtr value;
688
689 // Child pointers. The high bit of gt is robbed and used as the
690 // balance factor sign. The high bit of lt is robbed and used as
691 // the magnitude of the balance factor.
692 int32_t gt;
693 int32_t lt;
694};
695
696struct AVLTreeAbstractorForArrayCompare {
697 typedef int32_t handle; // Handle is an index into m_nodes vector.
698 typedef JSValuePtr key;
699 typedef int32_t size;
700
701 Vector<AVLTreeNodeForArrayCompare> m_nodes;
702 ExecState* m_exec;
703 JSValuePtr m_compareFunction;
704 CallType m_compareCallType;
705 const CallData* m_compareCallData;
706 JSValuePtr m_globalThisValue;
707
708 handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; }
709 void set_less(handle h, handle lh) { m_nodes[h].lt &= 0x80000000; m_nodes[h].lt |= lh; }
710 handle get_greater(handle h) { return m_nodes[h].gt & 0x7FFFFFFF; }
711 void set_greater(handle h, handle gh) { m_nodes[h].gt &= 0x80000000; m_nodes[h].gt |= gh; }
712
713 int get_balance_factor(handle h)
714 {
715 if (m_nodes[h].gt & 0x80000000)
716 return -1;
717 return static_cast<unsigned>(m_nodes[h].lt) >> 31;
718 }
719
720 void set_balance_factor(handle h, int bf)
721 {
722 if (bf == 0) {
723 m_nodes[h].lt &= 0x7FFFFFFF;
724 m_nodes[h].gt &= 0x7FFFFFFF;
725 } else {
726 m_nodes[h].lt |= 0x80000000;
727 if (bf < 0)
728 m_nodes[h].gt |= 0x80000000;
729 else
730 m_nodes[h].gt &= 0x7FFFFFFF;
731 }
732 }
733
734 int compare_key_key(key va, key vb)
735 {
736 ASSERT(!va.isUndefined());
737 ASSERT(!vb.isUndefined());
738
739 if (m_exec->hadException())
740 return 1;
741
742 ArgList arguments;
743 arguments.append(va);
744 arguments.append(vb);
745 double compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments).toNumber(m_exec);
746 return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
747 }
748
749 int compare_key_node(key k, handle h) { return compare_key_key(k, m_nodes[h].value); }
750 int compare_node_node(handle h1, handle h2) { return compare_key_key(m_nodes[h1].value, m_nodes[h2].value); }
751
752 static handle null() { return 0x7FFFFFFF; }
753};
754
755void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callType, const CallData& callData)
756{
757 checkConsistency();
758
759 // FIXME: This ignores exceptions raised in the compare function or in toNumber.
760
761 // The maximum tree depth is compiled in - but the caller is clearly up to no good
762 // if a larger array is passed.
763 ASSERT(m_storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max()));
764 if (m_storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max()))
765 return;
766
767 if (!m_storage->m_length)
768 return;
769
770 unsigned usedVectorLength = min(m_storage->m_length, m_storage->m_vectorLength);
771
772 AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items
773 tree.abstractor().m_exec = exec;
774 tree.abstractor().m_compareFunction = compareFunction;
775 tree.abstractor().m_compareCallType = callType;
776 tree.abstractor().m_compareCallData = &callData;
777 tree.abstractor().m_globalThisValue = exec->globalThisValue();
778 tree.abstractor().m_nodes.resize(usedVectorLength + (m_storage->m_sparseValueMap ? m_storage->m_sparseValueMap->size() : 0));
779
780 if (!tree.abstractor().m_nodes.begin()) {
781 throwOutOfMemoryError(exec);
782 return;
783 }
784
785 // FIXME: If the compare function modifies the array, the vector, map, etc. could be modified
786 // right out from under us while we're building the tree here.
787
788 unsigned numDefined = 0;
789 unsigned numUndefined = 0;
790
791 // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
792 for (; numDefined < usedVectorLength; ++numDefined) {
793 JSValuePtr v = m_storage->m_vector[numDefined];
794 if (!v || v.isUndefined())
795 break;
796 tree.abstractor().m_nodes[numDefined].value = v;
797 tree.insert(numDefined);
798 }
799 for (unsigned i = numDefined; i < usedVectorLength; ++i) {
800 JSValuePtr v = m_storage->m_vector[i];
801 if (v) {
802 if (v.isUndefined())
803 ++numUndefined;
804 else {
805 tree.abstractor().m_nodes[numDefined].value = v;
806 tree.insert(numDefined);
807 ++numDefined;
808 }
809 }
810 }
811
812 unsigned newUsedVectorLength = numDefined + numUndefined;
813
814 if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {
815 newUsedVectorLength += map->size();
816 if (newUsedVectorLength > m_storage->m_vectorLength) {
817 // Check that it is possible to allocate an array large enough to hold all the entries.
818 if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) {
819 throwOutOfMemoryError(exec);
820 return;
821 }
822 }
823
824 SparseArrayValueMap::iterator end = map->end();
825 for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
826 tree.abstractor().m_nodes[numDefined].value = it->second;
827 tree.insert(numDefined);
828 ++numDefined;
829 }
830
831 delete map;
832 m_storage->m_sparseValueMap = 0;
833 }
834
835 ASSERT(tree.abstractor().m_nodes.size() >= numDefined);
836
837 // FIXME: If the compare function changed the length of the array, the following might be
838 // modifying the vector incorrectly.
839
840 // Copy the values back into m_storage.
841 AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
842 iter.start_iter_least(tree);
843 for (unsigned i = 0; i < numDefined; ++i) {
844 m_storage->m_vector[i] = tree.abstractor().m_nodes[*iter].value;
845 ++iter;
846 }
847
848 // Put undefined values back in.
849 for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
850 m_storage->m_vector[i] = jsUndefined();
851
852 // Ensure that unused values in the vector are zeroed out.
853 for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
854 m_storage->m_vector[i] = noValue();
855
856 m_fastAccessCutoff = newUsedVectorLength;
857 m_storage->m_numValuesInVector = newUsedVectorLength;
858
859 checkConsistency(SortConsistencyCheck);
860}
861
862void JSArray::fillArgList(ExecState* exec, ArgList& args)
863{
864 unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff);
865 unsigned i = 0;
866 for (; i < fastAccessLength; ++i)
867 args.append(getIndex(i));
868 for (; i < m_storage->m_length; ++i)
869 args.append(get(exec, i));
870}
871
872unsigned JSArray::compactForSorting()
873{
874 checkConsistency();
875
876 ArrayStorage* storage = m_storage;
877
878 unsigned usedVectorLength = min(m_storage->m_length, storage->m_vectorLength);
879
880 unsigned numDefined = 0;
881 unsigned numUndefined = 0;
882
883 for (; numDefined < usedVectorLength; ++numDefined) {
884 JSValuePtr v = storage->m_vector[numDefined];
885 if (!v || v.isUndefined())
886 break;
887 }
888 for (unsigned i = numDefined; i < usedVectorLength; ++i) {
889 JSValuePtr v = storage->m_vector[i];
890 if (v) {
891 if (v.isUndefined())
892 ++numUndefined;
893 else
894 storage->m_vector[numDefined++] = v;
895 }
896 }
897
898 unsigned newUsedVectorLength = numDefined + numUndefined;
899
900 if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
901 newUsedVectorLength += map->size();
902 if (newUsedVectorLength > storage->m_vectorLength) {
903 // Check that it is possible to allocate an array large enough to hold all the entries - if not,
904 // exception is thrown by caller.
905 if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength))
906 return 0;
907 storage = m_storage;
908 }
909
910 SparseArrayValueMap::iterator end = map->end();
911 for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
912 storage->m_vector[numDefined++] = it->second;
913
914 delete map;
915 storage->m_sparseValueMap = 0;
916 }
917
918 for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
919 storage->m_vector[i] = jsUndefined();
920 for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
921 storage->m_vector[i] = noValue();
922
923 m_fastAccessCutoff = newUsedVectorLength;
924 storage->m_numValuesInVector = newUsedVectorLength;
925
926 checkConsistency(SortConsistencyCheck);
927
928 return numDefined;
929}
930
931void* JSArray::lazyCreationData()
932{
933 return m_storage->lazyCreationData;
934}
935
936void JSArray::setLazyCreationData(void* d)
937{
938 m_storage->lazyCreationData = d;
939}
940
941#if CHECK_ARRAY_CONSISTENCY
942
943void JSArray::checkConsistency(ConsistencyCheckType type)
944{
945 ASSERT(m_storage);
946 if (type == SortConsistencyCheck)
947 ASSERT(!m_storage->m_sparseValueMap);
948
949 ASSERT(m_fastAccessCutoff <= m_storage->m_length);
950 ASSERT(m_fastAccessCutoff <= m_storage->m_numValuesInVector);
951
952 unsigned numValuesInVector = 0;
953 for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) {
954 if (JSValuePtr value = m_storage->m_vector[i]) {
955 ASSERT(i < m_storage->m_length);
956 if (type != DestructorConsistencyCheck)
957 value->type(); // Likely to crash if the object was deallocated.
958 ++numValuesInVector;
959 } else {
960 ASSERT(i >= m_fastAccessCutoff);
961 if (type == SortConsistencyCheck)
962 ASSERT(i >= m_storage->m_numValuesInVector);
963 }
964 }
965 ASSERT(numValuesInVector == m_storage->m_numValuesInVector);
966
967 if (m_storage->m_sparseValueMap) {
968 SparseArrayValueMap::iterator end = m_storage->m_sparseValueMap->end();
969 for (SparseArrayValueMap::iterator it = m_storage->m_sparseValueMap->begin(); it != end; ++it) {
970 unsigned index = it->first;
971 ASSERT(index < m_storage->m_length);
972 ASSERT(index >= m_storage->m_vectorLength);
973 ASSERT(index <= MAX_ARRAY_INDEX);
974 ASSERT(it->second);
975 if (type != DestructorConsistencyCheck)
976 it->second->type(); // Likely to crash if the object was deallocated.
977 }
978 }
979}
980
981#endif
982
983JSArray* constructEmptyArray(ExecState* exec)
984{
985 return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure());
986}
987
988JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
989{
990 return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
991}
992
993JSArray* constructArray(ExecState* exec, JSValuePtr singleItemValue)
994{
995 ArgList values;
996 values.append(singleItemValue);
997 return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), values);
998}
999
1000JSArray* constructArray(ExecState* exec, const ArgList& values)
1001{
1002 return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), values);
1003}
1004
1005} // namespace JSC
Note: See TracBrowser for help on using the repository browser.