<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [INTL] Implement Collator Compare Functions"
   href="https://bugs.webkit.org/show_bug.cgi?id=147604#c21">Comment # 21</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [INTL] Implement Collator Compare Functions"
   href="https://bugs.webkit.org/show_bug.cgi?id=147604">bug 147604</a>
              from <span class="vcard"><a class="email" href="mailto:sukolsak&#64;gmail.com" title="Sukolsak Sakshuwong &lt;sukolsak&#64;gmail.com&gt;"> <span class="fn">Sukolsak Sakshuwong</span></a>
</span></b>
        <pre>Thanks for the review.

Regarding the string object lifetime bug, it looks like there are a few places in StringPrototype.cpp that do that. For example, <a href="https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/runtime/StringPrototype.cpp#L801">https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/runtime/StringPrototype.cpp#L801</a> Should I file a bug for that?

(In reply to <a href="show_bug.cgi?id=147604#c19">comment #19</a>)
<span class="quote">&gt; Comment on <span class="bz_obsolete"><a href="attachment.cgi?id=267366&amp;action=diff" name="attach_267366" title="Patch">attachment 267366</a> <a href="attachment.cgi?id=267366&amp;action=edit" title="Patch">[details]</a></span>
&gt; Patch
&gt; 
&gt; View in context:
&gt; <a href="https://bugs.webkit.org/attachment.cgi?id=267366&amp;action=review">https://bugs.webkit.org/attachment.cgi?id=267366&amp;action=review</a>
&gt; 
&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:104
&gt; &gt; +        keyLocaleData.append(String());
&gt; 
&gt; Alternate syntax for null in this context is { } rather than String(). I
&gt; slightly prefer the former.</span >

Fixed.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:125
&gt; &gt; +                keyLocaleData.append(String(collation));
&gt; 
&gt; This treats the keyword value strings as ASCII or Latin-1, not UTF-8. Is
&gt; that correct? Also, an explicit conversion to String() is not needed; please
&gt; just write append(collation).
&gt; 
&gt; To create the strings as UTF-8, we would use String::fromUTF8(collation) but
&gt; we also have to consider that the string might be invalid UTF-8 which would
&gt; result in a null string.</span >

Changed to append(collation). collation can only be ASCII. See <a href="show_bug.cgi?id=147604#c13">Comment 13</a> (<a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [INTL] Implement Collator Compare Functions"
   href="show_bug.cgi?id=147604#c13">https://bugs.webkit.org/show_bug.cgi?id=147604#c13</a>).

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:170
&gt; &gt; +    Vector&lt;String&gt; requestedLocales = canonicalizeLocaleList(state, locales);
&gt; 
&gt; I like to use auto for the return value type in a case like this.</span >

Fixed.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:220
&gt; &gt; +    opt.set(ASCIILiteral(&quot;localeMatcher&quot;), matcher);
&gt; 
&gt; More efficient to use the add function here rather than the set function.
&gt; 
&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:241
&gt; &gt; +        opt.set(ASCIILiteral(&quot;kn&quot;), numericString);
&gt; 
&gt; Ditto.
&gt; 
&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:247
&gt; &gt; +        opt.set(ASCIILiteral(&quot;kf&quot;), caseFirst);
&gt; 
&gt; Ditto.</span >

Fixed.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:252
&gt; &gt; +    const HashSet&lt;String&gt;&amp; availableLocales = state.callee()-&gt;globalObject()-&gt;intlCollatorAvailableLocales();
&gt; 
&gt; I like auto&amp; here better for the return type.</span >

Fixed.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:253
&gt; &gt; +    HashMap&lt;String, String&gt; result = resolveLocale(availableLocales, requestedLocales, opt, relevantExtensionKeys, sizeof(relevantExtensionKeys) / sizeof(relevantExtensionKeys[0]), localeData);
&gt; 
&gt; I like auto here better for the return type.
&gt; 
&gt; WTF_ARRAY_LENGTH is preferred over that sizeof expression. Or perhaps we can
&gt; use std::array and use relevantExtensionKeys.size().</span >

Fixed by using auto and WTF_ARRAY_LENGTH.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:329
&gt; &gt; +        ASSERT(!state.hadException());
&gt; 
&gt; Why can we assert this? What guarantees it is true. If we can assert here,
&gt; why can’t we assert along the way doing each step inside initializeCollator
&gt; itself?</span >

The spec guarantees that it is true. According to the steps in ECMA-402, 10.1.1, InitializeCollator (collator, locales, options) will not throw if locales and options are undefined.

Another reason is that the spec says that &quot;The Intl.Collator prototype object is itself an Intl.Collator instance ... whose internal slots are set as if it had been constructed by the expression Construct(%Collator%)&quot;. If InitializeCollator(collator, undefined, undefined) could throw, then Intl.Collator.prototype could throw when it was created, which doesn't make sense.

We can't assert inside initializeCollator because locales and options are not always undefined.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:332
&gt; &gt; +    if (!m_collator) {
&gt; 
&gt; I suggest putting the code to allocate a new collator into a separate
&gt; function. So the code here would be:
&gt; 
&gt;     if (!m_collator) {
&gt;         createCollator();
&gt;         if (!m_collator)
&gt;             return state.vm().throwException(&amp;state, createError(&amp;state,
&gt; ASCIILiteral(&quot;error message here&quot;)));
&gt;     }
&gt; 
&gt; The code to call initializeCollator could also possibly go into the
&gt; createCollator function for the same reason.
&gt; 
&gt; I think this would make this function easier to read and possible even more
&gt; efficient.</span >

Fixed.

<span class="quote">&gt; Is there any other place we can share this code with? It’s pretty long
&gt; winded and I seem to have seen code like this before.</span >

I think this is the only place that uses this code.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.cpp:384
&gt; &gt; +        return state.vm().throwException(&amp;state, createError(&amp;state, ASCIILiteral(&quot;ucol_setAttribute failed.&quot;)));
&gt; 
&gt; This does not seem like an acceptable string for an error seen by the web.
&gt; When would this exception occur? Why is it useful to give the function name
&gt; ucol_setAttribute to the web developer?</span >

Changed the message to &quot;Failed to compare strings.&quot; The ICU spec doesn't say what can cause an error for these functions.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.h:50
&gt; &gt; +    JSValue compareStrings(ExecState&amp;, StringView x, StringView y);
&gt; 
&gt; I don’t think the names “x” and “y” here add anything. Please omit them.
&gt; 
&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.h:67
&gt; &gt; +    enum class Usage {
&gt; &gt; +        Sort,
&gt; &gt; +        Search
&gt; &gt; +    };
&gt; 
&gt; I would find this more readable as a one-liner.
&gt; 
&gt; &gt; Source/JavaScriptCore/runtime/IntlCollator.h:74
&gt; &gt; +    enum class Sensitivity {
&gt; &gt; +        Base,
&gt; &gt; +        Accent,
&gt; &gt; +        Case,
&gt; &gt; +        Variant
&gt; &gt; +    };
&gt; 
&gt; I would find this more readable as a one-liner.</span >

Fixed.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp:98
&gt; &gt; +    StringView x = state-&gt;argument(0).toString(state)-&gt;view(state);
&gt; 
&gt; This won’t work. We are creating a StringView pointing to the result of
&gt; toString, but then the garbage collector is allowed to destroy that object.
&gt; Instead the local variable needs to be of type JSString* and the call to
&gt; view needs to be separate. I suggest calling view in the line that calls
&gt; compareStrings.
&gt; 
&gt; &gt; Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp:104
&gt; &gt; +    StringView y = state-&gt;argument(1).toString(state)-&gt;view(state);
&gt; 
&gt; Ditto.</span >

Fixed.

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlObject.cpp:118
&gt; &gt; +    String locale(uloc_getDefault());
&gt; 
&gt; Is the result of uloc_getDefault guaranteed to be ASCII or Latin-1? Or could
&gt; it be UTF-8? If it’s UTF-8 then we need to write this code differently.</span >

ASCII, according to <a href="http://userguide.icu-project.org/locale">http://userguide.icu-project.org/locale</a>

<span class="quote">&gt; &gt; Source/JavaScriptCore/runtime/IntlObject.cpp:202
&gt; &gt;              state.vm().throwException(&amp;state, createRangeError(&amp;state, String(notFound)));
&gt; 
&gt; This explicit conversion to String should not be needed. Please remove it.
&gt; 
&gt; &gt; Source/JavaScriptCore/runtime/IntlObject.cpp:211
&gt; &gt; -    return fallback;
&gt; &gt; +    return String(fallback);
&gt; 
&gt; This explicit conversion to String should not be needed. Please don’t make
&gt; this change.
&gt; 
&gt; &gt; Source/JavaScriptCore/runtime/IntlObject.cpp:759
&gt; &gt; -                        supportedExtensionAddition = &quot;-&quot; + key + '-' + value;
&gt; &gt; +                        supportedExtensionAddition = String(&quot;-&quot;) + key + '-' + value;
&gt; 
&gt; More efficient idiom for this is:
&gt; 
&gt;     supportedExtensionAddition = makeString('-', key, '-', value);
&gt; 
&gt; Avoids extra work to allocate and destroy a single character string for &quot;-&quot;.</span >

Fixed.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>