From 64be5e900806b82b316377433100ca1e6ae83f3a Mon Sep 17 00:00:00 2001 From: "ggaren@apple.com" Date: Tue, 24 Jan 2012 07:34:10 +0000 Subject: [PATCH] JSValue::toString() should return a JSString* instead of a UString https://bugs.webkit.org/show_bug.cgi?id=76861 ../JavaScriptCore: Reviewed by Gavin Barraclough. This makes the common case -- toString() on a string -- faster and inline-able. (Not a measureable speedup, but we can now remove a bunch of duplicate hand-rolled code for this optimization.) This also clarifies the boundary between "C++ strings" and "JS strings". In all cases other than true, false, null, undefined, and multi-digit numbers, the JS runtime was just retrieving a UString from a JSString, so returning a JSString* is strictly better. In the other cases, we can optimize to avoid creating a new JSString if we care to, but it doesn't seem to be a big deal. * JavaScriptCore.exp: Export! * jsc.cpp: (functionPrint): (functionDebug): (functionRun): (functionLoad): (functionCheckSyntax): (runWithScripts): (runInteractive): * API/JSValueRef.cpp: (JSValueToStringCopy): * bytecode/CodeBlock.cpp: (JSC::valueToSourceString): Call value() after calling toString(), to convert from "JS string" (JSString*) to "C++ string" (UString), since toString() no longer returns a "C++ string". * dfg/DFGOperations.cpp: (JSC::DFG::operationValueAddNotNumber): * jit/JITStubs.cpp: (op_add): Updated for removal of toPrimitiveString(): all '+' operands can use toString(), except for object operands, which need to take a slow path to call toPrimitive(). * runtime/ArrayPrototype.cpp: (JSC::arrayProtoFuncToString): (JSC::arrayProtoFuncToLocaleString): (JSC::arrayProtoFuncJoin): (JSC::arrayProtoFuncPush): * runtime/CommonSlowPaths.h: (JSC::CommonSlowPaths::opIn): * runtime/DateConstructor.cpp: (JSC::dateParse): * runtime/DatePrototype.cpp: (JSC::formatLocaleDate): Call value() after calling toString(), as above. * runtime/ErrorInstance.h: (JSC::ErrorInstance::create): Simplified down to one canonical create() function, to make string handling easier. * runtime/ErrorPrototype.cpp: (JSC::errorProtoFuncToString): * runtime/ExceptionHelpers.cpp: (JSC::createInvalidParamError): (JSC::createNotAConstructorError): (JSC::createNotAFunctionError): (JSC::createNotAnObjectError): * runtime/FunctionConstructor.cpp: (JSC::constructFunctionSkippingEvalEnabledCheck): * runtime/FunctionPrototype.cpp: (JSC::functionProtoFuncBind): * runtime/JSArray.cpp: (JSC::JSArray::sort): Call value() after calling toString(), as above. * runtime/JSCell.cpp: * runtime/JSCell.h: Removed JSCell::toString() because JSValue does this job now. Doing it in JSCell is slower (requires extra type checking), and creates the misimpression that language-defined toString() behavior is an implementation detail of JSCell. * runtime/JSGlobalObjectFunctions.cpp: (JSC::encode): (JSC::decode): (JSC::globalFuncEval): (JSC::globalFuncParseInt): (JSC::globalFuncParseFloat): (JSC::globalFuncEscape): (JSC::globalFuncUnescape): Call value() after calling toString(), as above. * runtime/JSONObject.cpp: (JSC::unwrapBoxedPrimitive): (JSC::Stringifier::Stringifier): (JSC::JSONProtoFuncParse): Removed some manual optimization that toString() takes care of. * runtime/JSObject.cpp: (JSC::JSObject::toString): * runtime/JSObject.h: Updated to return JSString*. * runtime/JSString.cpp: * runtime/JSString.h: (JSC::JSValue::toString): Removed, since I removed JSCell::toString(). * runtime/JSValue.cpp: (JSC::JSValue::toStringSlowCase): Removed toPrimitiveString(), and re- spawned toStringSlowCase() from its zombie corpse, since toPrimitiveString() basically did what we want all the time. (Note that the toPrimitive() preference changes from NoPreference to PreferString, because that's how ToString is defined in the language. op_add does not want this behavior.) * runtime/NumberPrototype.cpp: (JSC::numberProtoFuncToString): (JSC::numberProtoFuncToLocaleString): A little simpler, now that toString() returns a JSString*. * runtime/ObjectConstructor.cpp: (JSC::objectConstructorGetOwnPropertyDescriptor): (JSC::objectConstructorDefineProperty): * runtime/ObjectPrototype.cpp: (JSC::objectProtoFuncHasOwnProperty): (JSC::objectProtoFuncDefineGetter): (JSC::objectProtoFuncDefineSetter): (JSC::objectProtoFuncLookupGetter): (JSC::objectProtoFuncLookupSetter): (JSC::objectProtoFuncPropertyIsEnumerable): More calls to value(), as above. * runtime/Operations.cpp: (JSC::jsAddSlowCase): Need to check for object before taking the toString() fast path becuase adding an object to a string requires calling toPrimitive() on the object, not toString(). (They differ in their preferred conversion type.) * runtime/Operations.h: (JSC::jsString): (JSC::jsStringFromArguments): This code gets simpler, now that toString() does the right thing. (JSC::jsAdd): Now checks for object, just like jsAddSlowCase(). * runtime/RegExpConstructor.cpp: (JSC::setRegExpConstructorInput): (JSC::constructRegExp): * runtime/RegExpObject.cpp: (JSC::RegExpObject::match): * runtime/RegExpPrototype.cpp: (JSC::regExpProtoFuncCompile): (JSC::regExpProtoFuncToString): More calls to value(), as above. * runtime/StringConstructor.cpp: (JSC::constructWithStringConstructor): (JSC::callStringConstructor): This code gets simpler, now that toString() does the right thing. * runtime/StringPrototype.cpp: (JSC::replaceUsingRegExpSearch): (JSC::replaceUsingStringSearch): (JSC::stringProtoFuncReplace): (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): (JSC::trimString): Some of this code gets simpler, now that toString() does the right thing. More calls to value(), as above. ../JavaScriptGlue: Reviewed by Gavin Barraclough. * JSUtils.cpp: (KJSValueToCFTypeInternal): ../WebCore: Reviewed by Gavin Barraclough. Mechanical changes to call value() after calling toString(), to convert from "JS string" (JSString*) to "C++ string" (UString), since toString() no longer returns a "C++ string". * bindings/js/IDBBindingUtilities.cpp: (WebCore::createIDBKeyFromValue): * bindings/js/JSCSSStyleDeclarationCustom.cpp: (WebCore::JSCSSStyleDeclaration::getPropertyCSSValue): * bindings/js/JSClipboardCustom.cpp: (WebCore::JSClipboard::clearData): (WebCore::JSClipboard::getData): * bindings/js/JSCustomXPathNSResolver.cpp: (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI): * bindings/js/JSDOMBinding.cpp: (WebCore::valueToStringWithNullCheck): (WebCore::valueToStringWithUndefinedOrNullCheck): (WebCore::reportException): * bindings/js/JSDOMFormDataCustom.cpp: (WebCore::JSDOMFormData::append): * bindings/js/JSDOMStringMapCustom.cpp: (WebCore::JSDOMStringMap::putDelegate): * bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::setLocation): (WebCore::JSDOMWindow::open): (WebCore::JSDOMWindow::addEventListener): (WebCore::JSDOMWindow::removeEventListener): * bindings/js/JSDeviceMotionEventCustom.cpp: (WebCore::JSDeviceMotionEvent::initDeviceMotionEvent): * bindings/js/JSDeviceOrientationEventCustom.cpp: (WebCore::JSDeviceOrientationEvent::initDeviceOrientationEvent): * bindings/js/JSDictionary.cpp: (WebCore::JSDictionary::convertValue): * bindings/js/JSDocumentCustom.cpp: (WebCore::JSDocument::setLocation): * bindings/js/JSEventListener.cpp: (WebCore::JSEventListener::handleEvent): * bindings/js/JSHTMLAllCollectionCustom.cpp: (WebCore::callHTMLAllCollection): (WebCore::JSHTMLAllCollection::item): (WebCore::JSHTMLAllCollection::namedItem): * bindings/js/JSHTMLCanvasElementCustom.cpp: (WebCore::JSHTMLCanvasElement::getContext): * bindings/js/JSHTMLCollectionCustom.cpp: (WebCore::JSHTMLCollection::item): (WebCore::JSHTMLCollection::namedItem): * bindings/js/JSHTMLDocumentCustom.cpp: (WebCore::documentWrite): * bindings/js/JSHTMLInputElementCustom.cpp: (WebCore::JSHTMLInputElement::setSelectionDirection): (WebCore::JSHTMLInputElement::setSelectionRange): * bindings/js/JSInspectorFrontendHostCustom.cpp: (WebCore::JSInspectorFrontendHost::showContextMenu): * 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/JSMessageEventCustom.cpp: (WebCore::handleInitMessageEvent): * bindings/js/JSSQLTransactionCustom.cpp: (WebCore::JSSQLTransaction::executeSql): * bindings/js/JSSQLTransactionSyncCustom.cpp: (WebCore::JSSQLTransactionSync::executeSql): * bindings/js/JSSharedWorkerCustom.cpp: (WebCore::JSSharedWorkerConstructor::constructJSSharedWorker): * bindings/js/JSStorageCustom.cpp: (WebCore::JSStorage::putDelegate): * bindings/js/JSWebGLRenderingContextCustom.cpp: (WebCore::JSWebGLRenderingContext::getExtension): * bindings/js/JSWebSocketCustom.cpp: (WebCore::JSWebSocketConstructor::constructJSWebSocket): (WebCore::JSWebSocket::send): (WebCore::JSWebSocket::close): * bindings/js/JSWorkerContextCustom.cpp: (WebCore::JSWorkerContext::importScripts): * bindings/js/JSWorkerCustom.cpp: (WebCore::JSWorkerConstructor::constructJSWorker): * bindings/js/JSXMLHttpRequestCustom.cpp: (WebCore::JSXMLHttpRequest::open): (WebCore::JSXMLHttpRequest::send): * bindings/js/JSXSLTProcessorCustom.cpp: (WebCore::JSXSLTProcessor::setParameter): (WebCore::JSXSLTProcessor::getParameter): (WebCore::JSXSLTProcessor::removeParameter): * bindings/js/ScheduledAction.cpp: (WebCore::ScheduledAction::create): * bindings/js/ScriptEventListener.cpp: (WebCore::eventListenerHandlerBody): * bindings/js/ScriptValue.cpp: (WebCore::ScriptValue::toString): * bindings/scripts/CodeGeneratorJS.pm: (GenerateEventListenerCall): (JSValueToNative): (GenerateConstructorDefinition): * bridge/c/c_utility.cpp: (JSC::Bindings::convertValueToNPVariant): * bridge/jni/jni_jsobject.mm: (JavaJSObject::convertValueToJObject): * bridge/jni/jsc/JNIUtilityPrivate.cpp: (JSC::Bindings::convertArrayInstanceToJavaArray): (JSC::Bindings::convertValueToJValue): * bridge/jni/jsc/JavaFieldJSC.cpp: (JavaField::dispatchValueFromInstance): (JavaField::valueFromInstance): (JavaField::dispatchSetValueToInstance): (JavaField::setValueToInstance): * bridge/jni/jsc/JavaInstanceJSC.cpp: (JavaInstance::invokeMethod): * testing/js/JSInternalsCustom.cpp: (WebCore::JSInternals::setUserPreferredLanguages): ../WebKit/mac: Reviewed by Gavin Barraclough. Mechanical changes to call value() after calling toString(), to convert from "JS string" (JSString*) to "C++ string" (UString), since toString() no longer returns a "C++ string". * Plugins/Hosted/NetscapePluginInstanceProxy.mm: (WebKit::NetscapePluginInstanceProxy::addValueToArray): * WebView/WebFrame.mm: (-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]): (-[WebFrame _stringByEvaluatingJavaScriptFromString:withGlobalObject:inScriptWorld:]): ../WebKit2: Reviewed by Gavin Barraclough. Mechanical changes to call value() after calling toString(), to convert from "JS string" (JSString*) to "C++ string" (UString), since toString() no longer returns a "C++ string". * WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp: (WebKit::NPRuntimeObjectMap::convertJSValueToNPVariant): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105698 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/JavaScriptCore/API/JSValueRef.cpp | 2 +- Source/JavaScriptCore/ChangeLog | 186 +++++++++++++++++++++ Source/JavaScriptCore/JavaScriptCore.exp | 2 +- .../JavaScriptCore/JavaScriptCore.def | 4 +- Source/JavaScriptCore/bytecode/CodeBlock.cpp | 2 +- Source/JavaScriptCore/dfg/DFGOperations.cpp | 13 +- Source/JavaScriptCore/jit/JITStubs.cpp | 22 ++- Source/JavaScriptCore/jsc.cpp | 18 +- Source/JavaScriptCore/runtime/ArrayPrototype.cpp | 18 +- Source/JavaScriptCore/runtime/CommonSlowPaths.h | 2 +- Source/JavaScriptCore/runtime/DateConstructor.cpp | 2 +- Source/JavaScriptCore/runtime/DatePrototype.cpp | 6 +- Source/JavaScriptCore/runtime/ErrorInstance.h | 8 +- Source/JavaScriptCore/runtime/ErrorPrototype.cpp | 4 +- Source/JavaScriptCore/runtime/ExceptionHelpers.cpp | 8 +- .../JavaScriptCore/runtime/FunctionConstructor.cpp | 8 +- .../JavaScriptCore/runtime/FunctionPrototype.cpp | 2 +- Source/JavaScriptCore/runtime/JSArray.cpp | 2 +- Source/JavaScriptCore/runtime/JSCell.cpp | 7 - Source/JavaScriptCore/runtime/JSCell.h | 1 - .../runtime/JSGlobalObjectFunctions.cpp | 15 +- Source/JavaScriptCore/runtime/JSONObject.cpp | 22 +-- Source/JavaScriptCore/runtime/JSObject.cpp | 4 +- Source/JavaScriptCore/runtime/JSObject.h | 2 +- Source/JavaScriptCore/runtime/JSString.cpp | 5 - Source/JavaScriptCore/runtime/JSString.h | 20 +-- Source/JavaScriptCore/runtime/JSValue.cpp | 14 +- Source/JavaScriptCore/runtime/JSValue.h | 4 +- Source/JavaScriptCore/runtime/NumberPrototype.cpp | 4 +- .../JavaScriptCore/runtime/ObjectConstructor.cpp | 4 +- Source/JavaScriptCore/runtime/ObjectPrototype.cpp | 12 +- Source/JavaScriptCore/runtime/Operations.cpp | 10 +- Source/JavaScriptCore/runtime/Operations.h | 23 +-- .../JavaScriptCore/runtime/RegExpConstructor.cpp | 6 +- Source/JavaScriptCore/runtime/RegExpObject.cpp | 2 +- Source/JavaScriptCore/runtime/RegExpPrototype.cpp | 6 +- .../JavaScriptCore/runtime/StringConstructor.cpp | 7 +- Source/JavaScriptCore/runtime/StringPrototype.cpp | 132 ++++++--------- Source/JavaScriptGlue/ChangeLog | 10 ++ Source/JavaScriptGlue/JSUtils.cpp | 2 +- Source/WebCore/ChangeLog | 126 ++++++++++++++ Source/WebCore/bindings/js/IDBBindingUtilities.cpp | 2 +- .../bindings/js/JSCSSStyleDeclarationCustom.cpp | 2 +- Source/WebCore/bindings/js/JSClipboardCustom.cpp | 4 +- .../bindings/js/JSCustomXPathNSResolver.cpp | 2 +- Source/WebCore/bindings/js/JSDOMBinding.cpp | 8 +- Source/WebCore/bindings/js/JSDOMFormDataCustom.cpp | 6 +- .../WebCore/bindings/js/JSDOMStringMapCustom.cpp | 2 +- Source/WebCore/bindings/js/JSDOMWindowCustom.cpp | 8 +- .../bindings/js/JSDeviceMotionEventCustom.cpp | 2 +- .../bindings/js/JSDeviceOrientationEventCustom.cpp | 2 +- Source/WebCore/bindings/js/JSDictionary.cpp | 2 +- Source/WebCore/bindings/js/JSDocumentCustom.cpp | 2 +- Source/WebCore/bindings/js/JSEventListener.cpp | 2 +- .../bindings/js/JSHTMLAllCollectionCustom.cpp | 12 +- .../bindings/js/JSHTMLCanvasElementCustom.cpp | 2 +- .../WebCore/bindings/js/JSHTMLCollectionCustom.cpp | 6 +- .../WebCore/bindings/js/JSHTMLDocumentCustom.cpp | 4 +- .../bindings/js/JSHTMLInputElementCustom.cpp | 4 +- .../bindings/js/JSInspectorFrontendHostCustom.cpp | 4 +- .../bindings/js/JSJavaScriptCallFrameCustom.cpp | 2 +- Source/WebCore/bindings/js/JSLocationCustom.cpp | 20 +-- .../WebCore/bindings/js/JSMessageEventCustom.cpp | 6 +- .../WebCore/bindings/js/JSSQLTransactionCustom.cpp | 4 +- .../bindings/js/JSSQLTransactionSyncCustom.cpp | 4 +- .../WebCore/bindings/js/JSSharedWorkerCustom.cpp | 4 +- Source/WebCore/bindings/js/JSStorageCustom.cpp | 2 +- .../bindings/js/JSWebGLRenderingContextCustom.cpp | 2 +- Source/WebCore/bindings/js/JSWebSocketCustom.cpp | 10 +- .../WebCore/bindings/js/JSWorkerContextCustom.cpp | 2 +- Source/WebCore/bindings/js/JSWorkerCustom.cpp | 2 +- .../WebCore/bindings/js/JSXMLHttpRequestCustom.cpp | 6 +- .../WebCore/bindings/js/JSXSLTProcessorCustom.cpp | 14 +- Source/WebCore/bindings/js/ScheduledAction.cpp | 2 +- Source/WebCore/bindings/js/ScriptEventListener.cpp | 3 +- Source/WebCore/bindings/js/ScriptValue.cpp | 2 +- Source/WebCore/bindings/scripts/CodeGeneratorJS.pm | 6 +- Source/WebCore/bridge/c/c_utility.cpp | 2 +- Source/WebCore/bridge/jni/jni_jsobject.mm | 2 +- .../WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp | 6 +- Source/WebCore/bridge/jni/jsc/JavaFieldJSC.cpp | 8 +- Source/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp | 4 +- Source/WebCore/bridge/qt/qt_runtime.cpp | 20 +-- Source/WebCore/bridge/testbindings.cpp | 2 +- Source/WebCore/bridge/testqtbindings.cpp | 2 +- Source/WebCore/testing/js/JSInternalsCustom.cpp | 2 +- Source/WebKit/efl/ewk/ewk_frame.cpp | 3 +- Source/WebKit/mac/ChangeLog | 17 ++ .../Plugins/Hosted/NetscapePluginInstanceProxy.mm | 2 +- Source/WebKit/mac/WebView/WebFrame.mm | 6 +- Source/WebKit/win/WebFrame.cpp | 3 +- Source/WebKit2/ChangeLog | 14 ++ .../Plugins/Netscape/NPRuntimeObjectMap.cpp | 2 +- 93 files changed, 638 insertions(+), 371 deletions(-) diff --git a/Source/JavaScriptCore/API/JSValueRef.cpp b/Source/JavaScriptCore/API/JSValueRef.cpp index c89e267..1b4e03b 100644 --- a/Source/JavaScriptCore/API/JSValueRef.cpp +++ b/Source/JavaScriptCore/API/JSValueRef.cpp @@ -293,7 +293,7 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* JSValue jsValue = toJS(exec, value); - RefPtr stringRef(OpaqueJSString::create(jsValue.toString(exec))); + RefPtr stringRef(OpaqueJSString::create(jsValue.toString(exec)->value(exec))); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index 83e0002..1ba9f1e 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,3 +1,189 @@ +2012-01-23 Geoffrey Garen + + JSValue::toString() should return a JSString* instead of a UString + https://bugs.webkit.org/show_bug.cgi?id=76861 + + Reviewed by Gavin Barraclough. + + This makes the common case -- toString() on a string -- faster and + inline-able. (Not a measureable speedup, but we can now remove a bunch + of duplicate hand-rolled code for this optimization.) + + This also clarifies the boundary between "C++ strings" and "JS strings". + + In all cases other than true, false, null, undefined, and multi-digit + numbers, the JS runtime was just retrieving a UString from a JSString, + so returning a JSString* is strictly better. In the other cases, we can + optimize to avoid creating a new JSString if we care to, but it doesn't + seem to be a big deal. + + * JavaScriptCore.exp: Export! + + * jsc.cpp: + (functionPrint): + (functionDebug): + (functionRun): + (functionLoad): + (functionCheckSyntax): + (runWithScripts): + (runInteractive): + * API/JSValueRef.cpp: + (JSValueToStringCopy): + * bytecode/CodeBlock.cpp: + (JSC::valueToSourceString): Call value() after calling toString(), to + convert from "JS string" (JSString*) to "C++ string" (UString), since + toString() no longer returns a "C++ string". + + * dfg/DFGOperations.cpp: + (JSC::DFG::operationValueAddNotNumber): + * jit/JITStubs.cpp: + (op_add): Updated for removal of toPrimitiveString(): + all '+' operands can use toString(), except for object operands, which + need to take a slow path to call toPrimitive(). + + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + (JSC::arrayProtoFuncToLocaleString): + (JSC::arrayProtoFuncJoin): + (JSC::arrayProtoFuncPush): + * runtime/CommonSlowPaths.h: + (JSC::CommonSlowPaths::opIn): + * runtime/DateConstructor.cpp: + (JSC::dateParse): + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): Call value() after calling toString(), as above. + + * runtime/ErrorInstance.h: + (JSC::ErrorInstance::create): Simplified down to one canonical create() + function, to make string handling easier. + + * runtime/ErrorPrototype.cpp: + (JSC::errorProtoFuncToString): + * runtime/ExceptionHelpers.cpp: + (JSC::createInvalidParamError): + (JSC::createNotAConstructorError): + (JSC::createNotAFunctionError): + (JSC::createNotAnObjectError): + * runtime/FunctionConstructor.cpp: + (JSC::constructFunctionSkippingEvalEnabledCheck): + * runtime/FunctionPrototype.cpp: + (JSC::functionProtoFuncBind): + * runtime/JSArray.cpp: + (JSC::JSArray::sort): Call value() after calling toString(), as above. + + * runtime/JSCell.cpp: + * runtime/JSCell.h: Removed JSCell::toString() because JSValue does this + job now. Doing it in JSCell is slower (requires extra type checking), and + creates the misimpression that language-defined toString() behavior is + an implementation detail of JSCell. + + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::encode): + (JSC::decode): + (JSC::globalFuncEval): + (JSC::globalFuncParseInt): + (JSC::globalFuncParseFloat): + (JSC::globalFuncEscape): + (JSC::globalFuncUnescape): Call value() after calling toString(), as above. + + * runtime/JSONObject.cpp: + (JSC::unwrapBoxedPrimitive): + (JSC::Stringifier::Stringifier): + (JSC::JSONProtoFuncParse): Removed some manual optimization that toString() + takes care of. + + * runtime/JSObject.cpp: + (JSC::JSObject::toString): + * runtime/JSObject.h: Updated to return JSString*. + + * runtime/JSString.cpp: + * runtime/JSString.h: + (JSC::JSValue::toString): Removed, since I removed JSCell::toString(). + + * runtime/JSValue.cpp: + (JSC::JSValue::toStringSlowCase): Removed toPrimitiveString(), and re- + spawned toStringSlowCase() from its zombie corpse, since toPrimitiveString() + basically did what we want all the time. (Note that the toPrimitive() + preference changes from NoPreference to PreferString, because that's + how ToString is defined in the language. op_add does not want this behavior.) + + * runtime/NumberPrototype.cpp: + (JSC::numberProtoFuncToString): + (JSC::numberProtoFuncToLocaleString): A little simpler, now that toString() + returns a JSString*. + + * runtime/ObjectConstructor.cpp: + (JSC::objectConstructorGetOwnPropertyDescriptor): + (JSC::objectConstructorDefineProperty): + * runtime/ObjectPrototype.cpp: + (JSC::objectProtoFuncHasOwnProperty): + (JSC::objectProtoFuncDefineGetter): + (JSC::objectProtoFuncDefineSetter): + (JSC::objectProtoFuncLookupGetter): + (JSC::objectProtoFuncLookupSetter): + (JSC::objectProtoFuncPropertyIsEnumerable): More calls to value(), as above. + + * runtime/Operations.cpp: + (JSC::jsAddSlowCase): Need to check for object before taking the toString() + fast path becuase adding an object to a string requires calling toPrimitive() + on the object, not toString(). (They differ in their preferred conversion + type.) + + * runtime/Operations.h: + (JSC::jsString): + (JSC::jsStringFromArguments): This code gets simpler, now that toString() + does the right thing. + + (JSC::jsAdd): Now checks for object, just like jsAddSlowCase(). + + * runtime/RegExpConstructor.cpp: + (JSC::setRegExpConstructorInput): + (JSC::constructRegExp): + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::match): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncCompile): + (JSC::regExpProtoFuncToString): More calls to value(), as above. + + * runtime/StringConstructor.cpp: + (JSC::constructWithStringConstructor): + (JSC::callStringConstructor): This code gets simpler, now that toString() + does the right thing. + + * runtime/StringPrototype.cpp: + (JSC::replaceUsingRegExpSearch): + (JSC::replaceUsingStringSearch): + (JSC::stringProtoFuncReplace): + (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): + (JSC::trimString): Some of this code gets simpler, now that toString() + does the right thing. More calls to value(), as above. + 2012-01-23 Luke Macpherson Unreviewed, rolling out r105676. diff --git a/Source/JavaScriptCore/JavaScriptCore.exp b/Source/JavaScriptCore/JavaScriptCore.exp index 34ebe93..4bf3ed9 100644 --- a/Source/JavaScriptCore/JavaScriptCore.exp +++ b/Source/JavaScriptCore/JavaScriptCore.exp @@ -567,13 +567,13 @@ __ZNK3JSC19SourceProviderCache8byteSizeEv __ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE __ZNK3JSC6JSCell8toNumberEPNS_9ExecStateE __ZNK3JSC6JSCell8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE -__ZNK3JSC6JSCell8toStringEPNS_9ExecStateE __ZNK3JSC6JSCell9getStringEPNS_9ExecStateE __ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE __ZNK3JSC7ArgList8getSliceEiRS0_ __ZNK3JSC7JSArray12subclassDataEv __ZNK3JSC7JSValue16toNumberSlowCaseEPNS_9ExecStateE __ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateEPNS_14JSGlobalObjectE +__ZNK3JSC7JSValue16toStringSlowCaseEPNS_9ExecStateE __ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE __ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE __ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index 4ef8ed3..5095d5c 100644 --- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -339,10 +339,10 @@ EXPORTS ?toNumberSlowCase@JSValue@JSC@@ABENPAVExecState@2@@Z ?toObject@JSCell@JSC@@QBEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z ?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z - ?toString@JSCell@JSC@@QBE?AVUString@2@PAVExecState@2@@Z - ?toString@JSObject@JSC@@QBE?AVUString@2@PAVExecState@2@@Z + ?toString@JSObject@JSC@@QBEPAVJSString@2@PAVExecState@2@@Z ?toStringDecimal@DecimalNumber@WTF@@QBEIPA_WI@Z ?toStringExponential@DecimalNumber@WTF@@QBEIPA_WI@Z + ?toStringSlowCase@JSValue@JSC@@ABEPAVJSString@2@PAVExecState@2@@Z ?toThisObject@JSObject@JSC@@SAPAV12@PAVJSCell@2@PAVExecState@2@@Z ?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z ?toUInt32@Identifier@JSC@@SAIABVUString@2@AA_N@Z diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index 72ea0b4..0599833 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -78,7 +78,7 @@ static UString valueToSourceString(ExecState* exec, JSValue val) return "0"; if (val.isString()) - return makeUString("\"", escapeQuotes(val.toString(exec)), "\""); + return makeUString("\"", escapeQuotes(val.toString(exec)->value(exec)), "\""); return val.description(); } diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp index d1d9bd3..26be252 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp @@ -197,7 +197,7 @@ ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exe JSGlobalData* globalData = &exec->globalData(); // Don't put to an object if toString throws an exception. - Identifier ident(exec, property.toString(exec)); + Identifier ident(exec, property.toString(exec)->value(exec)); if (!globalData->exception) { PutPropertySlot slot(strict); baseValue.put(exec, ident, value, slot); @@ -259,11 +259,8 @@ EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, Encoded ASSERT(!op1.isNumber() || !op2.isNumber()); - if (op1.isString()) { - if (op2.isString()) - return JSValue::encode(jsString(exec, asString(op1), asString(op2))); - return JSValue::encode(jsString(exec, asString(op1), op2.toPrimitiveString(exec))); - } + if (op1.isString() && !op2.isObject()) + return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec))); return JSValue::encode(jsAddSlowCase(exec, op1, op2)); } @@ -306,7 +303,7 @@ EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue e } } - Identifier ident(exec, property.toString(exec)); + Identifier ident(exec, property.toString(exec)->value(exec)); return JSValue::encode(baseValue.get(exec, ident)); } @@ -326,7 +323,7 @@ EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base return JSValue::encode(result); } - Identifier ident(exec, property.toString(exec)); + Identifier ident(exec, property.toString(exec)->value(exec)); return JSValue::encode(JSValue(base).get(exec, ident)); } diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index 29c5b98..38c8504 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -1303,10 +1303,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add) JSValue v2 = stackFrame.args[1].jsValue(); CallFrame* callFrame = stackFrame.callFrame; - if (v1.isString()) { - JSValue result = v2.isString() - ? jsString(callFrame, asString(v1), asString(v2)) - : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame)); + if (v1.isString() && !v2.isObject()) { + JSValue result = jsString(callFrame, asString(v1), v2.toString(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -2461,7 +2459,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val) return JSValue::encode(result); } - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); JSValue result = baseValue.get(callFrame, property); CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); @@ -2488,7 +2486,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string) ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val)); } } else { - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); result = baseValue.get(callFrame, property); } @@ -2518,7 +2516,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array) if (!isJSByteArray(baseValue)) ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val)); } else { - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); result = baseValue.get(callFrame, property); } @@ -2579,7 +2577,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) } else baseValue.put(callFrame, i, value); } else { - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception. PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); baseValue.put(callFrame, property, value, slot); @@ -2620,7 +2618,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array) ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val)); baseValue.put(callFrame, i, value); } else { - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception. PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); baseValue.put(callFrame, property, value, slot); @@ -3386,7 +3384,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_in) if (propName.getUInt32(i)) return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, i))); - Identifier property(callFrame, propName.toString(callFrame)); + Identifier property(callFrame, propName.toString(callFrame)->value(callFrame)); CHECK_FOR_EXCEPTION(); return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, property))); } @@ -3498,7 +3496,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val) result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i); else { CHECK_FOR_EXCEPTION(); - Identifier property(callFrame, subscript.toString(callFrame)); + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); CHECK_FOR_EXCEPTION(); result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property); } @@ -3539,7 +3537,7 @@ DEFINE_STUB_FUNCTION(void, op_throw_reference_error) STUB_INIT_STACK_FRAME(stackFrame); CallFrame* callFrame = stackFrame.callFrame; - UString message = stackFrame.args[0].jsValue().toString(callFrame); + UString message = stackFrame.args[0].jsValue().toString(callFrame)->value(callFrame); stackFrame.globalData->exception = createReferenceError(callFrame, message); VM_THROW_EXCEPTION_AT_END(); } diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp index ea32d89..47ec8c6 100644 --- a/Source/JavaScriptCore/jsc.cpp +++ b/Source/JavaScriptCore/jsc.cpp @@ -238,7 +238,7 @@ EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec) if (i) putchar(' '); - printf("%s", exec->argument(i).toString(exec).utf8().data()); + printf("%s", exec->argument(i).toString(exec)->value(exec).utf8().data()); } putchar('\n'); @@ -248,7 +248,7 @@ EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec) EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec) { - fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec).utf8().data()); + fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec)->value(exec).utf8().data()); return JSValue::encode(jsUndefined()); } @@ -277,7 +277,7 @@ EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*) EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec) { - UString fileName = exec->argument(0).toString(exec); + UString fileName = exec->argument(0).toString(exec)->value(exec); Vector script; if (!fillBufferWithContentsOfFile(fileName, script)) return JSValue::encode(throwError(exec, createError(exec, "Could not open file."))); @@ -294,7 +294,7 @@ EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec) EncodedJSValue JSC_HOST_CALL functionLoad(ExecState* exec) { - UString fileName = exec->argument(0).toString(exec); + UString fileName = exec->argument(0).toString(exec)->value(exec); Vector script; if (!fillBufferWithContentsOfFile(fileName, script)) return JSValue::encode(throwError(exec, createError(exec, "Could not open file."))); @@ -310,7 +310,7 @@ EncodedJSValue JSC_HOST_CALL functionLoad(ExecState* exec) EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState* exec) { - UString fileName = exec->argument(0).toString(exec); + UString fileName = exec->argument(0).toString(exec)->value(exec); Vector script; if (!fillBufferWithContentsOfFile(fileName, script)) return JSValue::encode(throwError(exec, createError(exec, "Could not open file."))); @@ -487,9 +487,9 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector