23#ifdef DUK_USE_REGEXP_SUPPORT
29#define DUK__RE_INITIAL_BUFSIZE 64
32#define DUK__RE_BUFLEN(re_ctx) \
33 DUK_BW_GET_SIZE(re_ctx->thr, &re_ctx->bw)
56 duk_uint32_t start_captures;
57 duk_uint32_t end_captures;
76 return ((duk_uint32_t) (-x)) * 2 + 1;
78 return ((duk_uint32_t) x) * 2;
91 return (duk_uint32_t) len;
100 return (duk_uint32_t) len;
157 skip -= (duk_int32_t) len;
188 DUK_DD(
DUK_DDPRINT(
"duk__generate_ranges(): re_ctx=%p, range=[%ld,%ld] direct=%ld",
189 (
void *) re_ctx, (
long) r1, (
long) r2, (
long) direct));
211 for (i = r1 + 1; i <= r2; i++) {
213 if (t == r_end + 1) {
216 DUK_DD(
DUK_DDPRINT(
"canonicalized, emit range: [%ld,%ld]", (
long) r_start, (
long) r_end));
224 DUK_DD(
DUK_DDPRINT(
"canonicalized, emit range: [%ld,%ld]", (
long) r_start, (
long) r_end));
287 duk_int32_t atom_start_offset = -1;
288 duk_int32_t atom_char_length = 0;
289 duk_uint32_t atom_start_captures = re_ctx->
captures;
290 duk_int32_t unpatched_disjunction_split = -1;
291 duk_int32_t unpatched_disjunction_jump = -1;
292 duk_uint32_t entry_offset = (duk_uint32_t)
DUK__RE_BUFLEN(re_ctx);
293 duk_int32_t res_charlen = 0;
304 out_atom_info->start_captures = re_ctx->
captures;
314 duk_int32_t new_atom_char_length;
315 duk_int32_t new_atom_start_offset;
318 duk_uint32_t new_atom_start_captures;
329 new_atom_start_offset = -1;
330 new_atom_char_length = -1;
331 new_atom_start_captures = re_ctx->
captures;
342 if (unpatched_disjunction_jump >= 0) {
346 offset = unpatched_disjunction_jump;
352 unpatched_disjunction_split,
353 offset - unpatched_disjunction_split);
360 unpatched_disjunction_split = entry_offset + 1;
364 unpatched_disjunction_jump = (duk_int32_t)
DUK__RE_BUFLEN(re_ctx);
371 if (atom_start_offset < 0) {
377 if (atom_char_length >= 0) {
390 duk_int32_t atom_code_length;
392 duk_uint32_t qmin, qmax;
396 if (atom_char_length == 0) {
407 atom_code_length = (duk_int32_t) (
DUK__RE_BUFLEN(re_ctx) - atom_start_offset);
409 offset = atom_start_offset;
435 duk_int32_t atom_code_length;
436 duk_uint32_t atom_copies;
437 duk_uint32_t tmp_qmin, tmp_qmax;
447 DUK_ASSERT(atom_start_captures <= re_ctx->captures);
448 if (atom_start_captures != re_ctx->
captures) {
449 DUK_ASSERT(atom_start_captures < re_ctx->captures);
451 (
long) atom_start_captures, (
long) re_ctx->
captures));
455 duk__insert_u32(re_ctx, atom_start_offset, (atom_start_captures + 1) * 2);
458 DUK_DDD(
DUK_DDDPRINT(
"no need to wipe captures: atom_start_captures == re_ctx->captures == %ld",
459 (
long) atom_start_captures));
462 atom_code_length = (duk_int32_t)
DUK__RE_BUFLEN(re_ctx) - atom_start_offset;
467 while (tmp_qmin > 0) {
512 while (tmp_qmax > 0) {
572 new_atom_char_length = 1;
584 new_atom_char_length = 1;
596 new_atom_char_length = 1;
607 new_atom_char_length = 1;
618 new_atom_char_length = 1;
628 duk_uint32_t backref = (duk_uint32_t) re_ctx->
curr_token.
num;
632 new_atom_char_length = -1;
641 new_atom_char_length = -1;
654 new_atom_char_length = tmp_disj.
charlen;
688 new_atom_char_length = 1;
721 if (new_atom_start_offset >= 0) {
722 if (new_atom_char_length < 0) {
724 }
else if (res_charlen >= 0) {
726 res_charlen += new_atom_char_length;
731 atom_start_offset = new_atom_start_offset;
732 atom_char_length = new_atom_char_length;
733 atom_start_captures = new_atom_start_captures;
739 if (unpatched_disjunction_jump >= 0) {
743 offset = unpatched_disjunction_jump;
749 unpatched_disjunction_split,
750 offset - unpatched_disjunction_split);
754 out_atom_info->end_captures = re_ctx->
captures;
756 out_atom_info->
charlen = res_charlen;
758 (
long) out_atom_info->
charlen));
768 const duk_uint8_t *p;
769 const duk_uint8_t *p_end;
770 duk_uint32_t flags = 0;
778 duk_uint8_t c = *p++;
837 const duk_uint8_t *p;
861 for (i = 0; i < n; i++) {
872 *q++ = (duk_uint8_t) c;
943 DUK_DD(
DUK_DDPRINT(
"regexp compiler ctx initialized, flags=0x%08lx, recursion_limit=%ld",
1002 DUK_DD(
DUK_DDPRINT(
"regexp compilation successful, bytecode: %!T, escaped source: %!T",
1066#undef DUK__RE_BUFLEN
#define DUK_USE_REGEXP_COMPILER_RECLIMIT
duk_uint_t duk_ucodepoint_t
duk_uint8_t duk_uint_fast8_t
duk_int_t duk_codepoint_t
#define DUK_MEMZERO(p, n)
duk_small_int_t duk_bool_t
#define DUK_RETOK_DISJUNCTION
#define DUK_ERROR_RANGE(thr, msg)
#define DUK_BW_WRITE_ENSURE_SLICE(thr, bw, dst_off, dst_len)
#define DUK_HSTRING_GET_DATA(x)
#define DUK_REOP_ASSERT_WORD_BOUNDARY
#define DUK_HOBJECT_CLASS_REGEXP
#define DUK_RETOK_ATOM_PERIOD
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out)
#define DUK_STRIDX_GLOBAL
DUK_EXTERNAL void duk_push_boolean(duk_context *ctx, duk_bool_t val)
#define DUK_RETOK_ATOM_WORD_CHAR
#define DUK_RETOK_ATOM_START_CHARCLASS
#define DUK_STRIDX_SOURCE
#define DUK_REOP_ASSERT_END
#define DUK_BW_COMPACT(thr, bw_ctx)
#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM
#define DUK_STR_UNEXPECTED_REGEXP_TOKEN
#define DUK_BW_SETPTR_AND_COMPACT(thr, bw_ctx, ptr)
#define DUK_RE_FLAG_MULTILINE
#define DUK_ERROR_SYNTAX(thr, msg)
#define DUK_PROPDESC_FLAGS_NONE
DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_context *ctx, duk_small_int_t stridx)
#define DUK_ASC_BACKSLASH
#define DUK_HSTRING_GET_CHARLEN(x)
#define DUK_REOP_INVRANGES
DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, p)
#define DUK_BW_ENSURE_RAW(thr, bw_ctx, sz, ptr)
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_digit[2]
DUK_EXTERNAL void duk_push_int(duk_context *ctx, duk_int_t val)
#define DUK_LEXER_INITCTX(ctx)
#define DUK_RE_COMPILE_TOKEN_LIMIT
#define DUK_RETOK_ATOM_START_CHARCLASS_INVERTED
#define DUK_LEXER_SETPOINT(ctx, pt)
#define DUK_STR_UNEXPECTED_END_OF_PATTERN
#define DUK_REOP_SQGREEDY
#define DUK_RE_FLAG_GLOBAL
#define DUK_RETOK_ATOM_DIGIT
#define DUK_BW_INSERT_ENSURE_BYTES(thr, bw, dst_off, buf, len)
#define DUK_RETOK_ATOM_END_GROUP
#define DUK_HSTRING_GET_BYTELEN(x)
#define DUK_RETOK_ATOM_NOT_WHITE
DUK_EXTERNAL duk_idx_t duk_push_object(duk_context *ctx)
#define DUK_RETOK_ASSERT_WORD_BOUNDARY
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp)
DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index)
#define DUK_RETOK_ATOM_NOT_WORD_CHAR
#define DUK_RETOK_ATOM_START_CAPTURE_GROUP
#define DUK_RETOK_ASSERT_START
#define DUK_STRIDX_LAST_INDEX
#define DUK_STR_INVALID_QUANTIFIER_VALUES
DUK_INTERNAL_DECL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token)
#define DUK_RETOK_ASSERT_START_POS_LOOKAHEAD
#define DUK_BW_REMOVE_ENSURE_SLICE(thr, bw, off, len)
#define DUK_BW_INIT_PUSHBUF(thr, bw_ctx, sz)
#define DUK_BW_GET_PTR(thr, bw_ctx)
#define DUK_RETOK_ATOM_NOT_DIGIT
#define DUK_REOP_BACKREFERENCE
#define DUK_STRIDX_ESCAPED_EMPTY_REGEXP
#define DUK_RETOK_QUANTIFIER
#define DUK_REOP_WIPERANGE
#define DUK_STRIDX_IGNORE_CASE
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_wordchar[8]
#define DUK_REOP_ASSERT_START
#define DUK_STR_INVALID_REGEXP_FLAGS
#define DUK_RE_QUANTIFIER_INFINITE
#define DUK_RETOK_ATOM_START_NONCAPTURE_GROUP
#define DUK_BIDX_REGEXP_PROTOTYPE
#define DUK_RETOK_ATOM_WHITE
DUK_EXTERNAL const char * duk_to_string(duk_context *ctx, duk_idx_t index)
#define DUK_RE_FLAG_IGNORE_CASE
#define DUK_BW_INSERT_ENSURE_SLICE(thr, bw, dst_off, src_off, len)
#define DUK_BW_WRITE_ENSURE_BYTES(thr, bw_ctx, valptr, valsz)
#define DUK_STRIDX_INT_BYTECODE
DUK_INTERNAL_DECL duk_hobject * duk_get_hobject(duk_context *ctx, duk_idx_t index)
#define DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT
DUK_INTERNAL_DECL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp)
#define DUK_RETOK_ASSERT_END
#define DUK_REOP_ASSERT_NOT_WORD_BOUNDARY
#define DUK_RETOK_ATOM_BACKREFERENCE
DUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_small_uint_t desc_flags)
DUK_INTERNAL_DECL duk_hstring * duk_get_hstring(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL duk_hstring * duk_require_hstring(duk_context *ctx, duk_idx_t index)
#define DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD
#define DUK_RE_MAX_ATOM_COPIES
#define DUK_STRIDX_MULTILINE
DUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata)
#define DUK_STR_UNEXPECTED_CLOSING_PAREN
#define DUK_HOBJECT_SET_CLASS_NUMBER(h, v)
#define DUK_REOP_SQMINIMAL
#define DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY
#define DUK_PROPDESC_FLAGS_W
#define DUK_UNICODE_MAX_XUTF8_LENGTH
#define DUK_STR_QUANTIFIER_TOO_MANY_COPIES
#define DUK_STR_INVALID_BACKREFS
DUK_INTERNAL_DECL duk_tval * duk_get_tval(duk_context *ctx, duk_idx_t index)
#define DUK_RETOK_ATOM_CHAR
DUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_white[22]
DUK_LOCAL duk_uint32_t duk__append_jump_offset(duk_re_compiler_ctx *re_ctx, duk_int32_t skip)
DUK_LOCAL void duk__remove_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length)
DUK_LOCAL void duk__generate_ranges(void *userdata, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct)
DUK_LOCAL duk_uint32_t duk__parse_regexp_flags(duk_hthread *thr, duk_hstring *h)
DUK_LOCAL duk_uint32_t duk__insert_jump_offset(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t skip)
DUK_LOCAL duk_uint32_t duk__encode_i32(duk_int32_t x)
DUK_LOCAL void duk__append_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length)
DUK_LOCAL duk_uint32_t duk__insert_i32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t x)
DUK_LOCAL void duk__insert_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t data_offset, duk_uint32_t data_length)
DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t expect_eof, duk__re_disjunction_info *out_atom_info)
DUK_LOCAL void duk__append_u16_list(duk_re_compiler_ctx *re_ctx, const duk_uint16_t *values, duk_uint32_t count)
DUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern)
#define DUK__RE_INITIAL_BUFSIZE
DUK_LOCAL duk_uint32_t duk__append_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t x)
DUK_LOCAL duk_uint32_t duk__insert_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t x)
DUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr)
#define DUK__RE_BUFLEN(re_ctx)
DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr)
static void error(LoadState *S, const char *why)
duk_hobject * builtins[DUK_NUM_BUILTINS]
const duk_uint8_t * input
duk_uint32_t highest_backref
duk_uint32_t recursion_depth
duk_uint32_t recursion_limit