Ignore:
Timestamp:
Jan 23, 2012, 11:34:10 PM (13 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/jsc.cpp

    r103691 r105698  
    239239            putchar(' ');
    240240
    241         printf("%s", exec->argument(i).toString(exec).utf8().data());
     241        printf("%s", exec->argument(i).toString(exec)->value(exec).utf8().data());
    242242    }
    243243
     
    249249EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
    250250{
    251     fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec).utf8().data());
     251    fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec)->value(exec).utf8().data());
    252252    return JSValue::encode(jsUndefined());
    253253}
     
    278278EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
    279279{
    280     UString fileName = exec->argument(0).toString(exec);
     280    UString fileName = exec->argument(0).toString(exec)->value(exec);
    281281    Vector<char> script;
    282282    if (!fillBufferWithContentsOfFile(fileName, script))
     
    295295EncodedJSValue JSC_HOST_CALL functionLoad(ExecState* exec)
    296296{
    297     UString fileName = exec->argument(0).toString(exec);
     297    UString fileName = exec->argument(0).toString(exec)->value(exec);
    298298    Vector<char> script;
    299299    if (!fillBufferWithContentsOfFile(fileName, script))
     
    311311EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState* exec)
    312312{
    313     UString fileName = exec->argument(0).toString(exec);
     313    UString fileName = exec->argument(0).toString(exec)->value(exec);
    314314    Vector<char> script;
    315315    if (!fillBufferWithContentsOfFile(fileName, script))
     
    488488        if (dump) {
    489489            if (evaluationException)
    490                 printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec()).utf8().data());
     490                printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
    491491            else
    492                 printf("End: %s\n", returnValue.toString(globalObject->globalExec()).utf8().data());
     492                printf("End: %s\n", returnValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
    493493        }
    494494
     
    547547#endif
    548548        if (evaluationException)
    549             printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec()).utf8().data());
     549            printf("Exception: %s\n", evaluationException.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
    550550        else
    551             printf("%s\n", returnValue.toString(globalObject->globalExec()).utf8().data());
     551            printf("%s\n", returnValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
    552552
    553553        globalObject->globalExec()->clearException();
Note: See TracChangeset for help on using the changeset viewer.