Skip to content

Commit

Permalink
Use a lookup table for whitespaces and comments
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Jan 16, 2025
1 parent f34b28d commit 0c7cb79
Showing 1 changed file with 44 additions and 39 deletions.
83 changes: 44 additions & 39 deletions ext/json/ext/parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,58 +442,63 @@ static void raise_parse_error(const char *format, const char *start)
rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr);
}

static inline void
json_eat_whitespace(JSON_ParserState *state) {
while (state->cursor < state->end) {
switch (*state->cursor) {
case ' ':
case '\t':
case '\n':
case '\r':
state->cursor++;
break;
static const bool whitespace[256] = {
[' '] = 1,
['\t'] = 1,
['\n'] = 1,
['\r'] = 1,
['/'] = 1,
};

static void
json_eat_comments(JSON_ParserState *state)
{
if (state->cursor + 1 < state->end) {
switch(state->cursor[1]) {
case '/': {
if (state->cursor + 1 < state->end) {
switch(state->cursor[1]) {
case '/': {
state->cursor = memchr(state->cursor, '\n', state->end - state->cursor);
if (!state->cursor) {
state->cursor = state->end;
} else {
state->cursor++;
}
break;
}
case '*': {
state->cursor += 2;
while (true) {
state->cursor = memchr(state->cursor, '*', state->end - state->cursor);
if (!state->cursor) {
state->cursor = state->end;
break;
} else {
state->cursor++;
if (state->cursor < state->end && *state->cursor == '/') {
state->cursor++;
break;
}
}
}
state->cursor = memchr(state->cursor, '\n', state->end - state->cursor);
if (!state->cursor) {
state->cursor = state->end;
} else {
state->cursor++;
}
break;
}
case '*': {
state->cursor += 2;
while (true) {
state->cursor = memchr(state->cursor, '*', state->end - state->cursor);
if (!state->cursor) {
state->cursor = state->end;
break;
} else {
state->cursor++;
if (state->cursor < state->end && *state->cursor == '/') {
state->cursor++;
break;
}
default:
return;
}
}
break;
}

default:
return;
}
}
}

static inline void
json_eat_whitespace(JSON_ParserState *state)
{
while (state->cursor < state->end && RB_UNLIKELY(whitespace[(unsigned char)*state->cursor])) {
if (RB_LIKELY(*state->cursor != '/')) {
state->cursor++;
} else {
json_eat_comments(state);
}
}
}

static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
{
if (symbolize) {
Expand Down

0 comments on commit 0c7cb79

Please sign in to comment.