Skip to content

Commit ca2f1e0

Browse files
committed
Drop String::characters8() / characters16()
https://bugs.webkit.org/show_bug.cgi?id=273352 Reviewed by Sam Weinig and Darin Adler. Drop String::characters8() / characters16(), in favor of span equivalents. * Source/JavaScriptCore/API/OpaqueJSString.cpp: (OpaqueJSString::~OpaqueJSString): * Source/JavaScriptCore/API/OpaqueJSString.h: (OpaqueJSString::OpaqueJSString): * Source/JavaScriptCore/runtime/IntlObjectInlines.h: (JSC::ListFormatInput::ListFormatInput): * Source/JavaScriptCore/runtime/JSONObject.cpp: (JSC::FastStringifier<CharType>::append): * Source/JavaScriptCore/runtime/JSStringJoiner.cpp: (JSC::joinStrings): * Source/JavaScriptCore/runtime/RegExpConstructor.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): * Source/JavaScriptCore/runtime/RegExpInlines.h: (JSC::RegExp::matchInline): * Source/JavaScriptCore/runtime/StringPrototype.cpp: (JSC::jsSpliceSubstrings): (JSC::codePointAt): * Source/JavaScriptCore/runtime/TemplateObjectDescriptor.h: (JSC::TemplateObjectDescriptor::calculateHash): * Source/JavaScriptCore/yarr/YarrJIT.h: (JSC::Yarr::YarrCodeBlock::execute): * Source/WTF/wtf/URLParser.cpp: (WTF::URLParser::copyBaseWindowsDriveLetter): (WTF::URLParser::copyASCIIStringUntil): (WTF::URLParser::URLParser): * Source/WTF/wtf/cf/URLCF.cpp: (WTF::URL::createCFURL const): * Source/WTF/wtf/text/StringBuilder.cpp: (WTF::StringBuilder::reserveCapacity): * Source/WTF/wtf/text/StringBuilder.h: (WTF::StringBuilder::characters const): * Source/WTF/wtf/text/StringBuilderJSON.cpp: (WTF::appendQuotedJSONStringInternal): (WTF::StringBuilder::appendQuotedJSONString): * Source/WTF/wtf/text/WTFString.h: (WTF::String::characters<LChar> const): Deleted. (WTF::String::characters<UChar> const): Deleted. * Source/WebCore/css/CSSVariableData.cpp: (WebCore::CSSVariableData::updateBackingStringsInTokens): * Source/WebCore/dom/make_names.pl: (printTagNameCppFile): (printNodeNameCppFile): * Source/WebCore/editing/MarkupAccumulator.cpp: (WebCore::appendCharactersReplacingEntitiesInternal): * Source/WebCore/editing/TextIterator.cpp: (WebCore::containsKanaLetters): * Source/WebCore/html/track/VTTScanner.cpp: (WebCore::VTTScanner::VTTScanner): * Source/WebCore/inspector/InspectorStyleSheet.cpp: (WebCore::fixUnparsedProperties): (WebCore::StyleSheetHandler::fixUnparsedPropertyRanges): * Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp: (WebCore::Layout::replaceNonPreservedNewLineAndTabCharactersAndAppend): * Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp: (WebCore::Layout::TextUtil::firstUserPerceivedCharacterLength): * Source/WebCore/rendering/LegacyInlineIterator.h: (WebCore::LegacyInlineIterator::incrementByCodePointInTextNode): * Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp: (WebCore::xmlDocPtrForString): * Source/WebGPU/WGSL/Lexer.h: (WGSL::Lexer::Lexer): * Source/WebKit/NetworkProcess/cache/NetworkCacheKey.cpp: (WebKit::NetworkCache::hexDigitsToHash): (WebKit::NetworkCache::Key::stringToHash): * Source/WebKit/Platform/IPC/ArgumentCoders.cpp: (IPC::ArgumentCoder<String>::encode): * Source/WebKit/Shared/API/c/cf/WKStringCF.mm: (WKStringCopyCFString): Canonical link: https://commits.webkit.org/278082@main
1 parent 1dd6d95 commit ca2f1e0

34 files changed

Lines changed: 148 additions & 159 deletions

Source/JavaScriptCore/API/OpaqueJSString.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ OpaqueJSString::~OpaqueJSString()
5555
if (!characters)
5656
return;
5757

58-
if (!m_string.is8Bit() && m_string.characters16() == characters)
58+
if (!m_string.is8Bit() && m_string.span16().data() == characters)
5959
return;
6060

