in GaiaXAndroidQuickJS/quickjs/gxquickjs/libregexp.c [950:1030]
static int re_check_advance(const uint8_t *bc_buf, int bc_buf_len)
{
int pos, opcode, ret, len, i;
uint32_t val, last;
BOOL has_back_reference;
uint8_t capture_bitmap[CAPTURE_COUNT_MAX];
ret = -2; /* not known yet */
pos = 0;
has_back_reference = FALSE;
memset(capture_bitmap, 0, sizeof(capture_bitmap));
while (pos < bc_buf_len) {
opcode = bc_buf[pos];
len = reopcode_info[opcode].size;
switch(opcode) {
case REOP_range:
val = get_u16(bc_buf + pos + 1);
len += val * 4;
goto simple_char;
case REOP_range32:
val = get_u16(bc_buf + pos + 1);
len += val * 8;
goto simple_char;
case REOP_char:
case REOP_char32:
case REOP_dot:
case REOP_any:
simple_char:
if (ret == -2)
ret = 1;
break;
case REOP_line_start:
case REOP_line_end:
case REOP_push_i32:
case REOP_push_char_pos:
case REOP_drop:
case REOP_word_boundary:
case REOP_not_word_boundary:
case REOP_prev:
/* no effect */
break;
case REOP_save_start:
case REOP_save_end:
val = bc_buf[pos + 1];
capture_bitmap[val] |= 1;
break;
case REOP_save_reset:
{
val = bc_buf[pos + 1];
last = bc_buf[pos + 2];
while (val < last)
capture_bitmap[val++] |= 1;
}
break;
case REOP_back_reference:
case REOP_backward_back_reference:
val = bc_buf[pos + 1];
capture_bitmap[val] |= 2;
has_back_reference = TRUE;
break;
default:
/* safe behvior: we cannot predict the outcome */
if (ret == -2)
ret = 0;
break;
}
pos += len;
}
if (has_back_reference) {
/* check if there is back reference which references a capture
made in the some code */
for(i = 0; i < CAPTURE_COUNT_MAX; i++) {
if (capture_bitmap[i] == 3)
return -1;
}
}
if (ret == -2)
ret = 0;
return ret;
}