|
|
@ -13,11 +13,11 @@ |
|
|
|
* Helper macros |
|
|
|
*/ |
|
|
|
|
|
|
|
#ifdef BUFLEN |
|
|
|
#undef BUFLEN |
|
|
|
#ifdef DUK_BUFLEN |
|
|
|
#undef DUK_BUFLEN |
|
|
|
#endif |
|
|
|
|
|
|
|
#define BUFLEN(re_ctx) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) re_ctx->buf) |
|
|
|
#define DUK_BUFLEN(re_ctx) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) re_ctx->buf) |
|
|
|
|
|
|
|
/*
|
|
|
|
* Encoding helpers |
|
|
@ -50,11 +50,11 @@ static duk_uint32_t append_i32(duk_re_compiler_ctx *re_ctx, duk_int32_t x) { |
|
|
|
#endif |
|
|
|
|
|
|
|
/* special helper for emitting u16 lists (used for character ranges for built-in char classes) */ |
|
|
|
static duk_uint32_t append_u16_list(duk_re_compiler_ctx *re_ctx, duk_uint16_t *values, duk_uint32_t num) { |
|
|
|
static duk_uint32_t append_u16_list(duk_re_compiler_ctx *re_ctx, duk_uint16_t *values, duk_uint32_t count) { |
|
|
|
duk_uint32_t len = 0; |
|
|
|
while (num > 0) { |
|
|
|
while (count > 0) { |
|
|
|
len += append_u32(re_ctx, (duk_uint32_t) (*values++)); |
|
|
|
num--; |
|
|
|
count--; |
|
|
|
} |
|
|
|
return len; |
|
|
|
} |
|
|
@ -105,7 +105,7 @@ static duk_uint32_t insert_jump_offset(duk_re_compiler_ctx *re_ctx, duk_uint32_t |
|
|
|
} |
|
|
|
|
|
|
|
static duk_uint32_t append_jump_offset(duk_re_compiler_ctx *re_ctx, duk_int32_t skip) { |
|
|
|
return insert_jump_offset(re_ctx, BUFLEN(re_ctx), skip); |
|
|
|
return insert_jump_offset(re_ctx, DUK_BUFLEN(re_ctx), skip); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
@ -232,7 +232,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
duk_int32_t atom_char_length = 0; /* negative -> complex atom */ |
|
|
|
duk_int32_t unpatched_disjunction_split = -1; |
|
|
|
duk_int32_t unpatched_disjunction_jump = -1; |
|
|
|
duk_uint32_t entry_offset = BUFLEN(re_ctx); |
|
|
|
duk_uint32_t entry_offset = DUK_BUFLEN(re_ctx); |
|
|
|
duk_int32_t res = 0; /* -1 if disjunction is complex, char length if simple */ |
|
|
|
|
|
|
|
if (re_ctx->recursion_depth >= re_ctx->recursion_limit) { |
|
|
@ -275,7 +275,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
offset = unpatched_disjunction_jump; |
|
|
|
offset += insert_jump_offset(re_ctx, |
|
|
|
offset, |
|
|
|
BUFLEN(re_ctx) - offset); |
|
|
|
DUK_BUFLEN(re_ctx) - offset); |
|
|
|
/* offset is now target of the pending split (right after jump) */ |
|
|
|
insert_jump_offset(re_ctx, |
|
|
|
unpatched_disjunction_split, |
|
|
@ -290,7 +290,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
|
|
|
|
/* add a new pending match jump for latest finished alternative */ |
|
|
|
append_u32(re_ctx, DUK_REOP_JUMP); |
|
|
|
unpatched_disjunction_jump = BUFLEN(re_ctx); |
|
|
|
unpatched_disjunction_jump = DUK_BUFLEN(re_ctx); |
|
|
|
|
|
|
|
/* 'taint' result as complex */ |
|
|
|
res = -1; |
|
|
@ -332,7 +332,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
} |
|
|
|
|
|
|
|
append_u32(re_ctx, DUK_REOP_MATCH); /* complete 'sub atom' */ |
|
|
|
atom_code_length = BUFLEN(re_ctx) - atom_start_offset; |
|
|
|
atom_code_length = DUK_BUFLEN(re_ctx) - atom_start_offset; |
|
|
|
|
|
|
|
offset = atom_start_offset; |
|
|
|
if (re_ctx->curr_token.greedy) { |
|
|
@ -371,7 +371,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
"quantifier expansion requires too many atom copies"); |
|
|
|
} |
|
|
|
|
|
|
|
atom_code_length = BUFLEN(re_ctx) - atom_start_offset; |
|
|
|
atom_code_length = DUK_BUFLEN(re_ctx) - atom_start_offset; |
|
|
|
|
|
|
|
/* insert the required matches (qmin) by copying the atom */ |
|
|
|
tmp_qmin = re_ctx->curr_token.qmin; |
|
|
@ -420,7 +420,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
* ... |
|
|
|
* LSEQ: |
|
|
|
*/ |
|
|
|
duk_uint32_t offset = BUFLEN(re_ctx); |
|
|
|
duk_uint32_t offset = DUK_BUFLEN(re_ctx); |
|
|
|
while (tmp_qmax > 0) { |
|
|
|
insert_slice(re_ctx, offset, atom_start_offset, atom_code_length); |
|
|
|
if (re_ctx->curr_token.greedy) { |
|
|
@ -430,7 +430,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
} |
|
|
|
insert_jump_offset(re_ctx, |
|
|
|
offset + 1, /* +1 for opcode */ |
|
|
|
BUFLEN(re_ctx) - (offset + 1)); |
|
|
|
DUK_BUFLEN(re_ctx) - (offset + 1)); |
|
|
|
tmp_qmax--; |
|
|
|
} |
|
|
|
} |
|
|
@ -465,14 +465,14 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
duk_uint32_t opcode = (re_ctx->curr_token.t == DUK_RETOK_ASSERT_START_POS_LOOKAHEAD) ? |
|
|
|
DUK_REOP_LOOKPOS : DUK_REOP_LOOKNEG; |
|
|
|
|
|
|
|
offset = BUFLEN(re_ctx); |
|
|
|
offset = DUK_BUFLEN(re_ctx); |
|
|
|
(void) parse_disjunction(re_ctx, 0); |
|
|
|
append_u32(re_ctx, DUK_REOP_MATCH); |
|
|
|
|
|
|
|
(void) insert_u32(re_ctx, offset, opcode); |
|
|
|
(void) insert_jump_offset(re_ctx, |
|
|
|
offset + 1, /* +1 for opcode */ |
|
|
|
BUFLEN(re_ctx) - (offset + 1)); |
|
|
|
DUK_BUFLEN(re_ctx) - (offset + 1)); |
|
|
|
|
|
|
|
/* 'taint' result as complex -- this is conservative,
|
|
|
|
* as lookaheads do not backtrack. |
|
|
@ -482,7 +482,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
} |
|
|
|
case DUK_RETOK_ATOM_PERIOD: { |
|
|
|
new_atom_char_length = 1; |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
append_u32(re_ctx, DUK_REOP_PERIOD); |
|
|
|
break; |
|
|
|
} |
|
|
@ -494,7 +494,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
duk_uint32_t ch; |
|
|
|
|
|
|
|
new_atom_char_length = 1; |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
append_u32(re_ctx, DUK_REOP_CHAR); |
|
|
|
ch = re_ctx->curr_token.num; |
|
|
|
if (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) { |
|
|
@ -506,7 +506,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
case DUK_RETOK_ATOM_DIGIT: |
|
|
|
case DUK_RETOK_ATOM_NOT_DIGIT: { |
|
|
|
new_atom_char_length = 1; |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
append_u32(re_ctx, |
|
|
|
(re_ctx->curr_token.t == DUK_RETOK_ATOM_DIGIT) ? |
|
|
|
DUK_REOP_RANGES : DUK_REOP_INVRANGES); |
|
|
@ -517,7 +517,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
case DUK_RETOK_ATOM_WHITE: |
|
|
|
case DUK_RETOK_ATOM_NOT_WHITE: { |
|
|
|
new_atom_char_length = 1; |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
append_u32(re_ctx, |
|
|
|
(re_ctx->curr_token.t == DUK_RETOK_ATOM_WHITE) ? |
|
|
|
DUK_REOP_RANGES : DUK_REOP_INVRANGES); |
|
|
@ -528,7 +528,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
case DUK_RETOK_ATOM_WORD_CHAR: |
|
|
|
case DUK_RETOK_ATOM_NOT_WORD_CHAR: { |
|
|
|
new_atom_char_length = 1; |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
append_u32(re_ctx, |
|
|
|
(re_ctx->curr_token.t == DUK_RETOK_ATOM_WORD_CHAR) ? |
|
|
|
DUK_REOP_RANGES : DUK_REOP_INVRANGES); |
|
|
@ -542,7 +542,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
re_ctx->highest_backref = backref; |
|
|
|
} |
|
|
|
new_atom_char_length = -1; /* mark as complex */ |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
append_u32(re_ctx, DUK_REOP_BACKREFERENCE); |
|
|
|
append_u32(re_ctx, backref); |
|
|
|
break; |
|
|
@ -551,7 +551,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
duk_uint32_t cap; |
|
|
|
|
|
|
|
new_atom_char_length = -1; /* mark as complex (capture handling) */ |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
cap = ++re_ctx->captures; |
|
|
|
append_u32(re_ctx, DUK_REOP_SAVE); |
|
|
|
append_u32(re_ctx, cap * 2); |
|
|
@ -562,7 +562,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
} |
|
|
|
case DUK_RETOK_ATOM_START_NONCAPTURE_GROUP: { |
|
|
|
new_atom_char_length = parse_disjunction(re_ctx, 0); |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
break; |
|
|
|
} |
|
|
|
case DUK_RETOK_ATOM_START_CHARCLASS: |
|
|
@ -597,11 +597,11 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
|
|
|
|
/* insert ranges instruction, range count patched in later */ |
|
|
|
new_atom_char_length = 1; |
|
|
|
new_atom_start_offset = BUFLEN(re_ctx); |
|
|
|
new_atom_start_offset = DUK_BUFLEN(re_ctx); |
|
|
|
append_u32(re_ctx, |
|
|
|
(re_ctx->curr_token.t == DUK_RETOK_ATOM_START_CHARCLASS) ? |
|
|
|
DUK_REOP_RANGES : DUK_REOP_INVRANGES); |
|
|
|
offset = BUFLEN(re_ctx); /* patch in range count later */ |
|
|
|
offset = DUK_BUFLEN(re_ctx); /* patch in range count later */ |
|
|
|
|
|
|
|
/* parse ranges until character class ends */ |
|
|
|
re_ctx->nranges = 0; /* note: ctx-wide temporary */ |
|
|
@ -656,7 +656,7 @@ static duk_int32_t parse_disjunction(duk_re_compiler_ctx *re_ctx, int expect_eof |
|
|
|
offset = unpatched_disjunction_jump; |
|
|
|
offset += insert_jump_offset(re_ctx, |
|
|
|
offset, |
|
|
|
BUFLEN(re_ctx) - offset); |
|
|
|
DUK_BUFLEN(re_ctx) - offset); |
|
|
|
/* offset is now target of the pending split (right after jump) */ |
|
|
|
insert_jump_offset(re_ctx, |
|
|
|
unpatched_disjunction_split, |
|
|
@ -974,5 +974,7 @@ void duk_regexp_create_instance(duk_hthread *thr) { |
|
|
|
/* [ ... regexp_object ] */ |
|
|
|
} |
|
|
|
|
|
|
|
#undef DUK_BUFLEN |
|
|
|
|
|
|
|
#endif /* DUK_USE_REGEXP_SUPPORT */ |
|
|
|
|
|
|
|