6161
fastFree(characters);

Source/JavaScriptCore/API/OpaqueJSString.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
7878

7979
OpaqueJSString(const String& string)
8080
: m_string(string.isolatedCopy())
81-
, m_characters(m_string.impl() && m_string.is8Bit() ? nullptr : const_cast<UChar*>(m_string.characters16()))
81+
, m_characters(m_string.impl() && m_string.is8Bit() ? nullptr : const_cast<UChar*>(m_string.span16().data()))
8282
{
8383
}
8484

8585
explicit OpaqueJSString(String&& string)
8686
: m_string(WTFMove(string))
87-
, m_characters(m_string.impl() && m_string.is8Bit() ? nullptr : const_cast<UChar*>(m_string.characters16()))
87+
, m_characters(m_string.impl() && m_string.is8Bit() ? nullptr : const_cast<UChar*>(m_string.span16().data()))
8888
{
8989
}
9090

@@ -96,7 +96,7 @@ struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
9696

9797
OpaqueJSString(std::span<const UChar> characters)
9898
: m_string(characters)
99-
, m_characters(m_string.impl() && m_string.is8Bit() ? nullptr : const_cast<UChar*>(m_string.characters16()))
99+
, m_characters(m_string.impl() && m_string.is8Bit() ? nullptr : const_cast<UChar*>(m_string.span16().data()))
100100
{
101101
}
102102

Source/JavaScriptCore/runtime/IntlObjectInlines.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ class ListFormatInput {
352352
m_stringLengths.reserveInitialCapacity(m_strings.size());
353353
for (auto& string : m_strings) {
354354
string.convertTo16Bit();
355-
m_stringPointers.append(string.characters16());
355+
m_stringPointers.append(string.span16().data());
356356
m_stringLengths.append(string.length());
357357
}
358358
}

