···4545DEF(save_end, 2) /* save end position, must come after saved_start */
4646DEF(save_reset, 3) /* reset save positions */
4747DEF(loop, 6) /* decrement the top the stack and goto if != 0 */
4848-DEF(loop_split_goto_first, 10)
4848+DEF(loop_split_goto_first, 10) /* loop and then split */
4949DEF(loop_split_next_first, 10)
5050-DEF(loop_check_adv_split_goto_first, 10)
5050+DEF(loop_check_adv_split_goto_first, 10) /* loop and then check advance and split */
5151DEF(loop_check_adv_split_next_first, 10)
5252-DEF(push_i32, 6) /* push integer on the stack */
5252+DEF(set_i32, 6) /* store the immediate value to a register */
5353DEF(word_boundary, 1)
5454DEF(word_boundary_i, 1)
5555DEF(not_word_boundary, 1)
···6464DEF(range32_i, 3) /* variable length */
6565DEF(lookahead, 5)
6666DEF(negative_lookahead, 5) /* must come after */
6767-DEF(push_char_pos, 2) /* push the character position on the stack */
6868-DEF(check_advance, 2) /* pop one stack element and check that it is different from the character position */
6767+DEF(set_char_pos, 2) /* store the character position to a register */
6868+DEF(check_advance, 2) /* check that the register is different from the character position */
6969DEF(prev, 1) /* go to the previous char */
70707171#endif /* DEF */
+55-54
vendor/git/quickjs-c/libregexp.c
···5555} REOPCodeEnum;
56565757#define CAPTURE_COUNT_MAX 255
5858-#define STACK_SIZE_MAX 255
5858+#define REGISTER_COUNT_MAX 255
5959/* must be large enough to have a negligible runtime cost and small
6060 enough to call the interrupt callback often. */
6161#define INTERRUPT_COUNTER_INIT 10000
···105105#undef DEF
106106};
107107108108-#define RE_HEADER_FLAGS 0
109109-#define RE_HEADER_CAPTURE_COUNT 2
110110-#define RE_HEADER_STACK_SIZE 3
111111-#define RE_HEADER_BYTECODE_LEN 4
108108+#define RE_HEADER_FLAGS 0
109109+#define RE_HEADER_CAPTURE_COUNT 2
110110+#define RE_HEADER_REGISTER_COUNT 3
111111+#define RE_HEADER_BYTECODE_LEN 4
112112113113#define RE_HEADER_LEN 8
114114···468468 re_flags = lre_get_flags(buf);
469469 bc_len = get_u32(buf + RE_HEADER_BYTECODE_LEN);
470470 assert(bc_len + RE_HEADER_LEN <= buf_len);
471471- printf("flags: 0x%x capture_count=%d aux_stack_size=%d\n",
472472- re_flags, buf[RE_HEADER_CAPTURE_COUNT], buf[RE_HEADER_STACK_SIZE]);
471471+ printf("flags: 0x%x capture_count=%d reg_count=%d\n",
472472+ re_flags, buf[RE_HEADER_CAPTURE_COUNT], buf[RE_HEADER_REGISTER_COUNT]);
473473 if (re_flags & LRE_FLAG_NAMED_GROUPS) {
474474 const char *p;
475475 p = (char *)buf + RE_HEADER_LEN + bc_len;
···530530 val2 = buf[pos + 1];
531531 val = get_u32(buf + pos + 2);
532532 val += (pos + 6);
533533- printf(" %u, %u", val2, val);
533533+ printf(" r%u, %u", val2, val);
534534 break;
535535 case REOP_loop_split_goto_first:
536536 case REOP_loop_split_next_first:
···542542 limit = get_u32(buf + pos + 2);
543543 val = get_u32(buf + pos + 6);
544544 val += (pos + 10);
545545- printf(" %u, %u, %u", val2, limit, val);
545545+ printf(" r%u, %u, %u", val2, limit, val);
546546 }
547547 break;
548548 case REOP_save_start:
···556556 case REOP_save_reset:
557557 printf(" %u %u", buf[pos + 1], buf[pos + 2]);
558558 break;
559559- case REOP_push_i32:
559559+ case REOP_set_i32:
560560 val = buf[pos + 1];
561561 val2 = get_u32(buf + pos + 2);
562562- printf(" %u, %d", val, val2);
562562+ printf(" r%u, %d", val, val2);
563563 break;
564564- case REOP_push_char_pos:
564564+ case REOP_set_char_pos:
565565 case REOP_check_advance:
566566 val = buf[pos + 1];
567567- printf(" %u", val);
567567+ printf(" r%u", val);
568568 break;
569569 case REOP_range:
570570 case REOP_range_i:
···15701570 case REOP_line_start_m:
15711571 case REOP_line_end:
15721572 case REOP_line_end_m:
15731573- case REOP_push_i32:
15741574- case REOP_push_char_pos:
15731573+ case REOP_set_i32:
15741574+ case REOP_set_char_pos:
15751575 case REOP_word_boundary:
15761576 case REOP_word_boundary_i:
15771577 case REOP_not_word_boundary:
···21972197 put_u32(s->byte_code.buf + last_atom_start + 1,
21982198 len + 5 * has_goto + add_zero_advance_check * 2 * 2);
21992199 if (add_zero_advance_check) {
22002200- s->byte_code.buf[last_atom_start + 1 + 4] = REOP_push_char_pos;
22002200+ s->byte_code.buf[last_atom_start + 1 + 4] = REOP_set_char_pos;
22012201 s->byte_code.buf[last_atom_start + 1 + 4 + 1] = 0;
22022202 re_emit_op_u8(s, REOP_check_advance, 0);
22032203 }
···22112211 put_u32(s->byte_code.buf + pos, 6 + add_zero_advance_check * 2 + len + 10);
22122212 pos += 4;
2213221322142214- s->byte_code.buf[pos++] = REOP_push_i32;
22142214+ s->byte_code.buf[pos++] = REOP_set_i32;
22152215 s->byte_code.buf[pos++] = 0;
22162216 put_u32(s->byte_code.buf + pos, quant_max);
22172217 pos += 4;
22182218 last_atom_start = pos;
22192219 if (add_zero_advance_check) {
22202220- s->byte_code.buf[pos++] = REOP_push_char_pos;
22202220+ s->byte_code.buf[pos++] = REOP_set_char_pos;
22212221 s->byte_code.buf[pos++] = 0;
22222222 }
22232223 re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max, last_atom_start);
···22332233 goto out_of_memory;
22342234 /* Note: we assume the string length is < INT32_MAX */
22352235 pos = last_atom_start;
22362236- s->byte_code.buf[pos++] = REOP_push_i32;
22362236+ s->byte_code.buf[pos++] = REOP_set_i32;
22372237 s->byte_code.buf[pos++] = 0;
22382238 put_u32(s->byte_code.buf + pos, quant_max);
22392239 pos += 4;
22402240 last_atom_start = pos;
22412241 if (add_zero_advance_check) {
22422242- s->byte_code.buf[pos++] = REOP_push_char_pos;
22422242+ s->byte_code.buf[pos++] = REOP_set_char_pos;
22432243 s->byte_code.buf[pos++] = 0;
22442244 }
22452245 if (quant_min == quant_max) {
···23302330 return 0;
23312331}
2332233223332333-/* the control flow is recursive so the analysis can be linear. As a
23342334- side effect, the auxiliary stack addresses are computed. */
23352335-static int compute_stack_size(uint8_t *bc_buf, int bc_buf_len)
23332333+/* Allocate the registers as a stack. The control flow is recursive so
23342334+ the analysis can be linear. */
23352335+static int compute_register_count(uint8_t *bc_buf, int bc_buf_len)
23362336{
23372337 int stack_size, stack_size_max, pos, opcode, len;
23382338 uint32_t val;
···23482348 assert(opcode < REOP_COUNT);
23492349 assert((pos + len) <= bc_buf_len);
23502350 switch(opcode) {
23512351- case REOP_push_i32:
23522352- case REOP_push_char_pos:
23512351+ case REOP_set_i32:
23522352+ case REOP_set_char_pos:
23532353 bc_buf[pos + 1] = stack_size;
23542354 stack_size++;
23552355 if (stack_size > stack_size_max) {
23562356- if (stack_size > STACK_SIZE_MAX)
23562356+ if (stack_size > REGISTER_COUNT_MAX)
23572357 return -1;
23582358 stack_size_max = stack_size;
23592359 }
···24082408 void *opaque)
24092409{
24102410 REParseState s_s, *s = &s_s;
24112411- int stack_size;
24112411+ int register_count;
24122412 BOOL is_sticky;
2413241324142414 memset(s, 0, sizeof(*s));
···24692469 goto error;
24702470 }
2471247124722472- stack_size = compute_stack_size(s->byte_code.buf, s->byte_code.size);
24732473- if (stack_size < 0) {
24722472+ register_count = compute_register_count(s->byte_code.buf, s->byte_code.size);
24732473+ if (register_count < 0) {
24742474 re_parse_error(s, "too many imbricated quantifiers");
24752475 goto error;
24762476 }
2477247724782478 s->byte_code.buf[RE_HEADER_CAPTURE_COUNT] = s->capture_count;
24792479- s->byte_code.buf[RE_HEADER_STACK_SIZE] = stack_size;
24792479+ s->byte_code.buf[RE_HEADER_REGISTER_COUNT] = register_count;
24802480 put_u32(s->byte_code.buf + RE_HEADER_BYTECODE_LEN,
24812481 s->byte_code.size - RE_HEADER_LEN);
24822482···26202620 /* 0 = 8 bit chars, 1 = 16 bit chars, 2 = 16 bit chars, UTF-16 */
26212621 int cbuf_type;
26222622 int capture_count;
26232623- int stack_size_max;
26242623 BOOL is_unicode;
26252624 int interrupt_counter;
26262625 void *opaque; /* used for stack overflow check */
···2665266426662665/* return 1 if match, 0 if not match or < 0 if error. */
26672666static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
26682668- uint8_t **aux_stack, const uint8_t *pc, const uint8_t *cptr)
26672667+ uint8_t **regs, const uint8_t *pc, const uint8_t *cptr)
26692668{
26702669 int opcode;
26712670 int cbuf_type;
···27052704 }
2706270527072706 /* avoid saving the previous value if already saved */
27082708-#define SAVE_AUX_STACK(idx, value) \
27072707+#define SAVE_REG(idx, value) \
27092708 { \
27102709 StackElem *sp1; \
27112710 sp1 = sp; \
···27172716 } else { \
27182717 CHECK_STACK_SPACE(2); \
27192718 sp[0].val = -(int)(idx + 1); \
27202720- sp[1].ptr = aux_stack[idx]; \
27192719+ sp[1].ptr = regs[idx]; \
27212720 sp += 2; \
27222721 break; \
27232722 } \
27242723 } \
27252725- aux_stack[idx] = (value); \
27242724+ regs[idx] = (value); \
27262725 }
2727272627282727···27472746 REExecStateEnum type;
27482747 if (bp == s->stack_buf)
27492748 return 0;
27502750- /* undo the modifications to capture[] and aux_stack[] */
27492749+ /* undo the modifications to capture[] and regs[] */
27512750 while (sp > bp) {
27522751 intptr_t idx2 = sp[-2].val;
27532752 if (idx2 >= 0)
27542753 capture[idx2] = sp[-1].ptr;
27552754 else
27562756- aux_stack[-idx2 - 1] = sp[-1].ptr;
27552755+ regs[-idx2 - 1] = sp[-1].ptr;
27572756 sp -= 2;
27582757 }
27592758···28042803 for(;;) {
28052804 REExecStateEnum type;
28062805 type = bp[-1].bp.type;
28072807- /* undo the modifications to capture[] and aux_stack[] */
28062806+ /* undo the modifications to capture[] and regs[] */
28082807 while (sp > bp) {
28092808 intptr_t idx2 = sp[-2].val;
28102809 if (idx2 >= 0)
28112810 capture[idx2] = sp[-1].ptr;
28122811 else
28132813- aux_stack[-idx2 - 1] = sp[-1].ptr;
28122812+ regs[-idx2 - 1] = sp[-1].ptr;
28142813 sp -= 2;
28152814 }
28162815 pc = sp[-3].ptr;
···29502949 }
29512950 }
29522951 break;
29532953- case REOP_push_i32:
29522952+ case REOP_set_i32:
29542953 idx = pc[0];
29552954 val = get_u32(pc + 1);
29562955 pc += 5;
29572957- SAVE_AUX_STACK(idx, (void *)(uintptr_t)val);
29562956+ SAVE_REG(idx, (void *)(uintptr_t)val);
29582957 break;
29592958 case REOP_loop:
29602959 {
···29632962 val = get_u32(pc + 1);
29642963 pc += 5;
2965296429662966- val2 = (uintptr_t)aux_stack[idx] - 1;
29672967- SAVE_AUX_STACK(idx, (void *)(uintptr_t)val2);
29652965+ val2 = (uintptr_t)regs[idx] - 1;
29662966+ SAVE_REG(idx, (void *)(uintptr_t)val2);
29682967 if (val2 != 0) {
29692968 pc += (int)val;
29702969 if (lre_poll_timeout(s))
···29852984 pc += 9;
2986298529872986 /* decrement the counter */
29882988- val2 = (uintptr_t)aux_stack[idx] - 1;
29892989- SAVE_AUX_STACK(idx, (void *)(uintptr_t)val2);
29872987+ val2 = (uintptr_t)regs[idx] - 1;
29882988+ SAVE_REG(idx, (void *)(uintptr_t)val2);
2990298929912990 if (val2 > limit) {
29922991 /* normal loop if counter > limit */
···29972996 /* check advance */
29982997 if ((opcode == REOP_loop_check_adv_split_goto_first ||
29992998 opcode == REOP_loop_check_adv_split_next_first) &&
30003000- aux_stack[idx + 1] == cptr &&
29992999+ regs[idx + 1] == cptr &&
30013000 val2 != limit) {
30023001 goto no_match;
30033002 }
···30223021 }
30233022 }
30243023 break;
30253025- case REOP_push_char_pos:
30243024+ case REOP_set_char_pos:
30263025 idx = pc[0];
30273026 pc++;
30283028- SAVE_AUX_STACK(idx, (uint8_t *)cptr);
30273027+ SAVE_REG(idx, (uint8_t *)cptr);
30293028 break;
30303029 case REOP_check_advance:
30313030 idx = pc[0];
30323031 pc++;
30333033- if (aux_stack[idx] == cptr)
30323032+ if (regs[idx] == cptr)
30343033 goto no_match;
30353034 break;
30363035 case REOP_word_boundary:
···32123211 int cbuf_type, void *opaque)
32133212{
32143213 REExecContext s_s, *s = &s_s;
32153215- int re_flags, i, ret;
32163216- uint8_t **aux_stack;
32143214+ int re_flags, i, ret, register_count;
32153215+ uint8_t **regs;
32173216 const uint8_t *cptr;
3218321732193218 re_flags = lre_get_flags(bc_buf);
32203219 s->is_unicode = (re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0;
32213220 s->capture_count = bc_buf[RE_HEADER_CAPTURE_COUNT];
32223222- s->stack_size_max = bc_buf[RE_HEADER_STACK_SIZE];
32233221 s->cbuf = cbuf;
32243222 s->cbuf_end = cbuf + (clen << cbuf_type);
32253223 s->cbuf_type = cbuf_type;
···3233323132343232 for(i = 0; i < s->capture_count * 2; i++)
32353233 capture[i] = NULL;
32363236- aux_stack = alloca(s->stack_size_max * sizeof(aux_stack[0]));
32343234+ /* XXX: modify the API so that the registers are allocated after
32353235+ the captures to suppress some tests */
32363236+ register_count = bc_buf[RE_HEADER_REGISTER_COUNT];
32373237+ regs = alloca(register_count * sizeof(regs[0]));
3237323832383239 cptr = cbuf + (cindex << cbuf_type);
32393240 if (0 < cindex && cindex < clen && s->cbuf_type == 2) {
···32433244 }
32443245 }
3245324632463246- ret = lre_exec_backtrack(s, capture, aux_stack, bc_buf + RE_HEADER_LEN,
32473247+ ret = lre_exec_backtrack(s, capture, regs, bc_buf + RE_HEADER_LEN,
32473248 cptr);
32483249 if (s->stack_buf != s->static_stack_buf)
32493250 lre_realloc(s->opaque, s->stack_buf, 0);