blob: e00abc4d7f7fded1cbb68473ff5863985dd1669f [file] [log] [blame]
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include 'src/builtins/builtins-string-gen.h'
namespace runtime {
extern runtime StringToWellFormed(Context, String): String;
}
namespace string {
extern macro StringBuiltinsAssembler::ReplaceUnpairedSurrogates(
String, String): void labels Indirect;
@incrementUseCounter('v8::Isolate::kStringWellFormed')
transitioning javascript builtin StringPrototypeToWellFormed(
js-implicit context: NativeContext, receiver: JSAny)(
...arguments): String {
const methodName: constexpr string = 'String.prototype.toWellFormed';
// 1. Let O be ? RequireObjectCoercible(this value).
// 2. Let S be ? ToString(O).
const s = ToThisString(receiver, methodName);
// Fast path: one-byte strings cannot have unpaired surrogates and are
// definitionally well-formed.
if (s.StringInstanceType().is_one_byte) return s;
// 3. Let strLen be the length of S.
const strLen = s.length_uint32;
// 4. Let k be 0.
// 5. Let result be the empty String.
const flat = Flatten(s);
if (flat.IsOneByteRepresentation()) return flat;
let result = flat;
// 6. Repeat, while k < strLen,
// a. Let cp be CodePointAt(S, k).
// b. If cp.[[IsUnpairedSurrogate]] is true, then
// i. Set result to the string-concatenation of result and
// 0xFFFD (REPLACEMENT CHARACTER).
// c. Else,
// i. Set result to the string-concatenation of result and
// UTF16EncodeCodePoint(cp.[[CodePoint]]).
// d. Set k to k + cp.[[CodeUnitCount]].
try {
const illFormed = HasUnpairedSurrogate(flat) otherwise Indirect;
if (illFormed) {
result = AllocateSeqTwoByteString(strLen);
ReplaceUnpairedSurrogates(flat, result) otherwise Indirect;
}
// 7. Return result.
return result;
} label Indirect deferred {
return runtime::StringToWellFormed(context, flat);
}
}
}