diff --git a/quickjs.c b/quickjs.c index 62f438147..b0aff5234 100644 --- a/quickjs.c +++ b/quickjs.c @@ -20185,7 +20185,7 @@ typedef struct JSFunctionDef { bool need_home_object : 1; bool use_short_opcodes : 1; /* true if short opcodes are used in byte_code */ bool has_await : 1; /* true if await is used (used in module eval) */ - + JSFunctionKindEnum func_kind : 8; JSParseFunctionEnum func_type : 7; uint8_t is_strict_mode : 1; @@ -20344,6 +20344,21 @@ static const JSOpCode opcode_info[OP_COUNT + (OP_TEMP_END - OP_TEMP_START)] = { opcode_info[(op) >= OP_TEMP_START ? \ (op) + (OP_TEMP_END - OP_TEMP_START) : (op)] +static void json_free_token(JSParseState *s, JSToken *token) { + // Only free actual allocated values + switch(token->val) { + case TOK_NUMBER: + JS_FreeValue(s->ctx, token->u.num.val); + break; + case TOK_STRING: + JS_FreeValue(s->ctx, token->u.str.str); + break; + case TOK_IDENT: + JS_FreeAtom(s->ctx, token->u.ident.atom); + break; + } +} + static void free_token(JSParseState *s, JSToken *token) { switch(token->val) { @@ -21425,7 +21440,7 @@ static int json_parse_string(JSParseState *s, const uint8_t **pp) uint32_t c; StringBuffer b_s, *b = &b_s; - if (string_buffer_init(s->ctx, b, 32)) + if (string_buffer_init(s->ctx, b, 48)) goto fail; p = *pp; @@ -21433,6 +21448,22 @@ static int json_parse_string(JSParseState *s, const uint8_t **pp) if (p >= s->buf_end) { goto end_of_input; } + + // Fast path: batch consecutive ASCII characters + const uint8_t *p_start = p; + while (p < s->buf_end && *p != '"' && *p != '\\' && *p >= 0x20 && *p < 0x80) { + p++; + } + + // Write batched ASCII in one call + if (p > p_start) { + if (string_buffer_write8(b, p_start, p - p_start)) + goto fail; + } + + if (p >= s->buf_end) + goto end_of_input; + c = *p++; if (c == '"') break; @@ -21578,7 +21609,7 @@ static __exception int json_next_token(JSParseState *s) return -1; } - free_token(s, &s->token); + json_free_token(s, &s->token); p = s->last_ptr = s->buf_ptr; s->last_line_num = s->token.line_num;