Unroll whitespace-skipping loop

This commit is contained in:
2025-06-23 14:00:29 -04:00
parent 47a418b689
commit 5df9d958ab

View File

@@ -750,17 +750,33 @@ struct Parser3 {
Utf8Dfa strDfa;
};
inline PRESERVE_NONE WeaselJsonStatus skipWhitespace(char *&buf, char *bufEnd) {
constexpr int kStride = 4;
for (;;) {
if (bufEnd - buf < kStride) [[unlikely]] {
while (buf != bufEnd && tables.whitespace[uint8_t(*buf)]) {
++buf;
}
return buf == bufEnd ? WeaselJson_AGAIN : WeaselJson_OK;
}
for (int i = 0; i < kStride; ++i) {
if (tables.whitespace[uint8_t(*buf)]) {
++buf;
} else {
return WeaselJson_OK;
}
}
}
}
inline PRESERVE_NONE WeaselJsonStatus n_whitespace(Parser3 *self, char *buf,
char *bufEnd) {
if (bufEnd - buf == 0) {
if (buf == bufEnd) {
self->pop();
MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd);
}
while (tables.whitespace[uint8_t(*buf)]) {
++buf;
if (buf == bufEnd) {
return WeaselJson_AGAIN;
}
if (auto s = skipWhitespace(buf, bufEnd)) {
return s;
}
self->pop();
MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd);
@@ -856,11 +872,8 @@ inline PRESERVE_NONE WeaselJsonStatus scan_string(Parser3 *self, char *buf,
inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf,
char *bufEnd) {
assert(bufEnd - buf != 0);
while (tables.whitespace[uint8_t(*buf)]) {
++buf;
if (buf == bufEnd) {
return WeaselJson_AGAIN;
}
if (auto s = skipWhitespace(buf, bufEnd)) {
return s;
}
switch (*buf) {
case '{':
@@ -963,11 +976,8 @@ inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf,
inline PRESERVE_NONE WeaselJsonStatus n_object2(Parser3 *self, char *buf,
char *bufEnd) {
assert(bufEnd - buf != 0);
while (tables.whitespace[uint8_t(*buf)]) {
++buf;
if (buf == bufEnd) {
return WeaselJson_AGAIN;
}
if (auto s = skipWhitespace(buf, bufEnd)) {
return s;
}
switch (*buf) {
case '}':
@@ -992,11 +1002,8 @@ inline PRESERVE_NONE WeaselJsonStatus n_object2(Parser3 *self, char *buf,
inline PRESERVE_NONE WeaselJsonStatus n_object3(Parser3 *self, char *buf,
char *bufEnd) {
assert(bufEnd - buf != 0);
while (tables.whitespace[uint8_t(*buf)]) {
++buf;
if (buf == bufEnd) {
return WeaselJson_AGAIN;
}
if (auto s = skipWhitespace(buf, bufEnd)) {
return s;
}
switch (*buf) {
case '}':
@@ -1019,11 +1026,8 @@ inline PRESERVE_NONE WeaselJsonStatus n_object3(Parser3 *self, char *buf,
inline PRESERVE_NONE WeaselJsonStatus n_array2(Parser3 *self, char *buf,
char *bufEnd) {
assert(bufEnd - buf != 0);
while (tables.whitespace[uint8_t(*buf)]) {
++buf;
if (buf == bufEnd) {
return WeaselJson_AGAIN;
}
if (auto s = skipWhitespace(buf, bufEnd)) {
return s;
}
switch (*buf) {
case ']':
@@ -1043,11 +1047,8 @@ inline PRESERVE_NONE WeaselJsonStatus n_array2(Parser3 *self, char *buf,
inline PRESERVE_NONE WeaselJsonStatus n_array3(Parser3 *self, char *buf,
char *bufEnd) {
assert(bufEnd - buf != 0);
while (tables.whitespace[uint8_t(*buf)]) {
++buf;
if (buf == bufEnd) {
return WeaselJson_AGAIN;
}
if (auto s = skipWhitespace(buf, bufEnd)) {
return s;
}
switch (*buf) {
case ']':
@@ -1070,11 +1071,8 @@ inline PRESERVE_NONE WeaselJsonStatus n_array3(Parser3 *self, char *buf,
inline PRESERVE_NONE WeaselJsonStatus n_string(Parser3 *self, char *buf,
char *bufEnd) {
assert(bufEnd - buf != 0);
while (tables.whitespace[uint8_t(*buf)]) {
++buf;
if (buf == bufEnd) {
return WeaselJson_AGAIN;
}
if (auto s = skipWhitespace(buf, bufEnd)) {
return s;
}
if (*buf != '"') [[unlikely]] {
return WeaselJson_REJECT;
@@ -1318,11 +1316,8 @@ inline PRESERVE_NONE WeaselJsonStatus singleChar(Parser3 *self, char *buf,
char *bufEnd) {
if constexpr (kSkipWhitespace) {
assert(bufEnd - buf != 0);
while (tables.whitespace[uint8_t(*buf)]) {
++buf;
if (buf == bufEnd) {
return WeaselJson_AGAIN;
}
if (auto s = skipWhitespace(buf, bufEnd)) {
return s;
}
}
if (*buf == kChar) {