regcomp.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2018 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2019 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
}
#endif
+static int
+ops_init(regex_t* reg, int init_alloc_size)
+{
+ Operation* p;
+ size_t size = sizeof(Operation) * init_alloc_size;
+
+ if (init_alloc_size > 0) {
+ p = (Operation* )xrealloc(reg->ops, size);
+ CHECK_NULL_RETURN_MEMERR(p);
+ }
+ else {
+ p = (Operation* )0;
+ }
+
+ reg->ops = p;
+ reg->ops_curr = 0; /* !!! not yet done ops_new() */
+ reg->ops_alloc = init_alloc_size;
+ reg->ops_used = 0;
+
+ return ONIG_NORMAL;
+}
+
+static int
+ops_expand(regex_t* reg, int n)
+{
+#define MIN_OPS_EXPAND_SIZE 4
+
+ Operation* p;
+ size_t size;
+
+ if (n <= 0) n = MIN_OPS_EXPAND_SIZE;
+
+ n += reg->ops_alloc;
+ size = sizeof(Operation) * n;
+
+ p = (Operation* )xrealloc(reg->ops, size);
+ CHECK_NULL_RETURN_MEMERR(p);
+
+ reg->ops = p;
+ reg->ops_alloc = n;
+ if (reg->ops_used == 0)
+ reg->ops_curr = 0;
+ else
+ reg->ops_curr = reg->ops + (reg->ops_used - 1);
+
+ return ONIG_NORMAL;
+}
+
+static int
+ops_new(regex_t* reg)
+{
+ int r;
+
+ if (reg->ops_used >= reg->ops_alloc) {
+ r = ops_expand(reg, reg->ops_alloc);
+ if (r != ONIG_NORMAL) return r;
+ }
+
+ reg->ops_curr = reg->ops + reg->ops_used;
+ reg->ops_used++;
+
+ xmemset(reg->ops_curr, 0, sizeof(Operation));
+ return ONIG_NORMAL;
+}
+
+static void
+ops_free(regex_t* reg)
+{
+ int i;
+
+ if (IS_NULL(reg->ops)) return ;
+
+ for (i = 0; i < reg->ops_used; i++) {
+ Operation* op = reg->ops + i;
+ switch (op->opcode) {
+ case OP_EXACTMBN:
+ xfree(op->exact_len_n.s);
+ break;
+ case OP_EXACTN: case OP_EXACTMB2N: case OP_EXACTMB3N: case OP_EXACTN_IC:
+ xfree(op->exact_n.s);
+ break;
+ case OP_EXACT1: case OP_EXACT2: case OP_EXACT3: case OP_EXACT4:
+ case OP_EXACT5: case OP_EXACTMB2N1: case OP_EXACTMB2N2:
+ case OP_EXACTMB2N3: case OP_EXACT1_IC:
+ xfree(op->exact.s);
+ break;
+
+ case OP_CCLASS_MB_NOT: case OP_CCLASS_MB:
+ xfree(op->cclass_mb.mb);
+ break;
+ case OP_CCLASS_MIX_NOT: case OP_CCLASS_MIX:
+ xfree(op->cclass_mix.mb);
+ break;
+
+ case OP_BACKREF1: case OP_BACKREF2: case OP_BACKREF_N: case OP_BACKREF_N_IC:
+ break;
+ case OP_BACKREF_MULTI: case OP_BACKREF_MULTI_IC:
+ case OP_BACKREF_WITH_LEVEL: case OP_BACKREF_CHECK:
+ case OP_BACKREF_CHECK_WITH_LEVEL:
+ if (op->backref_general.num != 1)
+ xfree(op->backref_general.ns);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ xfree(reg->ops);
+
+ reg->ops = 0;
+ reg->ops_curr = 0;
+ reg->ops_alloc = 0;
+ reg->ops_used = 0;
+}
+
extern OnigCaseFoldType
onig_get_default_case_fold_flag(void)
{
static int
-add_opcode(regex_t* reg, int opcode)
-{
- BB_ADD1(reg, opcode);
- return 0;
-}
-
-static int
-add_rel_addr(regex_t* reg, int addr)
-{
- RelAddrType ra = (RelAddrType )addr;
-
- BB_ADD(reg, &ra, SIZE_RELADDR);
- return 0;
-}
-
-static int
-add_abs_addr(regex_t* reg, int addr)
-{
- AbsAddrType ra = (AbsAddrType )addr;
-
- BB_ADD(reg, &ra, SIZE_ABSADDR);
- return 0;
-}
-
-static int
-add_length(regex_t* reg, int len)
-{
- LengthType l = (LengthType )len;
-
- BB_ADD(reg, &l, SIZE_LENGTH);
- return 0;
-}
-
-static int
-add_mem_num(regex_t* reg, int num)
-{
- MemNumType n = (MemNumType )num;
-
- BB_ADD(reg, &n, SIZE_MEMNUM);
- return 0;
-}
-
-#if 0
-static int
-add_pointer(regex_t* reg, void* addr)
-{
- PointerType ptr = (PointerType )addr;
-
- BB_ADD(reg, &ptr, SIZE_POINTER);
- return 0;
-}
-#endif
-
-static int
-add_option(regex_t* reg, OnigOptionType option)
-{
- BB_ADD(reg, &option, SIZE_OPTION);
- return 0;
-}
-
-static int
-add_save_type(regex_t* reg, enum SaveType type)
-{
- SaveType t = (SaveType )type;
-
- BB_ADD(reg, &t, SIZE_SAVE_TYPE);
- return 0;
-}
-
-static int
-add_update_var_type(regex_t* reg, enum UpdateVarType type)
-{
- UpdateVarType t = (UpdateVarType )type;
-
- BB_ADD(reg, &t, SIZE_UPDATE_VAR_TYPE);
- return 0;
-}
-
-static int
-add_mode(regex_t* reg, ModeType mode)
-{
- BB_ADD(reg, &mode, SIZE_MODE);
- return 0;
-}
-
-static int
-add_opcode_rel_addr(regex_t* reg, int opcode, int addr)
+add_op(regex_t* reg, int opcode)
{
int r;
- r = add_opcode(reg, opcode);
- if (r != 0) return r;
- r = add_rel_addr(reg, addr);
- return r;
-}
+ r = ops_new(reg);
+ if (r != ONIG_NORMAL) return r;
-static int
-add_bytes(regex_t* reg, UChar* bytes, int len)
-{
- BB_ADD(reg, bytes, len);
- return 0;
-}
-
-static int
-add_bitset(regex_t* reg, BitSetRef bs)
-{
- BB_ADD(reg, bs, SIZE_BITSET);
+ reg->ops_curr->opcode = opcode;
return 0;
}
int saved_num_null_check = reg->num_null_check;
if (empty_info != QUANT_BODY_IS_NOT_EMPTY) {
- r = add_opcode(reg, OP_EMPTY_CHECK_START);
- if (r != 0) return r;
- r = add_mem_num(reg, reg->num_null_check); /* NULL CHECK ID */
+ r = add_op(reg, OP_EMPTY_CHECK_START);
if (r != 0) return r;
+ COP(reg)->empty_check_start.mem = reg->num_null_check; /* NULL CHECK ID */
reg->num_null_check++;
}
if (empty_info != QUANT_BODY_IS_NOT_EMPTY) {
if (empty_info == QUANT_BODY_IS_EMPTY)
- r = add_opcode(reg, OP_EMPTY_CHECK_END);
+ r = add_op(reg, OP_EMPTY_CHECK_END);
else if (empty_info == QUANT_BODY_IS_EMPTY_MEM)
- r = add_opcode(reg, OP_EMPTY_CHECK_END_MEMST);
+ r = add_op(reg, OP_EMPTY_CHECK_END_MEMST);
else if (empty_info == QUANT_BODY_IS_EMPTY_REC)
- r = add_opcode(reg, OP_EMPTY_CHECK_END_MEMST_PUSH);
+ r = add_op(reg, OP_EMPTY_CHECK_END_MEMST_PUSH);
if (r != 0) return r;
- r = add_mem_num(reg, saved_num_null_check); /* NULL CHECK ID */
+ COP(reg)->empty_check_end.mem = saved_num_null_check; /* NULL CHECK ID */
}
return r;
}
compile_call(CallNode* node, regex_t* reg, ScanEnv* env)
{
int r;
+ int offset;
- r = add_opcode(reg, OP_CALL);
- if (r != 0) return r;
- r = unset_addr_list_add(env->unset_addr_list, BB_GET_OFFSET_POS(reg),
- NODE_CALL_BODY(node));
+ r = add_op(reg, OP_CALL);
if (r != 0) return r;
- r = add_abs_addr(reg, 0 /*dummy addr.*/);
+
+ COP(reg)->call.addr = 0; /* dummy addr. */
+
+ offset = COP_CURR_OFFSET_BYTES(reg, call.addr);
+ r = unset_addr_list_add(env->unset_addr_list, offset, NODE_CALL_BODY(node));
return r;
}
#endif
add_compile_string_length(UChar* s ARG_UNUSED, int mb_len, int str_len,
regex_t* reg ARG_UNUSED, int ignore_case)
{
- int len;
- int op = select_str_opcode(mb_len, str_len, ignore_case);
-
- len = SIZE_OPCODE;
-
- if (op == OP_EXACTMBN) len += SIZE_LENGTH;
- if (IS_NEED_STR_LEN_OP_EXACT(op))
- len += SIZE_LENGTH;
-
- len += mb_len * str_len;
- return len;
+ return 1;
}
static int
add_compile_string(UChar* s, int mb_len, int str_len,
regex_t* reg, int ignore_case)
{
- int op = select_str_opcode(mb_len, str_len, ignore_case);
- add_opcode(reg, op);
+ int op;
+ int r;
+ UChar* p;
+ UChar* end;
- if (op == OP_EXACTMBN)
- add_length(reg, mb_len);
+ op = select_str_opcode(mb_len, str_len, ignore_case);
+ r = add_op(reg, op);
+ if (r != 0) return r;
+
+ end = s + (mb_len * str_len);
+ p = onigenc_strdup(reg->enc, s, end);
+ CHECK_NULL_RETURN_MEMERR(p);
- if (IS_NEED_STR_LEN_OP_EXACT(op)) {
+ if (op == OP_EXACTMBN) {
+ COP(reg)->exact_len_n.len = mb_len;
+ COP(reg)->exact_len_n.n = str_len;
+ COP(reg)->exact_len_n.s = p;
+ }
+ else if (IS_NEED_STR_LEN_OP_EXACT(op)) {
if (op == OP_EXACTN_IC)
- add_length(reg, mb_len * str_len);
+ COP(reg)->exact_n.n = mb_len * str_len;
else
- add_length(reg, str_len);
+ COP(reg)->exact_n.n = str_len;
+
+ COP(reg)->exact_n.s = p;
+ }
+ else {
+ COP(reg)->exact.s = p;
}
- add_bytes(reg, s, mb_len * str_len);
return 0;
}
-
static int
compile_length_string_node(Node* node, regex_t* reg)
{
return add_compile_string(sn->s, 1 /* sb */, (int )(sn->end - sn->s), reg, 0);
}
+#if 0
static int
add_multi_byte_cclass(BBuf* mbuf, regex_t* reg)
{
return r;
#endif
}
+#endif
-static int
-compile_length_cclass_node(CClassNode* cc, regex_t* reg)
+static void*
+set_multi_byte_cclass(BBuf* mbuf, regex_t* reg)
{
- int len;
+ size_t len;
+ void* p;
- if (IS_NULL(cc->mbuf)) {
- len = SIZE_OPCODE + SIZE_BITSET;
- }
- else {
- if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
- len = SIZE_OPCODE;
- }
- else {
- len = SIZE_OPCODE + SIZE_BITSET;
- }
-#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
- len += SIZE_LENGTH + cc->mbuf->used;
-#else
- len += SIZE_LENGTH + cc->mbuf->used + (WORD_ALIGNMENT_SIZE - 1);
-#endif
- }
+ len = (size_t )mbuf->used;
+ p = xmalloc(len);
+ if (IS_NULL(p)) return NULL;
- return len;
+ xmemcpy(p, mbuf->p, len);
+ return p;
+}
+
+static int
+compile_length_cclass_node(CClassNode* cc, regex_t* reg)
+{
+ return 1;
}
static int
int r;
if (IS_NULL(cc->mbuf)) {
- if (IS_NCCLASS_NOT(cc))
- add_opcode(reg, OP_CCLASS_NOT);
- else
- add_opcode(reg, OP_CCLASS);
+ r = add_op(reg, IS_NCCLASS_NOT(cc) ? OP_CCLASS_NOT : OP_CCLASS);
+ if (r != 0) return r;
- r = add_bitset(reg, cc->bs);
+ xmemcpy(COP(reg)->cclass.bs, cc->bs, SIZE_BITSET);
}
else {
+ void* p;
+
if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
- if (IS_NCCLASS_NOT(cc))
- add_opcode(reg, OP_CCLASS_MB_NOT);
- else
- add_opcode(reg, OP_CCLASS_MB);
+ r = add_op(reg, IS_NCCLASS_NOT(cc) ? OP_CCLASS_MB_NOT : OP_CCLASS_MB);
+ if (r != 0) return r;
- r = add_multi_byte_cclass(cc->mbuf, reg);
+ p = set_multi_byte_cclass(cc->mbuf, reg);
+ CHECK_NULL_RETURN_MEMERR(p);
+ COP(reg)->cclass_mb.mb = p;
}
else {
- if (IS_NCCLASS_NOT(cc))
- add_opcode(reg, OP_CCLASS_MIX_NOT);
- else
- add_opcode(reg, OP_CCLASS_MIX);
-
- r = add_bitset(reg, cc->bs);
+ r = add_op(reg, IS_NCCLASS_NOT(cc) ? OP_CCLASS_MIX_NOT : OP_CCLASS_MIX);
if (r != 0) return r;
- r = add_multi_byte_cclass(cc->mbuf, reg);
+
+ xmemcpy(COP(reg)->cclass_mix.bs, cc->bs, SIZE_BITSET);
+
+ p = set_multi_byte_cclass(cc->mbuf, reg);
+ CHECK_NULL_RETURN_MEMERR(p);
+ COP(reg)->cclass_mix.mb = p;
}
}
- return r;
+ return 0;
}
static int
else if (reg->repeat_range_alloc <= id) {
int n;
n = reg->repeat_range_alloc + REPEAT_RANGE_ALLOC;
- p = (OnigRepeatRange* )xrealloc(reg->repeat_range,
- sizeof(OnigRepeatRange) * n);
+ p = (OnigRepeatRange* )xrealloc(reg->repeat_range, sizeof(OnigRepeatRange) * n);
CHECK_NULL_RETURN_MEMERR(p);
reg->repeat_range = p;
reg->repeat_range_alloc = n;
regex_t* reg, ScanEnv* env)
{
int r;
- int num_repeat = reg->num_repeat;
+ int num_repeat = reg->num_repeat++;
- r = add_opcode(reg, qn->greedy ? OP_REPEAT : OP_REPEAT_NG);
- if (r != 0) return r;
- r = add_mem_num(reg, num_repeat); /* OP_REPEAT ID */
- reg->num_repeat++;
- if (r != 0) return r;
- r = add_rel_addr(reg, target_len + SIZE_OP_REPEAT_INC);
+ r = add_op(reg, qn->greedy ? OP_REPEAT : OP_REPEAT_NG);
if (r != 0) return r;
+ COP(reg)->repeat.id = num_repeat;
+ COP(reg)->repeat.addr = SIZE_INC_OP + target_len + SIZE_OP_REPEAT_INC;
+
r = entry_repeat_range(reg, num_repeat, qn->lower, qn->upper);
if (r != 0) return r;
NODE_IS_IN_MULTI_ENTRY(qn) ||
#endif
NODE_IS_IN_REAL_REPEAT(qn)) {
- r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC_SG : OP_REPEAT_INC_NG_SG);
+ r = add_op(reg, qn->greedy ? OP_REPEAT_INC_SG : OP_REPEAT_INC_NG_SG);
}
else {
- r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC : OP_REPEAT_INC_NG);
+ r = add_op(reg, qn->greedy ? OP_REPEAT_INC : OP_REPEAT_INC_NG);
}
if (r != 0) return r;
- r = add_mem_num(reg, num_repeat); /* OP_REPEAT ID */
+
+ COP(reg)->repeat_inc.id = num_repeat;
return r;
}
return 0;
}
-#define QUANTIFIER_EXPAND_LIMIT_SIZE 50
+#define QUANTIFIER_EXPAND_LIMIT_SIZE 10
#define CKN_ON (ckn > 0)
static int
len = SIZE_OP_PUSH + SIZE_OP_JUMP + tlen;
}
else {
- len = SIZE_OP_REPEAT_INC
- + mod_tlen + SIZE_OPCODE + SIZE_RELADDR + SIZE_MEMNUM;
+ len = SIZE_OP_REPEAT_INC + mod_tlen + SIZE_OP_REPEAT;
}
return len;
r = compile_tree_n_times(NODE_QUANT_BODY(qn), qn->lower, reg, env);
if (r != 0) return r;
if (IS_NOT_NULL(qn->next_head_exact)) {
- if (IS_MULTILINE(CTYPE_OPTION(NODE_QUANT_BODY(qn), reg)))
- r = add_opcode(reg, OP_ANYCHAR_ML_STAR_PEEK_NEXT);
- else
- r = add_opcode(reg, OP_ANYCHAR_STAR_PEEK_NEXT);
+ r = add_op(reg,
+ IS_MULTILINE(CTYPE_OPTION(NODE_QUANT_BODY(qn), reg)) ?
+ OP_ANYCHAR_ML_STAR_PEEK_NEXT : OP_ANYCHAR_STAR_PEEK_NEXT);
if (r != 0) return r;
- return add_bytes(reg, STR_(qn->next_head_exact)->s, 1);
+
+ COP(reg)->anychar_star_peek_next.c = STR_(qn->next_head_exact)->s[0];
+ return 0;
}
else {
- if (IS_MULTILINE(CTYPE_OPTION(NODE_QUANT_BODY(qn), reg)))
- return add_opcode(reg, OP_ANYCHAR_ML_STAR);
- else
- return add_opcode(reg, OP_ANYCHAR_STAR);
+ r = add_op(reg,
+ IS_MULTILINE(CTYPE_OPTION(NODE_QUANT_BODY(qn), reg)) ?
+ OP_ANYCHAR_ML_STAR : OP_ANYCHAR_STAR);
+ return r;
}
}
if (infinite &&
(qn->lower <= 1 ||
int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) {
+ int addr;
+
if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
+ r = add_op(reg, OP_JUMP);
+ if (r != 0) return r;
if (qn->greedy) {
if (IS_NOT_NULL(qn->head_exact))
- r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH_OR_JUMP_EXACT1);
+ COP(reg)->jump.addr = SIZE_OP_PUSH_OR_JUMP_EXACT1 + SIZE_INC_OP;
else if (IS_NOT_NULL(qn->next_head_exact))
- r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH_IF_PEEK_NEXT);
+ COP(reg)->jump.addr = SIZE_OP_PUSH_IF_PEEK_NEXT + SIZE_INC_OP;
else
- r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH);
+ COP(reg)->jump.addr = SIZE_OP_PUSH + SIZE_INC_OP;
}
else {
- r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_JUMP);
+ COP(reg)->jump.addr = SIZE_OP_JUMP + SIZE_INC_OP;
}
- if (r != 0) return r;
}
else {
r = compile_tree_n_times(NODE_QUANT_BODY(qn), qn->lower, reg, env);
if (qn->greedy) {
if (IS_NOT_NULL(qn->head_exact)) {
- r = add_opcode_rel_addr(reg, OP_PUSH_OR_JUMP_EXACT1,
- mod_tlen + SIZE_OP_JUMP);
+ r = add_op(reg, OP_PUSH_OR_JUMP_EXACT1);
if (r != 0) return r;
- add_bytes(reg, STR_(qn->head_exact)->s, 1);
+ COP(reg)->push_or_jump_exact1.addr = SIZE_INC_OP + mod_tlen + SIZE_OP_JUMP;
+ COP(reg)->push_or_jump_exact1.c = STR_(qn->head_exact)->s[0];
+
r = compile_tree_empty_check(NODE_QUANT_BODY(qn), reg, empty_info, env);
if (r != 0) return r;
- r = add_opcode_rel_addr(reg, OP_JUMP,
- -(mod_tlen + (int )SIZE_OP_JUMP + (int )SIZE_OP_PUSH_OR_JUMP_EXACT1));
+
+ addr = -(mod_tlen + (int )SIZE_OP_PUSH_OR_JUMP_EXACT1);
}
else if (IS_NOT_NULL(qn->next_head_exact)) {
- r = add_opcode_rel_addr(reg, OP_PUSH_IF_PEEK_NEXT,
- mod_tlen + SIZE_OP_JUMP);
+ r = add_op(reg, OP_PUSH_IF_PEEK_NEXT);
if (r != 0) return r;
- add_bytes(reg, STR_(qn->next_head_exact)->s, 1);
+ COP(reg)->push_if_peek_next.addr = SIZE_INC_OP + mod_tlen + SIZE_OP_JUMP;
+ COP(reg)->push_if_peek_next.c = STR_(qn->next_head_exact)->s[0];
+
r = compile_tree_empty_check(NODE_QUANT_BODY(qn), reg, empty_info, env);
if (r != 0) return r;
- r = add_opcode_rel_addr(reg, OP_JUMP,
- -(mod_tlen + (int )SIZE_OP_JUMP + (int )SIZE_OP_PUSH_IF_PEEK_NEXT));
+
+ addr = -(mod_tlen + (int )SIZE_OP_PUSH_IF_PEEK_NEXT);
}
else {
- r = add_opcode_rel_addr(reg, OP_PUSH, mod_tlen + SIZE_OP_JUMP);
+ r = add_op(reg, OP_PUSH);
if (r != 0) return r;
+ COP(reg)->push.addr = SIZE_INC_OP + mod_tlen + SIZE_OP_JUMP;
+
r = compile_tree_empty_check(NODE_QUANT_BODY(qn), reg, empty_info, env);
if (r != 0) return r;
- r = add_opcode_rel_addr(reg, OP_JUMP,
- -(mod_tlen + (int )SIZE_OP_JUMP + (int )SIZE_OP_PUSH));
+
+ addr = -(mod_tlen + (int )SIZE_OP_PUSH);
}
+
+ r = add_op(reg, OP_JUMP);
+ if (r != 0) return r;
+ COP(reg)->jump.addr = addr;
}
else {
- r = add_opcode_rel_addr(reg, OP_JUMP, mod_tlen);
+ r = add_op(reg, OP_JUMP);
if (r != 0) return r;
+ COP(reg)->jump.addr = mod_tlen + SIZE_INC_OP;
+
r = compile_tree_empty_check(NODE_QUANT_BODY(qn), reg, empty_info, env);
if (r != 0) return r;
- r = add_opcode_rel_addr(reg, OP_PUSH, -(mod_tlen + (int )SIZE_OP_PUSH));
+
+ r = add_op(reg, OP_PUSH);
+ if (r != 0) return r;
+ COP(reg)->push.addr = -mod_tlen;
}
}
else if (qn->upper == 0 && qn->is_refered != 0) { /* /(?<n>..){0}/ */
- r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
+ r = add_op(reg, OP_JUMP);
if (r != 0) return r;
+ COP(reg)->jump.addr = tlen + SIZE_INC_OP;
+
r = compile_tree(NODE_QUANT_BODY(qn), reg, env);
}
else if (! infinite && qn->greedy &&
if (r != 0) return r;
for (i = 0; i < n; i++) {
- int v = onig_positive_int_multiply(n - i, tlen);
+ int v = onig_positive_int_multiply(n - i, tlen + SIZE_OP_PUSH);
if (v < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
- r = add_opcode_rel_addr(reg, OP_PUSH, v + (n - i - 1) * SIZE_OP_PUSH);
+
+ r = add_op(reg, OP_PUSH);
if (r != 0) return r;
+ COP(reg)->push.addr = v;
+
r = compile_tree(NODE_QUANT_BODY(qn), reg, env);
if (r != 0) return r;
}
}
else if (! qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
- r = add_opcode_rel_addr(reg, OP_PUSH, SIZE_OP_JUMP);
+ r = add_op(reg, OP_PUSH);
if (r != 0) return r;
- r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
+ COP(reg)->push.addr = SIZE_INC_OP + SIZE_OP_JUMP;
+
+ r = add_op(reg, OP_JUMP);
if (r != 0) return r;
+ COP(reg)->jump.addr = tlen + SIZE_INC_OP;
+
r = compile_tree(NODE_QUANT_BODY(qn), reg, env);
}
else {
int len;
#ifdef USE_CALL
- if (node->m.regnum == 0 && NODE_IS_CALLED(node)) {
- r = add_opcode(reg, OP_CALL);
+ if (NODE_IS_CALLED(node)) {
+ r = add_op(reg, OP_CALL);
if (r != 0) return r;
- node->m.called_addr = BB_GET_OFFSET_POS(reg) + SIZE_ABSADDR + SIZE_OP_JUMP;
+
+ node->m.called_addr = COP_CURR_OFFSET(reg) + 1 + SIZE_OP_JUMP;
NODE_STATUS_ADD(node, ADDR_FIXED);
- r = add_abs_addr(reg, (int )node->m.called_addr);
- if (r != 0) return r;
- len = compile_length_tree(NODE_BAG_BODY(node), reg);
- len += SIZE_OP_RETURN;
- r = add_opcode_rel_addr(reg, OP_JUMP, len);
- if (r != 0) return r;
+ COP(reg)->call.addr = (int )node->m.called_addr;
- r = compile_tree(NODE_BAG_BODY(node), reg, env);
- if (r != 0) return r;
- r = add_opcode(reg, OP_RETURN);
- return r;
- }
+ if (node->m.regnum == 0) {
+ len = compile_length_tree(NODE_BAG_BODY(node), reg);
+ len += SIZE_OP_RETURN;
- if (NODE_IS_CALLED(node)) {
- r = add_opcode(reg, OP_CALL);
- if (r != 0) return r;
- node->m.called_addr = BB_GET_OFFSET_POS(reg) + SIZE_ABSADDR + SIZE_OP_JUMP;
- NODE_STATUS_ADD(node, ADDR_FIXED);
- r = add_abs_addr(reg, (int )node->m.called_addr);
- if (r != 0) return r;
- len = compile_length_tree(NODE_BAG_BODY(node), reg);
- len += (SIZE_OP_MEMORY_START_PUSH + SIZE_OP_RETURN);
- if (MEM_STATUS_AT0(reg->bt_mem_end, node->m.regnum))
- len += (NODE_IS_RECURSION(node)
- ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
- else
- len += (NODE_IS_RECURSION(node)
- ? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
+ r = add_op(reg, OP_JUMP);
+ if (r != 0) return r;
+ COP(reg)->jump.addr = len + SIZE_INC_OP;
- r = add_opcode_rel_addr(reg, OP_JUMP, len);
- if (r != 0) return r;
+ r = compile_tree(NODE_BAG_BODY(node), reg, env);
+ if (r != 0) return r;
+
+ r = add_op(reg, OP_RETURN);
+ return r;
+ }
+ else {
+ len = compile_length_tree(NODE_BAG_BODY(node), reg);
+ len += (SIZE_OP_MEMORY_START_PUSH + SIZE_OP_RETURN);
+ if (MEM_STATUS_AT0(reg->bt_mem_end, node->m.regnum))
+ len += (NODE_IS_RECURSION(node)
+ ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
+ else
+ len += (NODE_IS_RECURSION(node)
+ ? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
+
+ r = add_op(reg, OP_JUMP);
+ if (r != 0) return r;
+ COP(reg)->jump.addr = len + SIZE_INC_OP;
+ }
}
#endif
if (MEM_STATUS_AT0(reg->bt_mem_start, node->m.regnum))
- r = add_opcode(reg, OP_MEMORY_START_PUSH);
+ r = add_op(reg, OP_MEMORY_START_PUSH);
else
- r = add_opcode(reg, OP_MEMORY_START);
- if (r != 0) return r;
- r = add_mem_num(reg, node->m.regnum);
+ r = add_op(reg, OP_MEMORY_START);
if (r != 0) return r;
+ COP(reg)->memory_start.num = node->m.regnum;
+
r = compile_tree(NODE_BAG_BODY(node), reg, env);
if (r != 0) return r;
#ifdef USE_CALL
if (MEM_STATUS_AT0(reg->bt_mem_end, node->m.regnum))
- r = add_opcode(reg, (NODE_IS_RECURSION(node)
- ? OP_MEMORY_END_PUSH_REC : OP_MEMORY_END_PUSH));
+ r = add_op(reg, (NODE_IS_RECURSION(node)
+ ? OP_MEMORY_END_PUSH_REC : OP_MEMORY_END_PUSH));
else
- r = add_opcode(reg, (NODE_IS_RECURSION(node)
- ? OP_MEMORY_END_REC : OP_MEMORY_END));
+ r = add_op(reg, (NODE_IS_RECURSION(node) ? OP_MEMORY_END_REC : OP_MEMORY_END));
if (r != 0) return r;
- r = add_mem_num(reg, node->m.regnum);
+ COP(reg)->memory_end.num = node->m.regnum;
+
if (NODE_IS_CALLED(node)) {
if (r != 0) return r;
- r = add_opcode(reg, OP_RETURN);
+ r = add_op(reg, OP_RETURN);
}
#else
if (MEM_STATUS_AT0(reg->bt_mem_end, node->m.regnum))
- r = add_opcode(reg, OP_MEMORY_END_PUSH);
+ r = add_op(reg, OP_MEMORY_END_PUSH);
else
- r = add_opcode(reg, OP_MEMORY_END);
+ r = add_op(reg, OP_MEMORY_END);
if (r != 0) return r;
- r = add_mem_num(reg, node->m.regnum);
+ COP(reg)->memory_end.num = node->m.regnum;
#endif
return r;
len = compile_length_tree(NODE_QUANT_BODY(qn), reg);
if (len < 0) return len;
- r = add_opcode_rel_addr(reg, OP_PUSH, len + SIZE_OP_POP_OUT + SIZE_OP_JUMP);
+ r = add_op(reg, OP_PUSH);
if (r != 0) return r;
+ COP(reg)->push.addr = SIZE_INC_OP + len + SIZE_OP_POP_OUT + SIZE_OP_JUMP;
+
r = compile_tree(NODE_QUANT_BODY(qn), reg, env);
if (r != 0) return r;
- r = add_opcode(reg, OP_POP_OUT);
+ r = add_op(reg, OP_POP_OUT);
if (r != 0) return r;
- r = add_opcode_rel_addr(reg, OP_JUMP,
- -((int )SIZE_OP_PUSH + len + (int )SIZE_OP_POP_OUT + (int )SIZE_OP_JUMP));
+
+ r = add_op(reg, OP_JUMP);
+ if (r != 0) return r;
+ COP(reg)->jump.addr = -((int )SIZE_OP_PUSH + len + (int )SIZE_OP_POP_OUT);
}
else {
- r = add_opcode(reg, OP_ATOMIC_START);
+ r = add_op(reg, OP_ATOMIC_START);
if (r != 0) return r;
r = compile_tree(NODE_BAG_BODY(node), reg, env);
if (r != 0) return r;
- r = add_opcode(reg, OP_ATOMIC_END);
+ r = add_op(reg, OP_ATOMIC_END);
}
break;
Node* Then = node->te.Then;
Node* Else = node->te.Else;
- r = add_opcode(reg, OP_ATOMIC_START);
+ r = add_op(reg, OP_ATOMIC_START);
if (r != 0) return r;
cond_len = compile_length_tree(cond, reg);
jump_len = cond_len + then_len + SIZE_OP_ATOMIC_END;
if (IS_NOT_NULL(Else)) jump_len += SIZE_OP_JUMP;
- r = add_opcode_rel_addr(reg, OP_PUSH, jump_len);
+ r = add_op(reg, OP_PUSH);
if (r != 0) return r;
+ COP(reg)->push.addr = SIZE_INC_OP + jump_len;
+
r = compile_tree(cond, reg, env);
if (r != 0) return r;
- r = add_opcode(reg, OP_ATOMIC_END);
+ r = add_op(reg, OP_ATOMIC_END);
if (r != 0) return r;
if (IS_NOT_NULL(Then)) {
if (IS_NOT_NULL(Else)) {
int else_len = compile_length_tree(Else, reg);
- r = add_opcode_rel_addr(reg, OP_JUMP, else_len);
+ r = add_op(reg, OP_JUMP);
if (r != 0) return r;
+ COP(reg)->jump.addr = else_len + SIZE_INC_OP;
+
r = compile_tree(Else, reg, env);
}
}
enum OpCode op;
switch (node->type) {
- case ANCR_BEGIN_BUF: r = add_opcode(reg, OP_BEGIN_BUF); break;
- case ANCR_END_BUF: r = add_opcode(reg, OP_END_BUF); break;
- case ANCR_BEGIN_LINE: r = add_opcode(reg, OP_BEGIN_LINE); break;
- case ANCR_END_LINE: r = add_opcode(reg, OP_END_LINE); break;
- case ANCR_SEMI_END_BUF: r = add_opcode(reg, OP_SEMI_END_BUF); break;
- case ANCR_BEGIN_POSITION: r = add_opcode(reg, OP_BEGIN_POSITION); break;
+ case ANCR_BEGIN_BUF: r = add_op(reg, OP_BEGIN_BUF); break;
+ case ANCR_END_BUF: r = add_op(reg, OP_END_BUF); break;
+ case ANCR_BEGIN_LINE: r = add_op(reg, OP_BEGIN_LINE); break;
+ case ANCR_END_LINE: r = add_op(reg, OP_END_LINE); break;
+ case ANCR_SEMI_END_BUF: r = add_op(reg, OP_SEMI_END_BUF); break;
+ case ANCR_BEGIN_POSITION: r = add_op(reg, OP_BEGIN_POSITION); break;
case ANCR_WORD_BOUNDARY:
op = OP_WORD_BOUNDARY;
word:
- r = add_opcode(reg, op);
+ r = add_op(reg, op);
if (r != 0) return r;
- r = add_mode(reg, (ModeType )node->ascii_mode);
+ COP(reg)->word_boundary.mode = (ModeType )node->ascii_mode;
break;
case ANCR_NO_WORD_BOUNDARY:
#endif
case ANCR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
- r = add_opcode(reg, OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);
+ r = add_op(reg, OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);
break;
case ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
- r = add_opcode(reg, OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);
+ r = add_op(reg, OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);
break;
case ANCR_PREC_READ:
- r = add_opcode(reg, OP_PREC_READ_START);
+ r = add_op(reg, OP_PREC_READ_START);
if (r != 0) return r;
r = compile_tree(NODE_ANCHOR_BODY(node), reg, env);
if (r != 0) return r;
- r = add_opcode(reg, OP_PREC_READ_END);
+ r = add_op(reg, OP_PREC_READ_END);
break;
case ANCR_PREC_READ_NOT:
len = compile_length_tree(NODE_ANCHOR_BODY(node), reg);
if (len < 0) return len;
- r = add_opcode_rel_addr(reg, OP_PREC_READ_NOT_START, len + SIZE_OP_PREC_READ_NOT_END);
+
+ r = add_op(reg, OP_PREC_READ_NOT_START);
if (r != 0) return r;
+ COP(reg)->prec_read_not_start.addr = SIZE_INC_OP + len + SIZE_OP_PREC_READ_NOT_END;
r = compile_tree(NODE_ANCHOR_BODY(node), reg, env);
if (r != 0) return r;
- r = add_opcode(reg, OP_PREC_READ_NOT_END);
+ r = add_op(reg, OP_PREC_READ_NOT_END);
break;
case ANCR_LOOK_BEHIND:
{
int n;
- r = add_opcode(reg, OP_LOOK_BEHIND);
+ r = add_op(reg, OP_LOOK_BEHIND);
if (r != 0) return r;
if (node->char_len < 0) {
r = get_char_len_node(NODE_ANCHOR_BODY(node), reg, &n);
else
n = node->char_len;
- r = add_length(reg, n);
- if (r != 0) return r;
+ COP(reg)->look_behind.len = n;
r = compile_tree(NODE_ANCHOR_BODY(node), reg, env);
}
break;
int n;
len = compile_length_tree(NODE_ANCHOR_BODY(node), reg);
- r = add_opcode_rel_addr(reg, OP_LOOK_BEHIND_NOT_START,
- len + SIZE_OP_LOOK_BEHIND_NOT_END);
+ r = add_op(reg, OP_LOOK_BEHIND_NOT_START);
if (r != 0) return r;
+ COP(reg)->look_behind_not_start.addr = SIZE_INC_OP + len + SIZE_OP_LOOK_BEHIND_NOT_END;
+
if (node->char_len < 0) {
r = get_char_len_node(NODE_ANCHOR_BODY(node), reg, &n);
if (r != 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
}
else
n = node->char_len;
- r = add_length(reg, n);
- if (r != 0) return r;
+
+ COP(reg)->look_behind_not_start.len = n;
+
r = compile_tree(NODE_ANCHOR_BODY(node), reg, env);
if (r != 0) return r;
- r = add_opcode(reg, OP_LOOK_BEHIND_NOT_END);
+ r = add_op(reg, OP_LOOK_BEHIND_NOT_END);
}
break;
switch (node->type) {
case GIMMICK_FAIL:
- r = add_opcode(reg, OP_FAIL);
+ r = add_op(reg, OP_FAIL);
break;
case GIMMICK_KEEP:
- r = add_opcode(reg, OP_PUSH_SAVE_VAL);
+ r = add_op(reg, OP_PUSH_SAVE_VAL);
if (r != 0) return r;
- r = add_save_type(reg, SAVE_KEEP);
- if (r != 0) return r;
- r = add_mem_num(reg, node->id);
+ COP(reg)->push_save_val.type = SAVE_KEEP;
+ COP(reg)->push_save_val.id = node->id;
break;
case GIMMICK_SAVE:
- r = add_opcode(reg, OP_PUSH_SAVE_VAL);
- if (r != 0) return r;
- r = add_save_type(reg, node->detail_type);
+ r = add_op(reg, OP_PUSH_SAVE_VAL);
if (r != 0) return r;
- r = add_mem_num(reg, node->id);
+ COP(reg)->push_save_val.type = node->detail_type;
+ COP(reg)->push_save_val.id = node->id;
break;
case GIMMICK_UPDATE_VAR:
- r = add_opcode(reg, OP_UPDATE_VAR);
- if (r != 0) return r;
- r = add_update_var_type(reg, node->detail_type);
+ r = add_op(reg, OP_UPDATE_VAR);
if (r != 0) return r;
- r = add_mem_num(reg, node->id);
+ COP(reg)->update_var.type = node->detail_type;
+ COP(reg)->update_var.id = node->id;
break;
#ifdef USE_CALLOUT
case ONIG_CALLOUT_OF_CONTENTS:
case ONIG_CALLOUT_OF_NAME:
{
- r = add_opcode(reg, (node->detail_type == ONIG_CALLOUT_OF_CONTENTS) ?
- OP_CALLOUT_CONTENTS : OP_CALLOUT_NAME);
- if (r != 0) return r;
if (node->detail_type == ONIG_CALLOUT_OF_NAME) {
- r = add_mem_num(reg, node->id);
+ r = add_op(reg, OP_CALLOUT_NAME);
if (r != 0) return r;
+ COP(reg)->callout_name.id = node->id;
+ COP(reg)->callout_name.num = node->num;
+ }
+ else {
+ r = add_op(reg, OP_CALLOUT_CONTENTS);
+ if (r != 0) return r;
+ COP(reg)->callout_contents.num = node->num;
}
- r = add_mem_num(reg, node->num);
- if (r != 0) return r;
}
break;
break;
case NODE_BACKREF:
- {
- BackRefNode* br = BACKREF_(node);
-
- if (NODE_IS_CHECKER(node)) {
-#ifdef USE_BACKREF_WITH_LEVEL
- if (NODE_IS_NEST_LEVEL(node)) {
- r = SIZE_OPCODE + SIZE_LENGTH + SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
- }
- else
-#endif
- r = SIZE_OPCODE + SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
- }
- else {
-#ifdef USE_BACKREF_WITH_LEVEL
- if (NODE_IS_NEST_LEVEL(node)) {
- r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
- SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
- }
- else
-#endif
- if (br->back_num == 1) {
- r = ((!IS_IGNORECASE(reg->options) && br->back_static[0] <= 2)
- ? SIZE_OPCODE : (SIZE_OPCODE + SIZE_MEMNUM));
- }
- else {
- r = SIZE_OPCODE + SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
- }
- }
- }
+ r = SIZE_OP_BACKREF;
break;
#ifdef USE_CALL
len += SIZE_OP_PUSH + SIZE_OP_JUMP;
}
} while (IS_NOT_NULL(x = NODE_CDR(x)));
- pos = reg->used + len; /* goal position */
+ pos = COP_CURR_OFFSET(reg) + 1 + len; /* goal position */
do {
len = compile_length_tree(NODE_CAR(node), reg);
if (IS_NOT_NULL(NODE_CDR(node))) {
enum OpCode push = NODE_IS_SUPER(node) ? OP_PUSH_SUPER : OP_PUSH;
- r = add_opcode_rel_addr(reg, push, len + SIZE_OP_JUMP);
+ r = add_op(reg, push);
if (r != 0) break;
+ COP(reg)->push.addr = SIZE_INC_OP + len + SIZE_OP_JUMP;
}
r = compile_tree(NODE_CAR(node), reg, env);
if (r != 0) break;
if (IS_NOT_NULL(NODE_CDR(node))) {
- len = pos - (reg->used + SIZE_OP_JUMP);
- r = add_opcode_rel_addr(reg, OP_JUMP, len);
+ len = pos - (COP_CURR_OFFSET(reg) + 1);
+ r = add_op(reg, OP_JUMP);
if (r != 0) break;
+ COP(reg)->jump.addr = len;
}
} while (IS_NOT_NULL(node = NODE_CDR(node)));
}
switch (CTYPE_(node)->ctype) {
case CTYPE_ANYCHAR:
- if (IS_MULTILINE(CTYPE_OPTION(node, reg)))
- r = add_opcode(reg, OP_ANYCHAR_ML);
- else
- r = add_opcode(reg, OP_ANYCHAR);
+ r = add_op(reg, IS_MULTILINE(CTYPE_OPTION(node, reg)) ?
+ OP_ANYCHAR_ML : OP_ANYCHAR);
break;
case ONIGENC_CTYPE_WORD:
else {
op = CTYPE_(node)->not != 0 ? OP_NO_WORD_ASCII : OP_WORD_ASCII;
}
- r = add_opcode(reg, op);
+ r = add_op(reg, op);
break;
default:
if (NODE_IS_CHECKER(node)) {
#ifdef USE_BACKREF_WITH_LEVEL
if (NODE_IS_NEST_LEVEL(node)) {
- r = add_opcode(reg, OP_BACKREF_CHECK_WITH_LEVEL);
- if (r != 0) return r;
- r = add_length(reg, br->nest_level);
+ r = add_op(reg, OP_BACKREF_CHECK_WITH_LEVEL);
if (r != 0) return r;
+ COP(reg)->backref_general.nest_level = br->nest_level;
}
else
#endif
{
- r = add_opcode(reg, OP_BACKREF_CHECK);
+ r = add_op(reg, OP_BACKREF_CHECK);
if (r != 0) return r;
}
-
goto add_bacref_mems;
}
else {
#ifdef USE_BACKREF_WITH_LEVEL
if (NODE_IS_NEST_LEVEL(node)) {
- r = add_opcode(reg, OP_BACKREF_WITH_LEVEL);
+ r = add_op(reg, OP_BACKREF_WITH_LEVEL);
if (r != 0) return r;
- r = add_option(reg, (reg->options & ONIG_OPTION_IGNORECASE));
- if (r != 0) return r;
- r = add_length(reg, br->nest_level);
- if (r != 0) return r;
-
+ COP(reg)->backref_general.options =
+ (reg->options & ONIG_OPTION_IGNORECASE);
+ COP(reg)->backref_general.nest_level = br->nest_level;
goto add_bacref_mems;
}
else
if (br->back_num == 1) {
n = br->back_static[0];
if (IS_IGNORECASE(reg->options)) {
- r = add_opcode(reg, OP_BACKREF_N_IC);
+ r = add_op(reg, OP_BACKREF_N_IC);
if (r != 0) return r;
- r = add_mem_num(reg, n);
+ COP(reg)->backref_n.n1 = n;
}
else {
switch (n) {
- case 1: r = add_opcode(reg, OP_BACKREF1); break;
- case 2: r = add_opcode(reg, OP_BACKREF2); break;
+ case 1: r = add_op(reg, OP_BACKREF1); break;
+ case 2: r = add_op(reg, OP_BACKREF2); break;
default:
- r = add_opcode(reg, OP_BACKREF_N);
+ r = add_op(reg, OP_BACKREF_N);
if (r != 0) return r;
- r = add_mem_num(reg, n);
+ COP(reg)->backref_n.n1 = n;
break;
}
}
}
else {
- int i;
+ int num;
int* p;
- if (IS_IGNORECASE(reg->options)) {
- r = add_opcode(reg, OP_BACKREF_MULTI_IC);
- }
- else {
- r = add_opcode(reg, OP_BACKREF_MULTI);
- }
+ r = add_op(reg, IS_IGNORECASE(reg->options) ?
+ OP_BACKREF_MULTI_IC : OP_BACKREF_MULTI);
if (r != 0) return r;
add_bacref_mems:
- r = add_length(reg, br->back_num);
- if (r != 0) return r;
- p = BACKREFS_P(br);
- for (i = br->back_num - 1; i >= 0; i--) {
- r = add_mem_num(reg, p[i]);
- if (r != 0) return r;
+ num = br->back_num;
+ COP(reg)->backref_general.num = num;
+ if (num == 1) {
+ COP(reg)->backref_general.n1 = br->back_static[0];
+ }
+ else {
+ int i, j;
+ MemNumType* ns;
+
+ ns = xmalloc(sizeof(MemNumType) * num);
+ CHECK_NULL_RETURN_MEMERR(ns);
+ COP(reg)->backref_general.ns = ns;
+ p = BACKREFS_P(br);
+ for (i = num - 1, j = 0; i >= 0; i--, j++) {
+ ns[j] = p[i];
+ }
}
}
}
int i, offset;
BagNode* en;
AbsAddrType addr;
+ AbsAddrType* paddr;
for (i = 0; i < uslist->num; i++) {
if (! NODE_IS_ADDR_FIXED(uslist->us[i].target))
addr = en->m.called_addr;
offset = uslist->us[i].offset;
- BB_WRITE(reg, offset, &addr, SIZE_ABSADDR);
+ paddr = (AbsAddrType* )((void* )reg->ops + offset);
+ *paddr = addr;
}
return 0;
}
case NODE_LIST:
case NODE_ALT:
do {
- r = check_type_tree(NODE_CAR(node), type_mask, bag_mask,
- anchor_mask);
+ r = check_type_tree(NODE_CAR(node), type_mask, bag_mask, anchor_mask);
} while (r == 0 && IS_NOT_NULL(node = NODE_CDR(node)));
break;
return ONIG_NORMAL;
}
-
extern void
onig_free_body(regex_t* reg)
{
if (IS_NOT_NULL(reg)) {
- if (IS_NOT_NULL(reg->p)) xfree(reg->p);
+ ops_free(reg);
if (IS_NOT_NULL(reg->exact)) xfree(reg->exact);
if (IS_NOT_NULL(reg->repeat_range)) xfree(reg->repeat_range);
if (IS_NOT_NULL(reg->extp)) {
onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
OnigErrorInfo* einfo)
{
-#define COMPILE_INIT_SIZE 20
+#define OPS_INIT_SIZE 8
- int r, init_size;
+ int r;
Node* root;
ScanEnv scan_env;
#ifdef USE_CALL
print_enc_string(stderr, reg->enc, pattern, pattern_end);
#endif
- if (reg->alloc == 0) {
- init_size = (int )(pattern_end - pattern) * 2;
- if (init_size <= 0) init_size = COMPILE_INIT_SIZE;
- r = BB_INIT(reg, init_size);
+ if (reg->ops_alloc == 0) {
+ r = ops_init(reg, OPS_INIT_SIZE);
if (r != 0) goto end;
}
else
- reg->used = 0;
+ reg->ops_used = 0;
reg->num_mem = 0;
reg->num_repeat = 0;
r = compile_tree(root, reg, &scan_env);
if (r == 0) {
if (scan_env.keep_num > 0) {
- r = add_opcode(reg, OP_UPDATE_VAR);
- if (r != 0) goto err;
- r = add_update_var_type(reg, UPDATE_VAR_KEEP_FROM_STACK_LAST);
- if (r != 0) goto err;
- r = add_mem_num(reg, 0 /* not used */);
+ r = add_op(reg, OP_UPDATE_VAR);
if (r != 0) goto err;
+
+ COP(reg)->update_var.type = UPDATE_VAR_KEEP_FROM_STACK_LAST;
+ COP(reg)->update_var.id = 0; /* not used */
}
- r = add_opcode(reg, OP_END);
+ r = add_op(reg, OP_END);
+ if (r != 0) goto err;
+
#ifdef USE_CALL
if (scan_env.num_call > 0) {
r = fix_unset_addr_list(&uslist, reg);
(reg)->exact = (UChar* )NULL;
(reg)->extp = (RegexExt* )NULL;
- (reg)->p = (UChar* )NULL;
- (reg)->alloc = 0;
- (reg)->used = 0;
+ (reg)->ops = (Operation* )NULL;
+ (reg)->ops_curr = (Operation* )NULL;
+ (reg)->ops_used = 0;
+ (reg)->ops_alloc = 0;
(reg)->name_table = (void* )NULL;
(reg)->case_fold_flag = case_fold_flag;
return "";
}
+#if 0
static int
op2arg_type(int opcode)
{
}
return ARG_SPECIAL;
}
+#endif
static void
p_string(FILE* f, int len, UChar* s)
}
static void
-p_rel_addr(FILE* f, RelAddrType rel_addr, UChar* p, UChar* start)
+p_rel_addr(FILE* f, RelAddrType rel_addr, Operation* p, Operation* start)
{
RelAddrType curr = (RelAddrType )(p - start);
}
extern void
-onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar** nextp, UChar* start,
- OnigEncoding enc)
+onig_print_compiled_byte_code(FILE* f, Operation* p, Operation* start, OnigEncoding enc)
{
int i, n;
- OpArgType arg_type;
RelAddrType addr;
LengthType len;
MemNumType mem;
ModeType mode;
UChar *q;
- fprintf(f, "%s", op2name(*bp));
- arg_type = op2arg_type(*bp);
- if (arg_type != ARG_SPECIAL) {
- bp++;
- switch (arg_type) {
- case ARG_NON:
- break;
- case ARG_RELADDR:
- GET_RELADDR_INC(addr, bp);
- fputc(':', f);
- p_rel_addr(f, addr, bp, start);
- break;
- case ARG_ABSADDR:
- GET_ABSADDR_INC(addr, bp);
- fprintf(f, ":{/%d}", addr);
- break;
- case ARG_LENGTH:
- GET_LENGTH_INC(len, bp);
- fprintf(f, ":%d", len);
- break;
- case ARG_MEMNUM:
- mem = *((MemNumType* )bp);
- bp += SIZE_MEMNUM;
- fprintf(f, ":%d", mem);
- break;
- case ARG_OPTION:
- {
- OnigOptionType option = *((OnigOptionType* )bp);
- bp += SIZE_OPTION;
- fprintf(f, ":%d", option);
- }
- break;
- case ARG_MODE:
- mode = *((ModeType* )bp);
- bp += SIZE_MODE;
- fprintf(f, ":%d", mode);
- break;
- default:
- break;
+ fprintf(f, "%s", op2name(p->opcode));
+ switch (p->opcode) {
+ case OP_EXACT1:
+ p_string(f, 1, p->exact.s); break;
+ case OP_EXACT2:
+ p_string(f, 2, p->exact.s); break;
+ case OP_EXACT3:
+ p_string(f, 3, p->exact.s); break;
+ case OP_EXACT4:
+ p_string(f, 4, p->exact.s); break;
+ case OP_EXACT5:
+ p_string(f, 5, p->exact.s); break;
+ case OP_EXACTN:
+ len = p->exact_n.n;
+ p_string(f, len, p->exact_n.s); break;
+ case OP_EXACTMB2N1:
+ p_string(f, 2, p->exact.s); break;
+ case OP_EXACTMB2N2:
+ p_string(f, 4, p->exact.s); break;
+ case OP_EXACTMB2N3:
+ p_string(f, 3, p->exact.s); break;
+ case OP_EXACTMB2N:
+ len = p->exact_n.n;
+ p_len_string(f, len, 2, p->exact_n.s); break;
+ case OP_EXACTMB3N:
+ len = p->exact_n.n;
+ p_len_string(f, len, 3, p->exact_n.s); break;
+ case OP_EXACTMBN:
+ {
+ int mb_len;
+
+ mb_len = p->exact_len_n.len;
+ len = p->exact_len_n.n;
+ q = p->exact_len_n.s;
+ fprintf(f, ":%d:%d:", mb_len, len);
+ n = len * mb_len;
+ while (n-- > 0) { fputc(*q++, f); }
}
- }
- else {
- switch (*bp++) {
- case OP_EXACT1:
- case OP_ANYCHAR_STAR_PEEK_NEXT:
- case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
- p_string(f, 1, bp++); break;
- case OP_EXACT2:
- p_string(f, 2, bp); bp += 2; break;
- case OP_EXACT3:
- p_string(f, 3, bp); bp += 3; break;
- case OP_EXACT4:
- p_string(f, 4, bp); bp += 4; break;
- case OP_EXACT5:
- p_string(f, 5, bp); bp += 5; break;
- case OP_EXACTN:
- GET_LENGTH_INC(len, bp);
- p_len_string(f, len, 1, bp);
- bp += len;
- break;
+ break;
+ case OP_EXACT1_IC:
+ len = enclen(enc, p->exact.s);
+ p_string(f, len, p->exact.s);
+ break;
+ case OP_EXACTN_IC:
+ len = p->exact_n.n;
+ p_len_string(f, len, 1, p->exact_n.s);
+ break;
- case OP_EXACTMB2N1:
- p_string(f, 2, bp); bp += 2; break;
- case OP_EXACTMB2N2:
- p_string(f, 4, bp); bp += 4; break;
- case OP_EXACTMB2N3:
- p_string(f, 6, bp); bp += 6; break;
- case OP_EXACTMB2N:
- GET_LENGTH_INC(len, bp);
- p_len_string(f, len, 2, bp);
- bp += len * 2;
- break;
- case OP_EXACTMB3N:
- GET_LENGTH_INC(len, bp);
- p_len_string(f, len, 3, bp);
- bp += len * 3;
- break;
- case OP_EXACTMBN:
- {
- int mb_len;
+ case OP_CCLASS:
+ case OP_CCLASS_NOT:
+ n = bitset_on_num(p->cclass.bs);
+ fprintf(f, ":%d", n);
+ break;
+ case OP_CCLASS_MB:
+ case OP_CCLASS_MB_NOT:
+ {
+ OnigCodePoint ncode;
+ OnigCodePoint* codes;
+
+ codes = (OnigCodePoint* )p->cclass_mb.mb;
+ GET_CODE_POINT(ncode, codes);
+ codes++;
+ GET_CODE_POINT(code, codes);
+ fprintf(f, ":%u:%u", code, ncode);
+ }
+ break;
+ case OP_CCLASS_MIX:
+ case OP_CCLASS_MIX_NOT:
+ {
+ OnigCodePoint ncode;
+ OnigCodePoint* codes;
+
+ codes = (OnigCodePoint* )p->cclass_mix.mb;
+ n = bitset_on_num(p->cclass_mix.bs);
+
+ GET_CODE_POINT(ncode, codes);
+ codes++;
+ GET_CODE_POINT(code, codes);
+ fprintf(f, ":%d:%u:%u", n, code, ncode);
+ }
+ break;
- GET_LENGTH_INC(mb_len, bp);
- GET_LENGTH_INC(len, bp);
- fprintf(f, ":%d:%d:", mb_len, len);
- n = len * mb_len;
- while (n-- > 0) { fputc(*bp++, f); }
- }
- break;
+ case OP_ANYCHAR_STAR_PEEK_NEXT:
+ case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
+ p_string(f, 1, &(p->anychar_star_peek_next.c));
+ break;
- case OP_EXACT1_IC:
- len = enclen(enc, bp);
- p_string(f, len, bp);
- bp += len;
- break;
- case OP_EXACTN_IC:
- GET_LENGTH_INC(len, bp);
- p_len_string(f, len, 1, bp);
- bp += len;
- break;
+ case OP_WORD_BOUNDARY:
+ case OP_NO_WORD_BOUNDARY:
+ case OP_WORD_BEGIN:
+ case OP_WORD_END:
+ mode = p->word_boundary.mode;
+ fprintf(f, ":%d", mode);
+ break;
- case OP_CCLASS:
- n = bitset_on_num((BitSetRef )bp);
- bp += SIZE_BITSET;
- fprintf(f, ":%d", n);
- break;
+ case OP_BACKREF_N:
+ case OP_BACKREF_N_IC:
+ mem = p->backref_n.n1;
+ fprintf(f, ":%d", mem);
+ break;
+ case OP_BACKREF_MULTI_IC:
+ case OP_BACKREF_MULTI:
+ case OP_BACKREF_CHECK:
+ fputs(" ", f);
+ n = p->backref_general.num;
+ for (i = 0; i < n; i++) {
+ mem = (n == 1) ? p->backref_general.n1 : p->backref_general.ns[i];
+ if (i > 0) fputs(", ", f);
+ fprintf(f, "%d", mem);
+ }
+ break;
+ case OP_BACKREF_WITH_LEVEL:
+ option = p->backref_general.options;
+ fprintf(f, ":%d", option);
+ /* fall */
+ case OP_BACKREF_CHECK_WITH_LEVEL:
+ {
+ LengthType level;
+
+ level = p->backref_general.nest_level;
+ fprintf(f, ":%d", level);
+ fputs(" ", f);
+ n = p->backref_general.num;
+ for (i = 0; i < n; i++) {
+ mem = (n == 1) ? p->backref_general.n1 : p->backref_general.ns[i];
+ if (i > 0) fputs(", ", f);
+ fprintf(f, "%d", mem);
+ }
+ }
+ break;
- case OP_CCLASS_NOT:
- n = bitset_on_num((BitSetRef )bp);
- bp += SIZE_BITSET;
- fprintf(f, ":%d", n);
- break;
+ case OP_MEMORY_START:
+ case OP_MEMORY_START_PUSH:
+ mem = p->memory_start.num;
+ fprintf(f, ":%d", mem);
+ break;
+ case OP_MEMORY_END_PUSH:
+ case OP_MEMORY_END_PUSH_REC:
+ case OP_MEMORY_END:
+ case OP_MEMORY_END_REC:
+ mem = p->memory_end.num;
+ fprintf(f, ":%d", mem);
+ break;
- case OP_CCLASS_MB:
- case OP_CCLASS_MB_NOT:
- GET_LENGTH_INC(len, bp);
- q = bp;
-#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
- ALIGNMENT_RIGHT(q);
-#endif
- GET_CODE_POINT(code, q);
- bp += len;
- fprintf(f, ":%d:%d", (int )code, len);
- break;
+ case OP_JUMP:
+ addr = p->jump.addr;
+ fputc(':', f);
+ p_rel_addr(f, addr, p, start);
+ break;
- case OP_CCLASS_MIX:
- case OP_CCLASS_MIX_NOT:
- n = bitset_on_num((BitSetRef )bp);
- bp += SIZE_BITSET;
- GET_LENGTH_INC(len, bp);
- q = bp;
-#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
- ALIGNMENT_RIGHT(q);
-#endif
- GET_CODE_POINT(code, q);
- bp += len;
- fprintf(f, ":%d:%d:%d", n, (int )code, len);
- break;
+ case OP_PUSH:
+ case OP_PUSH_SUPER:
+ addr = p->push.addr;
+ fputc(':', f);
+ p_rel_addr(f, addr, p, start);
+ break;
-#ifdef USE_OP_CCLASS_NODE
- case OP_CCLASS_NODE:
- {
- CClassNode *cc;
+ case OP_PUSH_OR_JUMP_EXACT1:
+ addr = p->push_or_jump_exact1.addr;
+ fputc(':', f);
+ p_rel_addr(f, addr, p, start);
+ p_string(f, 1, &(p->push_or_jump_exact1.c));
+ break;
- GET_POINTER_INC(cc, bp);
- n = bitset_on_num(cc->bs);
- fprintf(f, ":%p:%d", cc, n);
- }
- break;
-#endif
+ case OP_PUSH_IF_PEEK_NEXT:
+ addr = p->push_if_peek_next.addr;
+ fputc(':', f);
+ p_rel_addr(f, addr, p, start);
+ p_string(f, 1, &(p->push_if_peek_next.c));
+ break;
- case OP_BACKREF_N_IC:
- mem = *((MemNumType* )bp);
- bp += SIZE_MEMNUM;
- fprintf(f, ":%d", mem);
- break;
+ case OP_REPEAT:
+ case OP_REPEAT_NG:
+ mem = p->repeat.id;
+ addr = p->repeat.addr;
+ fprintf(f, ":%d:%d", mem, addr);
+ break;
- case OP_BACKREF_MULTI_IC:
- case OP_BACKREF_MULTI:
- case OP_BACKREF_CHECK:
- fputs(" ", f);
- GET_LENGTH_INC(len, bp);
- for (i = 0; i < len; i++) {
- GET_MEMNUM_INC(mem, bp);
- if (i > 0) fputs(", ", f);
- fprintf(f, "%d", mem);
- }
- break;
+ case OP_REPEAT_INC:
+ case OP_REPEAT_INC_NG:
+ case OP_REPEAT_INC_SG:
+ case OP_REPEAT_INC_NG_SG:
+ mem = p->repeat.id;
+ fprintf(f, ":%d", mem);
+ break;
- case OP_BACKREF_WITH_LEVEL:
- GET_OPTION_INC(option, bp);
- fprintf(f, ":%d", option);
- /* fall */
- case OP_BACKREF_CHECK_WITH_LEVEL:
- {
- LengthType level;
+ case OP_EMPTY_CHECK_START:
+ mem = p->empty_check_start.mem;
+ fprintf(f, ":%d", mem);
+ break;
+ case OP_EMPTY_CHECK_END:
+ case OP_EMPTY_CHECK_END_MEMST:
+ case OP_EMPTY_CHECK_END_MEMST_PUSH:
+ mem = p->empty_check_end.mem;
+ fprintf(f, ":%d", mem);
+ break;
- GET_LENGTH_INC(level, bp);
- fprintf(f, ":%d", level);
+ case OP_PREC_READ_NOT_START:
+ addr = p->prec_read_not_start.addr;
+ fputc(':', f);
+ p_rel_addr(f, addr, p, start);
+ break;
- fputs(" ", f);
- GET_LENGTH_INC(len, bp);
- for (i = 0; i < len; i++) {
- GET_MEMNUM_INC(mem, bp);
- if (i > 0) fputs(", ", f);
- fprintf(f, "%d", mem);
- }
- }
- break;
+ case OP_LOOK_BEHIND:
+ len = p->look_behind.len;
+ fprintf(f, ":%d", len);
+ break;
- case OP_REPEAT:
- case OP_REPEAT_NG:
- {
- mem = *((MemNumType* )bp);
- bp += SIZE_MEMNUM;
- addr = *((RelAddrType* )bp);
- bp += SIZE_RELADDR;
- fprintf(f, ":%d:%d", mem, addr);
- }
- break;
+ case OP_LOOK_BEHIND_NOT_START:
+ addr = p->look_behind_not_start.addr;
+ len = p->look_behind_not_start.len;
+ fprintf(f, ":%d:", len);
+ p_rel_addr(f, addr, p, start);
+ break;
- case OP_PUSH_OR_JUMP_EXACT1:
- case OP_PUSH_IF_PEEK_NEXT:
- addr = *((RelAddrType* )bp);
- bp += SIZE_RELADDR;
- fputc(':', f);
- p_rel_addr(f, addr, bp, start);
- p_string(f, 1, bp);
- bp += 1;
- break;
+ case OP_CALL:
+ addr = p->call.addr;
+ fprintf(f, ":{/%d}", addr);
+ break;
- case OP_LOOK_BEHIND:
- GET_LENGTH_INC(len, bp);
- fprintf(f, ":%d", len);
- break;
+ case OP_PUSH_SAVE_VAL:
+ {
+ SaveType type;
- case OP_LOOK_BEHIND_NOT_START:
- GET_RELADDR_INC(addr, bp);
- GET_LENGTH_INC(len, bp);
- fprintf(f, ":%d:", len);
- p_rel_addr(f, addr, bp, start);
- break;
+ type = p->push_save_val.type;
+ mem = p->push_save_val.id;
+ fprintf(f, ":%d:%d", type, mem);
+ }
+ break;
- case OP_PUSH_SAVE_VAL:
- {
- SaveType type;
- GET_SAVE_TYPE_INC(type, bp);
- GET_MEMNUM_INC(mem, bp);
- fprintf(f, ":%d:%d", type, mem);
- }
- break;
+ case OP_UPDATE_VAR:
+ {
+ UpdateVarType type;
- case OP_UPDATE_VAR:
- {
- UpdateVarType type;
- GET_UPDATE_VAR_TYPE_INC(type, bp);
- GET_MEMNUM_INC(mem, bp);
- fprintf(f, ":%d:%d", type, mem);
- }
- break;
+ type = p->update_var.type;
+ mem = p->update_var.id;
+ fprintf(f, ":%d:%d", type, mem);
+ }
+ break;
#ifdef USE_CALLOUT
- case OP_CALLOUT_CONTENTS:
- {
- GET_MEMNUM_INC(mem, bp); /* number */
- fprintf(f, ":%d", mem);
- }
- break;
-
- case OP_CALLOUT_NAME:
- {
- int id;
+ case OP_CALLOUT_CONTENTS:
+ mem = p->callout_contents.num;
+ fprintf(f, ":%d", mem);
+ break;
- GET_MEMNUM_INC(id, bp); /* id */
- GET_MEMNUM_INC(mem, bp); /* number */
+ case OP_CALLOUT_NAME:
+ {
+ int id;
- fprintf(f, ":%d:%d", id, mem);
- }
- break;
+ id = p->callout_name.id;
+ mem = p->callout_name.num;
+ fprintf(f, ":%d:%d", id, mem);
+ }
+ break;
#endif
- default:
- fprintf(stderr, "onig_print_compiled_byte_code: undefined code %d\n", *--bp);
- }
+ case OP_FINISH:
+ case OP_END:
+ case OP_ANYCHAR:
+ case OP_ANYCHAR_ML:
+ case OP_ANYCHAR_STAR:
+ case OP_ANYCHAR_ML_STAR:
+ case OP_WORD:
+ case OP_WORD_ASCII:
+ case OP_NO_WORD:
+ case OP_NO_WORD_ASCII:
+ case OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
+ case OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
+ case OP_BEGIN_BUF:
+ case OP_END_BUF:
+ case OP_BEGIN_LINE:
+ case OP_END_LINE:
+ case OP_SEMI_END_BUF:
+ case OP_BEGIN_POSITION:
+ case OP_BACKREF1:
+ case OP_BACKREF2:
+ case OP_FAIL:
+ case OP_POP_OUT:
+ case OP_PREC_READ_START:
+ case OP_PREC_READ_END:
+ case OP_PREC_READ_NOT_END:
+ case OP_ATOMIC_START:
+ case OP_ATOMIC_END:
+ case OP_LOOK_BEHIND_NOT_END:
+ case OP_RETURN:
+ break;
+
+ default:
+ fprintf(stderr, "onig_print_compiled_byte_code: undefined code %d\n", p->opcode);
+ break;
}
- if (nextp) *nextp = bp;
}
#endif /* ONIG_DEBUG */
extern void
onig_print_compiled_byte_code_list(FILE* f, regex_t* reg)
{
- UChar* bp;
- UChar* start = reg->p;
- UChar* end = reg->p + reg->used;
+ Operation* bp;
+ Operation* start = reg->ops;
+ Operation* end = reg->ops + reg->ops_used;
fprintf(f, "bt_mem_start: 0x%x, bt_mem_end: 0x%x\n",
reg->bt_mem_start, reg->bt_mem_end);
- fprintf(f, "code-length: %d\n", reg->used);
+ fprintf(f, "code-length: %d\n", reg->ops_used);
bp = start;
while (bp < end) {
int pos = bp - start;
fprintf(f, "%4d: ", pos);
- onig_print_compiled_byte_code(f, bp, &bp, start, reg->enc);
+ onig_print_compiled_byte_code(f, bp, start, reg->enc);
fprintf(f, "\n");
+ bp++;
}
fprintf(f, "\n");
}
int zid;
union {
struct {
- UChar *pcode; /* byte code position */
- UChar *pstr; /* string position */
- UChar *pstr_prev; /* previous char position of pstr */
+ Operation* pcode; /* byte code position */
+ UChar* pstr; /* string position */
+ UChar* pstr_prev; /* previous char position of pstr */
} state;
struct {
- int count; /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
- UChar *pcode; /* byte code position (head of repeated target) */
+ int count; /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
+ Operation* pcode; /* byte code position (head of repeated target) */
} repeat;
struct {
StackIndex si; /* index of stack */
} empty_check;
#ifdef USE_CALL
struct {
- UChar *ret_addr; /* byte code position */
- UChar *pstr; /* string position */
+ Operation *ret_addr; /* byte code position */
+ UChar *pstr; /* string position */
} call_frame;
#endif
struct {
#define STACK_PUSH_ALT(pat,s,sprev) STACK_PUSH(STK_ALT,pat,s,sprev)
#define STACK_PUSH_SUPER_ALT(pat,s,sprev) STACK_PUSH(STK_SUPER_ALT,pat,s,sprev)
#define STACK_PUSH_POS(s,sprev) \
- STACK_PUSH(STK_TO_VOID_START,NULL_UCHARP,s,sprev)
+ STACK_PUSH(STK_TO_VOID_START,(Operation* )0,s,sprev)
#define STACK_PUSH_ALT_PREC_READ_NOT(pat,s,sprev) \
STACK_PUSH(STK_ALT_PREC_READ_NOT,pat,s,sprev)
#define STACK_PUSH_TO_VOID_START STACK_PUSH_TYPE(STK_TO_VOID_START)
#endif
#ifdef USE_BACKREF_WITH_LEVEL
-static int mem_is_in_memp(int mem, int num, UChar* memp)
+static int mem_is_in_memp(int mem, int num, MemNumType* memp)
{
int i;
- MemNumType m;
for (i = 0; i < num; i++) {
- GET_MEMNUM_INC(m, memp);
- if (mem == (int )m) return 1;
+ if (mem == (int )memp[i]) return 1;
}
return 0;
}
backref_match_at_nested_level(regex_t* reg,
StackType* top, StackType* stk_base,
int ignore_case, int case_fold_flag,
- int nest, int mem_num, UChar* memp,
+ int nest, int mem_num, MemNumType* memp,
UChar** s, const UChar* send)
{
UChar *ss, *p, *pstart, *pend = NULL_UCHARP;
static int
backref_check_at_nested_level(regex_t* reg,
StackType* top, StackType* stk_base,
- int nest, int mem_num, UChar* memp)
+ int nest, int mem_num, MemNumType* memp)
{
int level;
StackType* k;
#ifdef USE_THREADED_CODE
-#define BYTECODE_INTERPRETER_START JUMP_OP;
+#define BYTECODE_INTERPRETER_START GOTO_OP;
#define BYTECODE_INTERPRETER_END
#define CASE_OP(x) L_##x: SOP_IN(OP_##x); sbegin = s; MATCH_DEBUG_OUT(1)
#define DEFAULT_OP /* L_DEFAULT: */
#define NEXT_OP sprev = sbegin; JUMP_OP
-#define JUMP_OP goto *opcode_to_label[*p++]
+#define JUMP_OP GOTO_OP
+#define GOTO_OP goto *opcode_to_label[p->opcode]
#define BREAK_OP /* Nothing */
#else
#define CASE_OP(x) case OP_##x: SOP_IN(OP_##x);
#define DEFAULT_OP default:
#define NEXT_OP break
-#define JUMP_OP continue; break
+#define JUMP_OP GOTO_OP
+#define GOTO_OP continue; break
#define BREAK_OP break
#endif /* USE_THREADED_CODE */
+#define INC_OP p++
#define NEXT_OUT SOP_OUT; NEXT_OP
#define JUMP_OUT SOP_OUT; JUMP_OP
#define BREAK_OUT SOP_OUT; BREAK_OP
fprintf(stderr, "----: ");\
else\
fprintf(stderr, "%4d: ", (int )(xp - reg->p));\
- onig_print_compiled_byte_code(stderr, xp, NULL, reg->p, encode);\
+ onig_print_compiled_byte_code(stderr, xp, reg->p, encode);\
fprintf(stderr, "\n");\
} while(0);
#else
const UChar* in_right_range, const UChar* sstart, UChar* sprev,
MatchArg* msa)
{
- static UChar FinishCode[] = { OP_FINISH };
+ static Operation FinishCode[] = { { OP_FINISH } };
#ifdef USE_THREADED_CODE
static const void *opcode_to_label[] = {
LengthType tlen, tlen2;
MemNumType mem;
RelAddrType addr;
- UChar *s, *q, *sbegin;
+ UChar *s, *q, *ps, *sbegin;
UChar *right_range;
int is_alloca;
char *alloc_base;
int of;
#endif
- UChar *p = reg->p;
+ Operation* p = reg->ops;
OnigOptionType option = reg->options;
OnigEncoding encode = reg->enc;
OnigCaseFoldType case_fold_flag = reg->case_fold_flag;
CASE_OP(EXACT1)
DATA_ENSURE(1);
- if (*p != *s) goto fail;
- p++; s++;
+ ps = p->exact.s;
+ if (*ps != *s) goto fail;
+ s++;
+ INC_OP;
NEXT_OUT;
CASE_OP(EXACT1_IC)
&s, end, lowbuf);
DATA_ENSURE(0);
q = lowbuf;
+ ps = p->exact.s;
while (len-- > 0) {
- if (*p != *q) {
- goto fail;
- }
- p++; q++;
+ if (*ps != *q) goto fail;
+ ps++; q++;
}
}
+ INC_OP;
NEXT_OUT;
CASE_OP(EXACT2)
DATA_ENSURE(2);
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
+ ps = p->exact.s;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
sprev = s;
- p++; s++;
+ s++;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACT3)
DATA_ENSURE(3);
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
+ ps = p->exact.s;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
sprev = s;
- p++; s++;
+ s++;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACT4)
DATA_ENSURE(4);
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
+ ps = p->exact.s;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
sprev = s;
- p++; s++;
+ s++;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACT5)
DATA_ENSURE(5);
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
+ ps = p->exact.s;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
sprev = s;
- p++; s++;
+ s++;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACTN)
- GET_LENGTH_INC(tlen, p);
+ tlen = p->exact_n.n;
DATA_ENSURE(tlen);
+ ps = p->exact_n.s;
while (tlen-- > 0) {
- if (*p++ != *s++) goto fail;
+ if (*ps++ != *s++) goto fail;
}
sprev = s - 1;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACTN_IC)
int len;
UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
- GET_LENGTH_INC(tlen, p);
- endp = p + tlen;
-
- while (p < endp) {
+ tlen = p->exact_n.n;
+ ps = p->exact_n.s;
+ endp = ps + tlen;
+ while (ps < endp) {
sprev = s;
DATA_ENSURE(1);
len = ONIGENC_MBC_CASE_FOLD(encode,
DATA_ENSURE(0);
q = lowbuf;
while (len-- > 0) {
- if (*p != *q) goto fail;
- p++; q++;
+ if (*ps != *q) goto fail;
+ ps++; q++;
}
}
}
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACTMB2N1)
DATA_ENSURE(2);
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
+ ps = p->exact.s;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ s++;
+ INC_OP;
NEXT_OUT;
CASE_OP(EXACTMB2N2)
DATA_ENSURE(4);
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
+ ps = p->exact.s;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
sprev = s;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ s++;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACTMB2N3)
DATA_ENSURE(6);
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
+ ps = p->exact.s;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
sprev = s;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACTMB2N)
- GET_LENGTH_INC(tlen, p);
+ tlen = p->exact_n.n;
DATA_ENSURE(tlen * 2);
+ ps = p->exact_n.s;
while (tlen-- > 0) {
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
}
sprev = s - 2;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACTMB3N)
- GET_LENGTH_INC(tlen, p);
+ tlen = p->exact_n.n;
DATA_ENSURE(tlen * 3);
+ ps = p->exact_n.s;
while (tlen-- > 0) {
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
- if (*p != *s) goto fail;
- p++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
}
sprev = s - 3;
+ INC_OP;
JUMP_OUT;
CASE_OP(EXACTMBN)
- GET_LENGTH_INC(tlen, p); /* mb-len */
- GET_LENGTH_INC(tlen2, p); /* string len */
+ tlen = p->exact_len_n.len; /* mb byte len */
+ tlen2 = p->exact_len_n.n; /* number of chars */
tlen2 *= tlen;
DATA_ENSURE(tlen2);
+ ps = p->exact_len_n.s;
while (tlen2-- > 0) {
- if (*p != *s) goto fail;
- p++; s++;
+ if (*ps != *s) goto fail;
+ ps++; s++;
}
sprev = s - tlen;
+ INC_OP;
JUMP_OUT;
CASE_OP(CCLASS)
DATA_ENSURE(1);
- if (BITSET_AT(((BitSetRef )p), *s) == 0) goto fail;
- p += SIZE_BITSET;
+ if (BITSET_AT(p->cclass.bs, *s) == 0) goto fail;
s += enclen(encode, s); /* OP_CCLASS can match mb-code. \D, \S */
+ INC_OP;
NEXT_OUT;
CASE_OP(CCLASS_MB)
if (! ONIGENC_IS_MBC_HEAD(encode, s)) goto fail;
cclass_mb:
- GET_LENGTH_INC(tlen, p);
{
OnigCodePoint code;
UChar *ss;
ss = s;
s += mb_len;
code = ONIGENC_MBC_TO_CODE(encode, ss, s);
-
-#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
- if (! onig_is_in_code_range(p, code)) goto fail;
-#else
- q = p;
- ALIGNMENT_RIGHT(q);
- if (! onig_is_in_code_range(q, code)) goto fail;
-#endif
+ if (! onig_is_in_code_range(p->cclass_mb.mb, code)) goto fail;
}
- p += tlen;
+ INC_OP;
NEXT_OUT;
CASE_OP(CCLASS_MIX)
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_HEAD(encode, s)) {
- p += SIZE_BITSET;
goto cclass_mb;
}
else {
- if (BITSET_AT(((BitSetRef )p), *s) == 0)
+ if (BITSET_AT(p->cclass_mix.bs, *s) == 0)
goto fail;
- p += SIZE_BITSET;
- GET_LENGTH_INC(tlen, p);
- p += tlen;
s++;
}
+ INC_OP;
NEXT_OUT;
CASE_OP(CCLASS_NOT)
DATA_ENSURE(1);
- if (BITSET_AT(((BitSetRef )p), *s) != 0) goto fail;
- p += SIZE_BITSET;
+ if (BITSET_AT(p->cclass.bs, *s) != 0) goto fail;
s += enclen(encode, s);
+ INC_OP;
NEXT_OUT;
CASE_OP(CCLASS_MB_NOT)
DATA_ENSURE(1);
if (! ONIGENC_IS_MBC_HEAD(encode, s)) {
s++;
- GET_LENGTH_INC(tlen, p);
- p += tlen;
goto cc_mb_not_success;
}
cclass_mb_not:
- GET_LENGTH_INC(tlen, p);
{
OnigCodePoint code;
UChar *ss;
if (! DATA_ENSURE_CHECK(mb_len)) {
DATA_ENSURE(1);
s = (UChar* )end;
- p += tlen;
goto cc_mb_not_success;
}
ss = s;
s += mb_len;
code = ONIGENC_MBC_TO_CODE(encode, ss, s);
-
-#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
- if (onig_is_in_code_range(p, code)) goto fail;
-#else
- q = p;
- ALIGNMENT_RIGHT(q);
- if (onig_is_in_code_range(q, code)) goto fail;
-#endif
+ if (onig_is_in_code_range(p->cclass_mb.mb, code)) goto fail;
}
- p += tlen;
cc_mb_not_success:
+ INC_OP;
NEXT_OUT;
CASE_OP(CCLASS_MIX_NOT)
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_HEAD(encode, s)) {
- p += SIZE_BITSET;
goto cclass_mb_not;
}
else {
- if (BITSET_AT(((BitSetRef )p), *s) != 0)
+ if (BITSET_AT(p->cclass_mix.bs, *s) != 0)
goto fail;
- p += SIZE_BITSET;
- GET_LENGTH_INC(tlen, p);
- p += tlen;
s++;
}
+ INC_OP;
NEXT_OUT;
#ifdef USE_OP_CCLASS_NODE
code = ONIGENC_MBC_TO_CODE(encode, ss, s);
if (onig_is_code_in_cc_len(mb_len, code, node) == 0) goto fail;
}
+ INC_OP;
NEXT_OUT;
#endif
DATA_ENSURE(n);
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
s += n;
+ INC_OP;
NEXT_OUT;
CASE_OP(ANYCHAR_ML)
n = enclen(encode, s);
DATA_ENSURE(n);
s += n;
+ INC_OP;
NEXT_OUT;
CASE_OP(ANYCHAR_STAR)
+ INC_OP;
while (DATA_ENSURE_CHECK1) {
STACK_PUSH_ALT(p, s, sprev);
n = enclen(encode, s);
JUMP_OUT;
CASE_OP(ANYCHAR_ML_STAR)
+ INC_OP;
while (DATA_ENSURE_CHECK1) {
STACK_PUSH_ALT(p, s, sprev);
n = enclen(encode, s);
JUMP_OUT;
CASE_OP(ANYCHAR_STAR_PEEK_NEXT)
- while (DATA_ENSURE_CHECK1) {
- if (*p == *s) {
- STACK_PUSH_ALT(p + 1, s, sprev);
- }
- n = enclen(encode, s);
- DATA_ENSURE(n);
- if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
- sprev = s;
- s += n;
- }
- p++;
- NEXT_OUT;
+ {
+ UChar c;
- CASE_OP(ANYCHAR_ML_STAR_PEEK_NEXT)
- while (DATA_ENSURE_CHECK1) {
- if (*p == *s) {
- STACK_PUSH_ALT(p + 1, s, sprev);
- }
- n = enclen(encode, s);
- if (n > 1) {
+ c = p->anychar_star_peek_next.c;
+ INC_OP;
+ while (DATA_ENSURE_CHECK1) {
+ if (c == *s) {
+ STACK_PUSH_ALT(p, s, sprev);
+ }
+ n = enclen(encode, s);
DATA_ENSURE(n);
+ if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
sprev = s;
s += n;
}
- else {
- sprev = s;
- s++;
+ }
+ NEXT_OUT;
+
+ CASE_OP(ANYCHAR_ML_STAR_PEEK_NEXT)
+ {
+ UChar c;
+
+ c = p->anychar_star_peek_next.c;
+ INC_OP;
+ while (DATA_ENSURE_CHECK1) {
+ if (c == *s) {
+ STACK_PUSH_ALT(p, s, sprev);
+ }
+ n = enclen(encode, s);
+ if (n > 1) {
+ DATA_ENSURE(n);
+ sprev = s;
+ s += n;
+ }
+ else {
+ sprev = s;
+ s++;
+ }
}
}
- p++;
NEXT_OUT;
CASE_OP(WORD)
goto fail;
s += enclen(encode, s);
+ INC_OP;
NEXT_OUT;
CASE_OP(WORD_ASCII)
goto fail;
s += enclen(encode, s);
+ INC_OP;
NEXT_OUT;
CASE_OP(NO_WORD)
goto fail;
s += enclen(encode, s);
+ INC_OP;
NEXT_OUT;
CASE_OP(NO_WORD_ASCII)
goto fail;
s += enclen(encode, s);
+ INC_OP;
NEXT_OUT;
CASE_OP(WORD_BOUNDARY)
{
ModeType mode;
- GET_MODE_INC(mode, p); /* ascii_mode */
+ mode = p->word_boundary.mode;
if (ON_STR_BEGIN(s)) {
DATA_ENSURE(1);
if (! IS_MBC_WORD_ASCII_MODE(encode, s, end, mode))
goto fail;
}
}
+ INC_OP;
JUMP_OUT;
CASE_OP(NO_WORD_BOUNDARY)
{
ModeType mode;
- GET_MODE_INC(mode, p); /* ascii_mode */
+ mode = p->word_boundary.mode;
if (ON_STR_BEGIN(s)) {
if (DATA_ENSURE_CHECK1 && IS_MBC_WORD_ASCII_MODE(encode, s, end, mode))
goto fail;
goto fail;
}
}
+ INC_OP;
JUMP_OUT;
#ifdef USE_WORD_BEGIN_END
CASE_OP(WORD_BEGIN)
{
ModeType mode;
- GET_MODE_INC(mode, p); /* ascii_mode */
+ mode = p->word_boundary.mode;
if (DATA_ENSURE_CHECK1 && IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)) {
if (ON_STR_BEGIN(s) || !IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode)) {
+ INC_OP;
JUMP_OUT;
}
}
CASE_OP(WORD_END)
{
ModeType mode;
- GET_MODE_INC(mode, p); /* ascii_mode */
+ mode = p->word_boundary.mode;
if (!ON_STR_BEGIN(s) && IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode)) {
if (ON_STR_END(s) || ! IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)) {
+ INC_OP;
JUMP_OUT;
}
}
CASE_OP(EXTENDED_GRAPHEME_CLUSTER_BOUNDARY)
if (onigenc_egcb_is_break_position(encode, s, sprev, str, end)) {
+ INC_OP;
JUMP_OUT;
}
goto fail;
if (onigenc_egcb_is_break_position(encode, s, sprev, str, end))
goto fail;
+ INC_OP;
JUMP_OUT;
CASE_OP(BEGIN_BUF)
if (! ON_STR_BEGIN(s)) goto fail;
+ INC_OP;
JUMP_OUT;
CASE_OP(END_BUF)
if (! ON_STR_END(s)) goto fail;
+ INC_OP;
JUMP_OUT;
CASE_OP(BEGIN_LINE)
if (ON_STR_BEGIN(s)) {
if (IS_NOTBOL(msa->options)) goto fail;
+ INC_OP;
JUMP_OUT;
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end) && !ON_STR_END(s)) {
+ INC_OP;
JUMP_OUT;
}
goto fail;
if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {
#endif
if (IS_NOTEOL(msa->options)) goto fail;
+ INC_OP;
JUMP_OUT;
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
}
#endif
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) {
+ INC_OP;
JUMP_OUT;
}
#ifdef USE_CRNL_AS_LINE_TERMINATOR
else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {
+ INC_OP;
JUMP_OUT;
}
#endif
if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {
#endif
if (IS_NOTEOL(msa->options)) goto fail;
+ INC_OP;
JUMP_OUT;
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
}
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end) &&
ON_STR_END(s + enclen(encode, s))) {
+ INC_OP;
JUMP_OUT;
}
#ifdef USE_CRNL_AS_LINE_TERMINATOR
UChar* ss = s + enclen(encode, s);
ss += enclen(encode, ss);
if (ON_STR_END(ss)) {
+ INC_OP;
JUMP_OUT;
}
}
if (s != msa->start)
goto fail;
+ INC_OP;
JUMP_OUT;
CASE_OP(MEMORY_START_PUSH)
- GET_MEMNUM_INC(mem, p);
+ mem = p->memory_start.num;
STACK_PUSH_MEM_START(mem, s);
+ INC_OP;
JUMP_OUT;
CASE_OP(MEMORY_START)
- GET_MEMNUM_INC(mem, p);
+ mem = p->memory_start.num;
mem_start_stk[mem] = (StackIndex )((void* )s);
+ INC_OP;
JUMP_OUT;
CASE_OP(MEMORY_END_PUSH)
- GET_MEMNUM_INC(mem, p);
+ mem = p->memory_end.num;
STACK_PUSH_MEM_END(mem, s);
+ INC_OP;
JUMP_OUT;
CASE_OP(MEMORY_END)
- GET_MEMNUM_INC(mem, p);
+ mem = p->memory_end.num;
mem_end_stk[mem] = (StackIndex )((void* )s);
+ INC_OP;
JUMP_OUT;
#ifdef USE_CALL
CASE_OP(MEMORY_END_PUSH_REC)
- GET_MEMNUM_INC(mem, p);
+ mem = p->memory_end.num;
STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */
STACK_PUSH_MEM_END(mem, s);
mem_start_stk[mem] = GET_STACK_INDEX(stkp);
+ INC_OP;
JUMP_OUT;
CASE_OP(MEMORY_END_REC)
- GET_MEMNUM_INC(mem, p);
+ mem = p->memory_end.num;
mem_end_stk[mem] = (StackIndex )((void* )s);
STACK_GET_MEM_START(mem, stkp);
mem_start_stk[mem] = (StackIndex )((void* )stkp->u.mem.pstr);
STACK_PUSH_MEM_END_MARK(mem);
+ INC_OP;
JUMP_OUT;
#endif
goto backref;
CASE_OP(BACKREF_N)
- GET_MEMNUM_INC(mem, p);
+ mem = p->backref_n.n1;
backref:
{
int len;
while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
}
+ INC_OP;
JUMP_OUT;
CASE_OP(BACKREF_N_IC)
- GET_MEMNUM_INC(mem, p);
+ mem = p->backref_n.n1;
{
int len;
UChar *pstart, *pend;
while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
}
+ INC_OP;
JUMP_OUT;
CASE_OP(BACKREF_MULTI)
int len, is_fail;
UChar *pstart, *pend, *swork;
- GET_LENGTH_INC(tlen, p);
+ tlen = p->backref_general.num;
for (i = 0; i < tlen; i++) {
- GET_MEMNUM_INC(mem, p);
+ mem = tlen == 1 ? p->backref_general.n1 : p->backref_general.ns[i];
if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;
if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
- p += (SIZE_MEMNUM * (tlen - i - 1));
break; /* success */
}
if (i == tlen) goto fail;
}
+ INC_OP;
JUMP_OUT;
CASE_OP(BACKREF_MULTI_IC)
int len, is_fail;
UChar *pstart, *pend, *swork;
- GET_LENGTH_INC(tlen, p);
+ tlen = p->backref_general.num;
for (i = 0; i < tlen; i++) {
- GET_MEMNUM_INC(mem, p);
+ mem = tlen == 1 ? p->backref_general.n1 : p->backref_general.ns[i];
if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;
if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
- p += (SIZE_MEMNUM * (tlen - i - 1));
break; /* success */
}
if (i == tlen) goto fail;
}
+ INC_OP;
JUMP_OUT;
#ifdef USE_BACKREF_WITH_LEVEL
{
int len;
OnigOptionType ic;
- LengthType level;
+ int level;
+ MemNumType* mems;
- GET_OPTION_INC(ic, p);
- GET_LENGTH_INC(level, p);
- GET_LENGTH_INC(tlen, p);
+ ic = p->backref_general.options;
+ level = p->backref_general.nest_level;
+ tlen = p->backref_general.num;
+ mems = tlen == 1 ? &(p->backref_general.n1) : p->backref_general.ns;
sprev = s;
if (backref_match_at_nested_level(reg, stk, stk_base, ic
- , case_fold_flag, (int )level, (int )tlen, p, &s, end)) {
+ , case_fold_flag, level, (int )tlen, mems, &s, end)) {
if (sprev < end) {
while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
}
- p += (SIZE_MEMNUM * tlen);
}
else
goto fail;
}
+ INC_OP;
JUMP_OUT;
#endif
CASE_OP(BACKREF_CHECK)
{
- GET_LENGTH_INC(tlen, p);
- for (i = 0; i < tlen; i++) {
- GET_MEMNUM_INC(mem, p);
+ MemNumType* mems;
+
+ tlen = p->backref_general.num;
+ mems = tlen == 1 ? &(p->backref_general.n1) : p->backref_general.ns;
+ for (i = 0; i < tlen; i++) {
+ mem = mems[i];
if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;
if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
-
- p += (SIZE_MEMNUM * (tlen - i - 1));
break; /* success */
}
if (i == tlen) goto fail;
}
+ INC_OP;
JUMP_OUT;
#ifdef USE_BACKREF_WITH_LEVEL
CASE_OP(BACKREF_CHECK_WITH_LEVEL)
{
LengthType level;
+ MemNumType* mems;
- GET_LENGTH_INC(level, p);
- GET_LENGTH_INC(tlen, p);
+ level = p->backref_general.nest_level;
+ tlen = p->backref_general.num;
+ mems = tlen == 1 ? &(p->backref_general.n1) : p->backref_general.ns;
if (backref_check_at_nested_level(reg, stk, stk_base,
- (int )level, (int )tlen, p) != 0) {
- p += (SIZE_MEMNUM * tlen);
+ (int )level, (int )tlen, mems) != 0) {
}
else
goto fail;
}
+ INC_OP;
JUMP_OUT;
#endif
CASE_OP(EMPTY_CHECK_START)
- GET_MEMNUM_INC(mem, p); /* mem: null check id */
+ mem = p->empty_check_start.mem; /* mem: null check id */
STACK_PUSH_EMPTY_CHECK_START(mem, s);
+ INC_OP;
JUMP_OUT;
CASE_OP(EMPTY_CHECK_END)
{
int is_empty;
- GET_MEMNUM_INC(mem, p); /* mem: null check id */
+ mem = p->empty_check_end.mem; /* mem: null check id */
STACK_EMPTY_CHECK(is_empty, mem, s);
+ INC_OP;
if (is_empty) {
#ifdef ONIG_DEBUG_MATCH
fprintf(stderr, "EMPTY_CHECK_END: skip id:%d, s:%p\n", (int )mem, s);
#endif
empty_check_found:
/* empty loop founded, skip next instruction */
- switch (*p++) {
+ switch (p->opcode) {
case OP_JUMP:
case OP_PUSH:
- p += SIZE_RELADDR;
- break;
case OP_REPEAT_INC:
case OP_REPEAT_INC_NG:
case OP_REPEAT_INC_SG:
case OP_REPEAT_INC_NG_SG:
- p += SIZE_MEMNUM;
+ INC_OP;
break;
default:
goto unexpected_bytecode_error;
{
int is_empty;
- GET_MEMNUM_INC(mem, p); /* mem: null check id */
+ mem = p->empty_check_end.mem; /* mem: null check id */
STACK_EMPTY_CHECK_MEM(is_empty, mem, s, reg);
+ INC_OP;
if (is_empty) {
#ifdef ONIG_DEBUG_MATCH
fprintf(stderr, "EMPTY_CHECK_END_MEM: skip id:%d, s:%p\n", (int)mem, s);
{
int is_empty;
- GET_MEMNUM_INC(mem, p); /* mem: null check id */
+ mem = p->empty_check_end.mem; /* mem: null check id */
#ifdef USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT
STACK_EMPTY_CHECK_MEM_REC(is_empty, mem, s, reg);
#else
STACK_EMPTY_CHECK_REC(is_empty, mem, s);
#endif
+ INC_OP;
if (is_empty) {
#ifdef ONIG_DEBUG_MATCH
fprintf(stderr, "EMPTY_CHECK_END_MEM_PUSH: skip id:%d, s:%p\n",
#endif
CASE_OP(JUMP)
- GET_RELADDR_INC(addr, p);
+ addr = p->jump.addr;
p += addr;
CHECK_INTERRUPT_JUMP_OUT;
CASE_OP(PUSH)
- GET_RELADDR_INC(addr, p);
+ addr = p->push.addr;
STACK_PUSH_ALT(p + addr, s, sprev);
+ INC_OP;
JUMP_OUT;
CASE_OP(PUSH_SUPER)
- GET_RELADDR_INC(addr, p);
+ addr = p->push.addr;
STACK_PUSH_SUPER_ALT(p + addr, s, sprev);
+ INC_OP;
JUMP_OUT;
CASE_OP(POP_OUT)
STACK_POP_ONE;
/* for stop backtrack */
/* CHECK_RETRY_LIMIT_IN_MATCH; */
+ INC_OP;
JUMP_OUT;
CASE_OP(PUSH_OR_JUMP_EXACT1)
- GET_RELADDR_INC(addr, p);
- if (*p == *s && DATA_ENSURE_CHECK1) {
- p++;
- STACK_PUSH_ALT(p + addr, s, sprev);
- JUMP_OUT;
+ {
+ UChar c;
+
+ addr = p->push_or_jump_exact1.addr;
+ c = p->push_or_jump_exact1.c;
+ if (DATA_ENSURE_CHECK1 && c == *s) {
+ STACK_PUSH_ALT(p + addr, s, sprev);
+ INC_OP;
+ JUMP_OUT;
+ }
}
- p += (addr + 1);
+ p += addr;
JUMP_OUT;
CASE_OP(PUSH_IF_PEEK_NEXT)
- GET_RELADDR_INC(addr, p);
- if (*p == *s) {
- p++;
- STACK_PUSH_ALT(p + addr, s, sprev);
- JUMP_OUT;
+ {
+ UChar c;
+
+ addr = p->push_if_peek_next.addr;
+ c = p->push_if_peek_next.c;
+ if (c == *s) {
+ STACK_PUSH_ALT(p + addr, s, sprev);
+ INC_OP;
+ JUMP_OUT;
+ }
}
- p++;
+ INC_OP;
JUMP_OUT;
CASE_OP(REPEAT)
- {
- GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
- GET_RELADDR_INC(addr, p);
+ mem = p->repeat.id; /* mem: OP_REPEAT ID */
+ addr = p->repeat.addr;
- STACK_ENSURE(1);
- repeat_stk[mem] = GET_STACK_INDEX(stk);
- STACK_PUSH_REPEAT(mem, p);
+ STACK_ENSURE(1);
+ repeat_stk[mem] = GET_STACK_INDEX(stk);
+ STACK_PUSH_REPEAT(mem, p + 1);
- if (reg->repeat_range[mem].lower == 0) {
- STACK_PUSH_ALT(p + addr, s, sprev);
- }
+ if (reg->repeat_range[mem].lower == 0) {
+ STACK_PUSH_ALT(p + addr, s, sprev);
}
+ INC_OP;
JUMP_OUT;
CASE_OP(REPEAT_NG)
- {
- GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
- GET_RELADDR_INC(addr, p);
+ mem = p->repeat.id; /* mem: OP_REPEAT ID */
+ addr = p->repeat.addr;
- STACK_ENSURE(1);
- repeat_stk[mem] = GET_STACK_INDEX(stk);
- STACK_PUSH_REPEAT(mem, p);
+ STACK_ENSURE(1);
+ repeat_stk[mem] = GET_STACK_INDEX(stk);
+ STACK_PUSH_REPEAT(mem, p + 1);
- if (reg->repeat_range[mem].lower == 0) {
- STACK_PUSH_ALT(p, s, sprev);
- p += addr;
- }
+ if (reg->repeat_range[mem].lower == 0) {
+ STACK_PUSH_ALT(p + 1, s, sprev);
+ p += addr;
}
+ else
+ INC_OP;
JUMP_OUT;
CASE_OP(REPEAT_INC)
- GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
- si = repeat_stk[mem];
+ mem = p->repeat_inc.id; /* mem: OP_REPEAT ID */
+ si = repeat_stk[mem];
stkp = STACK_AT(si);
repeat_inc:
stkp->u.repeat.count++;
if (stkp->u.repeat.count >= reg->repeat_range[mem].upper) {
/* end of repeat. Nothing to do. */
+ INC_OP;
}
else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
STACK_PUSH_ALT(p, s, sprev);
CHECK_INTERRUPT_JUMP_OUT;
CASE_OP(REPEAT_INC_SG)
- GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
+ mem = p->repeat_inc.id; /* mem: OP_REPEAT ID */
STACK_GET_REPEAT(mem, stkp);
si = GET_STACK_INDEX(stkp);
goto repeat_inc;
CASE_OP(REPEAT_INC_NG)
- GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
+ mem = p->repeat_inc.id; /* mem: OP_REPEAT ID */
si = repeat_stk[mem];
stkp = STACK_AT(si);
stkp->u.repeat.count++;
if (stkp->u.repeat.count < reg->repeat_range[mem].upper) {
if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
- UChar* pcode = stkp->u.repeat.pcode;
+ Operation* pcode = stkp->u.repeat.pcode;
STACK_PUSH_REPEAT_INC(si);
STACK_PUSH_ALT(pcode, s, sprev);
+ INC_OP;
}
else {
p = stkp->u.repeat.pcode;
}
else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {
STACK_PUSH_REPEAT_INC(si);
+ INC_OP;
}
CHECK_INTERRUPT_JUMP_OUT;
CASE_OP(REPEAT_INC_NG_SG)
- GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
+ mem = p->repeat_inc.id; /* mem: OP_REPEAT ID */
STACK_GET_REPEAT(mem, stkp);
si = GET_STACK_INDEX(stkp);
goto repeat_inc_ng;
CASE_OP(PREC_READ_START)
STACK_PUSH_POS(s, sprev);
+ INC_OP;
JUMP_OUT;
CASE_OP(PREC_READ_END)
- {
- STACK_EXEC_TO_VOID(stkp);
- s = stkp->u.state.pstr;
- sprev = stkp->u.state.pstr_prev;
- }
+ STACK_EXEC_TO_VOID(stkp);
+ s = stkp->u.state.pstr;
+ sprev = stkp->u.state.pstr_prev;
+ INC_OP;
JUMP_OUT;
CASE_OP(PREC_READ_NOT_START)
- GET_RELADDR_INC(addr, p);
+ addr = p->prec_read_not_start.addr;
STACK_PUSH_ALT_PREC_READ_NOT(p + addr, s, sprev);
+ INC_OP;
JUMP_OUT;
CASE_OP(PREC_READ_NOT_END)
CASE_OP(ATOMIC_START)
STACK_PUSH_TO_VOID_START;
+ INC_OP;
JUMP_OUT;
CASE_OP(ATOMIC_END)
STACK_EXEC_TO_VOID(stkp);
+ INC_OP;
JUMP_OUT;
CASE_OP(LOOK_BEHIND)
- GET_LENGTH_INC(tlen, p);
+ tlen = p->look_behind.len;
s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);
if (IS_NULL(s)) goto fail;
sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);
+ INC_OP;
JUMP_OUT;
CASE_OP(LOOK_BEHIND_NOT_START)
- GET_RELADDR_INC(addr, p);
- GET_LENGTH_INC(tlen, p);
+ addr = p->look_behind_not_start.addr;
+ tlen = p->look_behind_not_start.len;
q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);
if (IS_NULL(q)) {
/* too short case -> success. ex. /(?<!XXX)a/.match("a")
STACK_PUSH_ALT_LOOK_BEHIND_NOT(p + addr, s, sprev);
s = q;
sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);
+ INC_OP;
}
JUMP_OUT;
CASE_OP(LOOK_BEHIND_NOT_END)
STACK_POP_TIL_ALT_LOOK_BEHIND_NOT;
+ INC_OP;
goto fail;
#ifdef USE_CALL
CASE_OP(CALL)
- GET_ABSADDR_INC(addr, p);
- STACK_PUSH_CALL_FRAME(p);
- p = reg->p + addr;
+ addr = p->call.addr;
+ INC_OP; STACK_PUSH_CALL_FRAME(p);
+ p = reg->ops + addr;
JUMP_OUT;
CASE_OP(RETURN)
CASE_OP(PUSH_SAVE_VAL)
{
SaveType type;
- GET_SAVE_TYPE_INC(type, p);
- GET_MEMNUM_INC(mem, p); /* mem: save id */
+
+ type = p->push_save_val.type;
+ mem = p->push_save_val.id; /* mem: save id */
switch ((enum SaveType )type) {
case SAVE_KEEP:
STACK_PUSH_SAVE_VAL(mem, type, s);
break;
}
}
+ INC_OP;
JUMP_OUT;
CASE_OP(UPDATE_VAR)
UpdateVarType type;
enum SaveType save_type;
- GET_UPDATE_VAR_TYPE_INC(type, p);
- GET_MEMNUM_INC(mem, p); /* mem: save id */
+ type = p->update_var.type;
+ mem = p->update_var.id; /* mem: save id */
+
switch ((enum UpdateVarType )type) {
case UPDATE_VAR_KEEP_FROM_STACK_LAST:
STACK_GET_SAVE_VAL_TYPE_LAST(SAVE_KEEP, keep);
break;
}
}
+ INC_OP;
JUMP_OUT;
#ifdef USE_CALLOUT
CASE_OP(CALLOUT_CONTENTS)
of = ONIG_CALLOUT_OF_CONTENTS;
+ mem = p->callout_contents.num;
goto callout_common_entry;
BREAK_OUT;
{
int call_result;
int name_id;
- int num;
int in;
CalloutListEntry* e;
OnigCalloutFunc func;
OnigCalloutArgs args;
of = ONIG_CALLOUT_OF_NAME;
- GET_MEMNUM_INC(name_id, p);
+ name_id = p->callout_name.id;
+ mem = p->callout_name.num;
callout_common_entry:
- GET_MEMNUM_INC(num, p);
- e = onig_reg_callout_list_at(reg, num);
+ e = onig_reg_callout_list_at(reg, mem);
in = e->in;
if (of == ONIG_CALLOUT_OF_NAME) {
- func = onig_get_callout_start_func(reg, num);
+ func = onig_get_callout_start_func(reg, mem);
}
else {
name_id = ONIG_NON_NAME_ID;
if (IS_NOT_NULL(func) && (in & ONIG_CALLOUT_IN_PROGRESS) != 0) {
CALLOUT_BODY(func, ONIG_CALLOUT_IN_PROGRESS, name_id,
- num, msa->mp->callout_user_data, args, call_result);
+ (int )mem, msa->mp->callout_user_data, args, call_result);
switch (call_result) {
case ONIG_CALLOUT_FAIL:
goto fail;
if ((in & ONIG_CALLOUT_IN_RETRACTION) != 0) {
if (of == ONIG_CALLOUT_OF_NAME) {
if (IS_NOT_NULL(func)) {
- STACK_PUSH_CALLOUT_NAME(name_id, num, func);
+ STACK_PUSH_CALLOUT_NAME(name_id, mem, func);
}
}
else {
func = msa->mp->retraction_callout_of_contents;
if (IS_NOT_NULL(func)) {
- STACK_PUSH_CALLOUT_CONTENTS(num, func);
+ STACK_PUSH_CALLOUT_CONTENTS(mem, func);
}
}
}
}
}
+ INC_OP;
JUMP_OUT;
#endif