| Index: src/unicode.cc
|
| diff --git a/src/unicode.cc b/src/unicode.cc
|
| index db98be867579740b0e599c84c5b8fc164d834665..9fd39a75ebc6c506d6a42ebf99273d306f6221b6 100644
|
| --- a/src/unicode.cc
|
| +++ b/src/unicode.cc
|
| @@ -190,8 +190,7 @@ static int LookupMapping(const int32_t* table,
|
| }
|
| }
|
|
|
| -
|
| -static inline size_t NonASCIISequenceLength(byte first) {
|
| +static inline uint8_t NonASCIISequenceLength(byte first) {
|
| // clang-format off
|
| static const uint8_t lengths[256] = {
|
| // The first 128 entries correspond to ASCII characters.
|
| @@ -305,6 +304,57 @@ uchar Utf8::CalculateValue(const byte* str, size_t max_length, size_t* cursor) {
|
| 0x03C82080;
|
| }
|
|
|
| +uchar Utf8::ValueOfIncremental(byte next, Utf8IncrementalBuffer* buffer) {
|
| + DCHECK_NOT_NULL(buffer);
|
| +
|
| + // The common case: 1-byte Utf8 (and no incomplete char in the buffer)
|
| + if (V8_LIKELY(next <= kMaxOneByteChar && *buffer == 0)) {
|
| + return static_cast<uchar>(next);
|
| + }
|
| +
|
| + if (*buffer == 0) {
|
| + // We're at the start of a new character.
|
| + uint32_t kind = NonASCIISequenceLength(next);
|
| + if (kind >= 2 && kind <= 4) {
|
| + // Start of 2..4 byte character, and no buffer.
|
| +
|
| + // The mask for the lower bits depends on the kind, and is
|
| + // 0x1F, 0x0F, 0x07 for kinds 2, 3, 4 respectively. We can get that
|
| + // with one shift.
|
| + uint8_t mask = 0x7f >> kind;
|
| +
|
| + // Store the kind - 1 (i.e., remaining bytes) in the top byte, value
|
| + // in the bottom three.
|
| + *buffer = (kind - 1) << 24 | (next & mask);
|
| + return kIncomplete;
|
| + } else {
|
| + // No buffer, and not the start of a 1-byte char (handled at the
|
| + // beginning), and not the start of a 2..4 byte char? Bad char.
|
| + *buffer = 0;
|
| + return kBadChar;
|
| + }
|
| + } else {
|
| + // We're inside of a character, as described by buffer.
|
| + if (IsContinuationCharacter(next)) {
|
| + // How many bytes (excluding this one) do we still expect?
|
| + uint8_t count = (*buffer >> 24) - 1;
|
| + // Update the value.
|
| + uint32_t value = ((*buffer & 0xffffff) << 6) | (next & 0x3F);
|
| + if (count) {
|
| + *buffer = count << 24 | value;
|
| + return kIncomplete;
|
| + } else {
|
| + *buffer = 0;
|
| + return value;
|
| + }
|
| + } else {
|
| + // Within a character, but not a continuation character? Bad char.
|
| + *buffer = 0;
|
| + return kBadChar;
|
| + }
|
| + }
|
| +}
|
| +
|
| bool Utf8::Validate(const byte* bytes, size_t length) {
|
| size_t cursor = 0;
|
|
|
|
|