Source/JavaScriptCore/runtime/JSONObject.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,9 +1072,7 @@ void FastStringifier<CharType>::append(JSValue value)
10721072
}
10731073
auto* cursor = m_buffer + m_length;
10741074
*cursor++ = '"';
1075-
auto* characters = string.characters8();
1076-
for (unsigned i = 0; i < stringLength; ++i) {
1077-
auto character = characters[i];
1075+
for (auto character : string.span8()) {
10781076
if (UNLIKELY(WTF::escapedFormsForJSON[character])) {
10791077
recordFailure("string character needs escaping"_s);
10801078
return;
@@ -1092,19 +1090,15 @@ void FastStringifier<CharType>::append(JSValue value)
10921090
auto* cursor = m_buffer + m_length;
10931091
*cursor++ = '"';
10941092
if (string.is8Bit()) {
1095-
auto* characters = string.characters8();
1096-
for (unsigned i = 0; i < stringLength; ++i) {
1097-
auto character = characters[i];
1093+
for (auto character : string.span8()) {
10981094
if (UNLIKELY(WTF::escapedFormsForJSON[character])) {
10991095
recordFailure("string character needs escaping"_s);
11001096
return;
11011097
}
11021098
*cursor++ = character;
11031099
}
11041100
} else {
1105-
auto* characters = string.characters16();
1106-
for (unsigned i = 0; i < stringLength; ++i) {
1107-
auto character = characters[i];
1101+
for (auto character : string.span16()) {
11081102
if (UNLIKELY(U16_IS_SURROGATE(character))) {
11091103
recordFailure("string character is surrogate"_s);
11101104
return;

Source/JavaScriptCore/runtime/JSStringJoiner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static inline String joinStrings(const JSStringJoiner::Entries& strings, std::sp
157157
break;
158158
}
159159
}
160-
ASSERT(data == result.characters<OutputCharacterType>() + joinedLength);
160+
ASSERT(data == result.span<OutputCharacterType>().data() + joinedLength);
161161

162162
return result;
163163
}

Source/JavaScriptCore/runtime/RegExpConstructor.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,11 @@ JSC_DEFINE_HOST_FUNCTION(regExpConstructorEscape, (JSGlobalObject* globalObject,
120120
for (unsigned i = 0; i < string.length();) {
121121
char32_t codePoint;
122122
if (string.is8Bit())
123-
codePoint = string.characters8()[i++];
124-
else
125-
U16_NEXT(string.characters16(), i, string.length(), codePoint);
123+
codePoint = string.span8()[i++];
124+
else {
125+
auto characters = string.span16();
126+
U16_NEXT(characters, i, string.length(), codePoint);
127+
}
126128

127129
if (builder.isEmpty() && isASCIIAlphanumeric(codePoint)) {
128130
builder.append('\\', 'x', toStringWithRadix(codePoint, 16));

Source/JavaScriptCore/runtime/RegExpInlines.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ ALWAYS_INLINE int RegExp::matchInline(JSGlobalObject* nullOrGlobalObject, VM& vm
139139
Yarr::MatchingContextHolder regExpContext(vm, m_regExpJITCode->usesPatternContextBuffer(), this, matchFrom);
140140

141141
if (s.is8Bit())
142-
result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), offsetVector, &regExpContext).start;
142+
result = m_regExpJITCode->execute(s.span8(), startOffset, offsetVector, &regExpContext).start;
143143
else
144-
result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), offsetVector, &regExpContext).start;
144+
result = m_regExpJITCode->execute(s.span16(), startOffset, offsetVector, &regExpContext).start;
145145
}
146146

147147
if (result == static_cast<int>(Yarr::JSRegExpResult::JITCodeFailure)) {
@@ -275,9 +275,9 @@ ALWAYS_INLINE MatchResult RegExp::matchInline(JSGlobalObject* nullOrGlobalObject
275275
Yarr::MatchingContextHolder regExpContext(vm, m_regExpJITCode->usesPatternContextBuffer(), this, matchFrom);
276276

277277
if (s.is8Bit())
278-
result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), &regExpContext);
278+
result = m_regExpJITCode->execute(s.span8(), startOffset, &regExpContext);
279279
else
280-
result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), &regExpContext);
280+
result = m_regExpJITCode->execute(s.span16(), startOffset, &regExpContext);
281281
}
282282

283283
#if ENABLE(REGEXP_TRACING)

Source/JavaScriptCore/runtime/StringPrototype.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -282,15 +282,15 @@ void substituteBackreferences(StringBuilder& result, const String& replacement,
282282
substituteBackreferencesInline(result, replacement, source, ovector, reg);
283283
}
284284

285-
static ALWAYS_INLINE JSString* jsSpliceSubstrings(JSGlobalObject* globalObject, JSString* sourceVal, const String& source, const Range<int32_t>* substringRanges, int rangeCount)
285+
static ALWAYS_INLINE JSString* jsSpliceSubstrings(JSGlobalObject* globalObject, JSString* sourceVal, const String& source, std::span<const Range<int32_t>> substringRanges)
286286
{
287287
VM& vm = globalObject->vm();
288288
auto scope = DECLARE_THROW_SCOPE(vm);
289289

290-
if (rangeCount == 1) {
290+
if (substringRanges.size() == 1) {
291291
int sourceSize = source.length();
292-
int position = substringRanges[0].begin();
293-
int length = substringRanges[0].distance();
292+
int position = substringRanges.front().begin();
293+
int length = substringRanges.front().distance();
294294
if (position <= 0 && length >= sourceSize)
295295
return sourceVal;
296296
// We could call String::substringSharingImpl(), but this would result in redundant checks.
@@ -302,45 +302,45 @@ static ALWAYS_INLINE JSString* jsSpliceSubstrings(JSGlobalObject* globalObject,
302302
// in removeUsingRegExpSearch(). Hence, totalLength cannot exceed
303303
// String::MaxLength, and therefore, cannot overflow.
304304
Checked<int, AssertNoOverflow> totalLength = 0;
305-
for (int i = 0; i < rangeCount; i++)
306-
totalLength += substringRanges[i].distance();
305+
for (auto& range : substringRanges)
306+
totalLength += range.distance();
307307
ASSERT(totalLength <= static_cast<int>(String::MaxLength));
308308

309309
if (!totalLength)
310310
return jsEmptyString(vm);
311311

312312
if (source.is8Bit()) {
313313
LChar* buffer;
314-
const LChar* sourceData = source.characters8();
314+
auto sourceData = source.span8();
315315
auto impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
316316
if (!impl) {
317317
throwOutOfMemoryError(globalObject, scope);
318318
return nullptr;
319319
}
320320

321-
Checked<int, AssertNoOverflow> bufferPos = 0;
322-
for (int i = 0; i < rangeCount; i++) {
323-
int srcLen = substringRanges[i].distance();
324-
StringImpl::copyCharacters(buffer + bufferPos.value(), { sourceData + substringRanges[i].begin(), static_cast<size_t>(srcLen) });
321+
Checked<size_t, AssertNoOverflow> bufferPos = 0;
322+
for (auto range : substringRanges) {
323+
size_t srcLen = range.distance();
324+
StringImpl::copyCharacters(buffer + bufferPos.value(), sourceData.subspan(range.begin(), srcLen));
325325
bufferPos += srcLen;
326326
}
327327

328328
RELEASE_AND_RETURN(scope, jsString(vm, impl.releaseNonNull()));
329329
}
330330

331331
UChar* buffer;
332-
const UChar* sourceData = source.characters16();
332+
auto sourceData = source.span16();
333333

334334
auto impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
335335
if (!impl) {
336336
throwOutOfMemoryError(globalObject, scope);
337337
return nullptr;
338338
}
339339

340-
Checked<int, AssertNoOverflow> bufferPos = 0;
341-
for (int i = 0; i < rangeCount; i++) {
342-
int srcLen = substringRanges[i].distance();
343-
StringImpl::copyCharacters(buffer + bufferPos.value(), { sourceData + substringRanges[i].begin(), static_cast<size_t>(srcLen) });
340+
Checked<size_t, AssertNoOverflow> bufferPos = 0;
341+
for (auto& range : substringRanges) {
342+
size_t srcLen = range.distance();
343+
StringImpl::copyCharacters(buffer + bufferPos.value(), sourceData.subspan(range.begin(), srcLen));
344344
bufferPos += srcLen;
345345
}
346346

@@ -392,7 +392,7 @@ static ALWAYS_INLINE JSString* removeUsingRegExpSearch(VM& vm, JSGlobalObject* g
392392
if (UNLIKELY(!sourceRanges.tryConstructAndAppend(lastIndex, sourceLen)))
393393
OUT_OF_MEMORY(globalObject, scope);
394394
}
395-
RELEASE_AND_RETURN(scope, jsSpliceSubstrings(globalObject, string, source, sourceRanges.data(), sourceRanges.size()));
395+
RELEASE_AND_RETURN(scope, jsSpliceSubstrings(globalObject, string, source, sourceRanges.span()));
396396
}
397397

398398
static ALWAYS_INLINE JSString* replaceUsingRegExpSearchWithCache(VM& vm, JSGlobalObject* globalObject, JSString* string, const String& source, RegExp* regExp, JSFunction* replaceFunction)
@@ -1028,9 +1028,10 @@ static inline char32_t codePointAt(const String& string, unsigned position, unsi
10281028
{
10291029
RELEASE_ASSERT(position < length);
10301030
if (string.is8Bit())
1031-
return string.characters8()[position];
1031+
return string.span8()[position];
10321032
char32_t character;
1033-
U16_NEXT(string.characters16(), position, length, character);
1033+
auto characters = string.span16();
1034+
U16_NEXT(characters, position, length, character);
10341035
return character;
10351036
}
10361037

Source/JavaScriptCore/runtime/TemplateObjectDescriptor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ inline unsigned TemplateObjectDescriptor::calculateHash(const StringVector& rawS
100100
SuperFastHash hasher;
101101
for (const String& string : rawStrings) {
102102
if (string.is8Bit())
103-
hasher.addCharacters(string.characters8(), string.length());
103+
hasher.addCharacters(string.span8());
104104
else
105-
hasher.addCharacters(string.characters16(), string.length());
105+
hasher.addCharacters(string.span16());
106106
}
107107
return hasher.hash();
108108
}

Source/JavaScriptCore/yarr/YarrJIT.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -330,44 +330,44 @@ class YarrCodeBlock : public YarrBoyerMooreData {
330330
InlineStats& get8BitInlineStats() { return m_matchOnly8Stats; }
331331
InlineStats& get16BitInlineStats() { return m_matchOnly16Stats; }
332332

333-
MatchResult execute(const LChar* input, unsigned start, unsigned length, int* output, MatchingContextHolder* matchingContext)
333+
MatchResult execute(std::span<const LChar> input, unsigned start, int* output, MatchingContextHolder* matchingContext)
334334
{
335335
ASSERT(has8BitCode());
336336
#if CPU(ARM64E)
337337
if (Options::useJITCage())
338-
return MatchResult(vmEntryToYarrJIT(input, start, length, output, matchingContext, retagCodePtr<Yarr8BitPtrTag, YarrEntryPtrTag>(m_ref8.code().taggedPtr())));
338+
return MatchResult(vmEntryToYarrJIT(input.data(), start, input.size(), output, matchingContext, retagCodePtr<Yarr8BitPtrTag, YarrEntryPtrTag>(m_ref8.code().taggedPtr())));
339339
#endif
340-
return MatchResult(untagCFunctionPtr<YarrJITCode8, Yarr8BitPtrTag>(m_ref8.code().taggedPtr())(input, start, length, output, matchingContext));
340+
return MatchResult(untagCFunctionPtr<YarrJITCode8, Yarr8BitPtrTag>(m_ref8.code().taggedPtr())(input.data(), start, input.size(), output, matchingContext));
341341
}
342342

343-
MatchResult execute(const UChar* input, unsigned start, unsigned length, int* output, MatchingContextHolder* matchingContext)
343+
MatchResult execute(std::span<const UChar> input, unsigned start, int* output, MatchingContextHolder* matchingContext)
344344
{
345345
ASSERT(has16BitCode());
346346
#if CPU(ARM64E)
347347
if (Options::useJITCage())
348-
return MatchResult(vmEntryToYarrJIT(input, start, length, output, matchingContext, retagCodePtr<Yarr16BitPtrTag, YarrEntryPtrTag>(m_ref16.code().taggedPtr())));
348+
return MatchResult(vmEntryToYarrJIT(input.data(), start, input.size(), output, matchingContext, retagCodePtr<Yarr16BitPtrTag, YarrEntryPtrTag>(m_ref16.code().taggedPtr())));
349349
#endif
350-
return MatchResult(untagCFunctionPtr<YarrJITCode16, Yarr16BitPtrTag>(m_ref16.code().taggedPtr())(input, start, length, output, matchingContext));
350+
return MatchResult(untagCFunctionPtr<YarrJITCode16, Yarr16BitPtrTag>(m_ref16.code().taggedPtr())(input.data(), start, input.size(), output, matchingContext));
351351
}
352352

353-
MatchResult execute(const LChar* input, unsigned start, unsigned length, MatchingContextHolder* matchingContext)
353+
MatchResult execute(std::span<const LChar> input, unsigned start, MatchingContextHolder* matchingContext)
354354
{
355355
ASSERT(has8BitCodeMatchOnly());
356356
#if CPU(ARM64E)
357357
if (Options::useJITCage())
358-
return MatchResult(vmEntryToYarrJIT(input, start, length, nullptr, matchingContext, retagCodePtr<YarrMatchOnly8BitPtrTag, YarrEntryPtrTag>(m_matchOnly8.code().taggedPtr())));
358+
return MatchResult(vmEntryToYarrJIT(input.data(), start, input.size(), nullptr, matchingContext, retagCodePtr<YarrMatchOnly8BitPtrTag, YarrEntryPtrTag>(m_matchOnly8.code().taggedPtr())));
359359
#endif
360-
return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly8, YarrMatchOnly8BitPtrTag>(m_matchOnly8.code().taggedPtr())(input, start, length, nullptr, matchingContext));
360+
return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly8, YarrMatchOnly8BitPtrTag>(m_matchOnly8.code().taggedPtr())(input.data(), start, input.size(), nullptr, matchingContext));
361361
}
362362

363-
MatchResult execute(const UChar* input, unsigned start, unsigned length, MatchingContextHolder* matchingContext)
363+
MatchResult execute(std::span<const UChar> input, unsigned start, MatchingContextHolder* matchingContext)
364364
{
365365
ASSERT(has16BitCodeMatchOnly());
366366
#if CPU(ARM64E)
367367
if (Options::useJITCage())
368-
return MatchResult(vmEntryToYarrJIT(input, start, length, nullptr, matchingContext, retagCodePtr<YarrMatchOnly16BitPtrTag, YarrEntryPtrTag>(m_matchOnly16.code().taggedPtr())));
368+
return MatchResult(vmEntryToYarrJIT(input.data(), start, input.size(), nullptr, matchingContext, retagCodePtr<YarrMatchOnly16BitPtrTag, YarrEntryPtrTag>(m_matchOnly16.code().taggedPtr())));
369369
#endif
370-
return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly16, YarrMatchOnly16BitPtrTag>(m_matchOnly16.code().taggedPtr())(input, start, length, nullptr, matchingContext));
370+
return MatchResult(untagCFunctionPtr<YarrJITCodeMatchOnly16, YarrMatchOnly16BitPtrTag>(m_matchOnly16.code().taggedPtr())(input.data(), start, input.size(), nullptr, matchingContext));
371371
}
372372

373373
#if ENABLE(REGEXP_TRACING)

0 commit comments

Comments
 (0)