Ignore:
Timestamp:
Jan 23, 2012, 11:34:10 PM (14 years ago)
Author:
[email protected]
Message:

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.


  • 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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r103922 r105698  
    5252static JSValue encode(ExecState* exec, const char* doNotEscape)
    5353{
    54     UString str = exec->argument(0).toString(exec);
    55     CString cstr = str.utf8(true);
     54    CString cstr = exec->argument(0).toString(exec)->value(exec).utf8(true);
    5655    if (!cstr.data())
    5756        return throwError(exec, createURIError(exec, "String contained an illegal UTF-16 sequence."));
     
    144143{
    145144    JSStringBuilder builder;
    146     UString str = exec->argument(0).toString(exec);
     145    UString str = exec->argument(0).toString(exec)->value(exec);
    147146   
    148147    if (str.is8Bit())
     
    514513        return JSValue::encode(x);
    515514
    516     UString s = x.toString(exec);
     515    UString s = x.toString(exec)->value(exec);
    517516
    518517    if (s.is8Bit()) {
     
    557556
    558557    // If ToString throws, we shouldn't call ToInt32.
    559     UString s = value.toString(exec);
     558    UString s = value.toString(exec)->value(exec);
    560559    if (exec->hadException())
    561560        return JSValue::encode(jsUndefined());
     
    566565EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec)
    567566{
    568     return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec))));
     567    return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->value(exec))));
    569568}
    570569
     
    624623
    625624    JSStringBuilder builder;
    626     UString str = exec->argument(0).toString(exec);
     625    UString str = exec->argument(0).toString(exec)->value(exec);
    627626    if (str.is8Bit()) {
    628627        const LChar* c = str.characters8();
     
    663662{
    664663    UStringBuilder builder;
    665     UString str = exec->argument(0).toString(exec);
     664    UString str = exec->argument(0).toString(exec)->value(exec);
    666665    int k = 0;
    667666    int len = str.length();
Note: See TracChangeset for help on using the changeset viewer.