1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

regexec.c: fix build with direct threaded VM

* regexec.c (match_at): move direct threaded VM code to get rid of
  mixed declarations and code, and enable it only for gcc since it
  depends on a gcc extension.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53251 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-12-22 17:34:38 +00:00
parent 03cc02c9ab
commit 9fb596815d
2 changed files with 197 additions and 187 deletions

View file

@ -1,3 +1,9 @@
Wed Dec 23 02:34:36 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* regexec.c (match_at): move direct threaded VM code to get rid of
mixed declarations and code, and enable it only for gcc since it
depends on a gcc extension.
Wed Dec 23 02:23:19 2015 Yuki Nishijima <mail@yukinishijima.net>
* gems/bundled_gems: Upgrade the did_you_mean gem to 1.0.0

378
regexec.c
View file

@ -33,7 +33,11 @@
/* #define USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
#ifndef USE_DIRECT_THREADED_VM
#define USE_DIRECT_THREADED_VM 1
# ifdef __GNUC__
# define USE_DIRECT_THREADED_VM 1
# else
# define USE_DIRECT_THREADED_VM 0
# endif
#endif
#ifdef USE_CRNL_AS_LINE_TERMINATOR
@ -1360,6 +1364,192 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
int num_comb_exp_check = reg->num_comb_exp_check;
#endif
#if USE_DIRECT_THREADED_VM
#define VM_LOOP JUMP;
#define VM_LOOP_END
#define CASE(x) L_##x: sbegin = s; OPCODE_EXEC_HOOK;
#define DEFAULT L_DEFAULT:
#define NEXT sprev = sbegin; JUMP
#define JUMP goto *oplabels[*p++]
static void *oplabels[] = {
&&L_OP_FINISH, /* matching process terminator (no more alternative) */
&&L_OP_END, /* pattern code terminator (success end) */
&&L_OP_EXACT1, /* single byte, N = 1 */
&&L_OP_EXACT2, /* single byte, N = 2 */
&&L_OP_EXACT3, /* single byte, N = 3 */
&&L_OP_EXACT4, /* single byte, N = 4 */
&&L_OP_EXACT5, /* single byte, N = 5 */
&&L_OP_EXACTN, /* single byte */
&&L_OP_EXACTMB2N1, /* mb-length = 2 N = 1 */
&&L_OP_EXACTMB2N2, /* mb-length = 2 N = 2 */
&&L_OP_EXACTMB2N3, /* mb-length = 2 N = 3 */
&&L_OP_EXACTMB2N, /* mb-length = 2 */
&&L_OP_EXACTMB3N, /* mb-length = 3 */
&&L_OP_EXACTMBN, /* other length */
&&L_OP_EXACT1_IC, /* single byte, N = 1, ignore case */
&&L_OP_EXACTN_IC, /* single byte, ignore case */
&&L_OP_CCLASS,
&&L_OP_CCLASS_MB,
&&L_OP_CCLASS_MIX,
&&L_OP_CCLASS_NOT,
&&L_OP_CCLASS_MB_NOT,
&&L_OP_CCLASS_MIX_NOT,
&&L_OP_CCLASS_NODE, /* pointer to CClassNode node */
&&L_OP_ANYCHAR, /* "." */
&&L_OP_ANYCHAR_ML, /* "." multi-line */
&&L_OP_ANYCHAR_STAR, /* ".*" */
&&L_OP_ANYCHAR_ML_STAR, /* ".*" multi-line */
&&L_OP_ANYCHAR_STAR_PEEK_NEXT,
&&L_OP_ANYCHAR_ML_STAR_PEEK_NEXT,
&&L_OP_WORD,
&&L_OP_NOT_WORD,
&&L_OP_WORD_BOUND,
&&L_OP_NOT_WORD_BOUND,
#ifdef USE_WORD_BEGIN_END
&&L_OP_WORD_BEGIN,
&&L_OP_WORD_END,
#else
&&L_DEFAULT,
&&L_DEFAULT,
#endif
&&L_OP_ASCII_WORD,
&&L_OP_NOT_ASCII_WORD,
&&L_OP_ASCII_WORD_BOUND,
&&L_OP_NOT_ASCII_WORD_BOUND,
#ifdef USE_WORD_BEGIN_END
&&L_OP_ASCII_WORD_BEGIN,
&&L_OP_ASCII_WORD_END,
#else
&&L_DEFAULT,
&&L_DEFAULT,
#endif
&&L_OP_BEGIN_BUF,
&&L_OP_END_BUF,
&&L_OP_BEGIN_LINE,
&&L_OP_END_LINE,
&&L_OP_SEMI_END_BUF,
&&L_OP_BEGIN_POSITION,
&&L_OP_BEGIN_POS_OR_LINE, /* used for implicit anchor optimization */
&&L_OP_BACKREF1,
&&L_OP_BACKREF2,
&&L_OP_BACKREFN,
&&L_OP_BACKREFN_IC,
&&L_OP_BACKREF_MULTI,
&&L_OP_BACKREF_MULTI_IC,
#ifdef USE_BACKREF_WITH_LEVEL
&&L_OP_BACKREF_WITH_LEVEL, /* \k<xxx+n>, \k<xxx-n> */
#else
&&L_DEFAULT,
#endif
&&L_OP_MEMORY_START,
&&L_OP_MEMORY_START_PUSH, /* push back-tracker to stack */
&&L_OP_MEMORY_END_PUSH, /* push back-tracker to stack */
#ifdef USE_SUBEXP_CALL
&&L_OP_MEMORY_END_PUSH_REC, /* push back-tracker to stack */
#else
&&L_DEFAULT,
#endif
&&L_OP_MEMORY_END,
#ifdef USE_SUBEXP_CALL
&&L_OP_MEMORY_END_REC, /* push marker to stack */
#else
&&L_DEFAULT,
#endif
&&L_OP_KEEP,
&&L_OP_FAIL, /* pop stack and move */
&&L_OP_JUMP,
&&L_OP_PUSH,
&&L_OP_POP,
&&L_OP_PUSH_OR_JUMP_EXACT1, /* if match exact then push, else jump. */
&&L_OP_PUSH_IF_PEEK_NEXT, /* if match exact then push, else none. */
&&L_OP_REPEAT, /* {n,m} */
&&L_OP_REPEAT_NG, /* {n,m}? (non greedy) */
&&L_OP_REPEAT_INC,
&&L_OP_REPEAT_INC_NG, /* non greedy */
&&L_OP_REPEAT_INC_SG, /* search and get in stack */
&&L_OP_REPEAT_INC_NG_SG, /* search and get in stack (non greedy) */
&&L_OP_NULL_CHECK_START, /* null loop checker start */
&&L_OP_NULL_CHECK_END, /* null loop checker end */
#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
&&L_OP_NULL_CHECK_END_MEMST, /* null loop checker end (with capture status) */
#else
&&L_DEFAULT,
#endif
#ifdef USE_SUBEXP_CALL
&&L_OP_NULL_CHECK_END_MEMST_PUSH, /* with capture status and push check-end */
#else
&&L_DEFAULT,
#endif
&&L_OP_PUSH_POS, /* (?=...) start */
&&L_OP_POP_POS, /* (?=...) end */
&&L_OP_PUSH_POS_NOT, /* (?!...) start */
&&L_OP_FAIL_POS, /* (?!...) end */
&&L_OP_PUSH_STOP_BT, /* (?>...) start */
&&L_OP_POP_STOP_BT, /* (?>...) end */
&&L_OP_LOOK_BEHIND, /* (?<=...) start (no needs end opcode) */
&&L_OP_PUSH_LOOK_BEHIND_NOT, /* (?<!...) start */
&&L_OP_FAIL_LOOK_BEHIND_NOT, /* (?<!...) end */
#ifdef USE_SUBEXP_CALL
&&L_OP_CALL, /* \g<name> */
&&L_OP_RETURN,
#else
&&L_DEFAULT,
&&L_DEFAULT,
#endif
&&L_OP_CONDITION,
#ifdef USE_COMBINATION_EXPLOSION_CHECK
&&L_OP_STATE_CHECK_PUSH, /* combination explosion check and push */
&&L_OP_STATE_CHECK_PUSH_OR_JUMP, /* check ok -> push, else jump */
&&L_OP_STATE_CHECK, /* check only */
#else
&&L_DEFAULT,
&&L_DEFAULT,
&&L_DEFAULT,
#endif
#ifdef USE_COMBINATION_EXPLOSION_CHECK
&&L_OP_STATE_CHECK_ANYCHAR_STAR,
&&L_OP_STATE_CHECK_ANYCHAR_ML_STAR,
#else
&&L_DEFAULT,
&&L_DEFAULT,
#endif
/* no need: IS_DYNAMIC_OPTION() == 0 */
#if 0 /* no need: IS_DYNAMIC_OPTION() == 0 */
&&L_OP_SET_OPTION_PUSH, /* set option and push recover option */
&&L_OP_SET_OPTION /* set option */
#else
&&L_DEFAULT,
&&L_DEFAULT
#endif
};
#else
#define VM_LOOP \
while (1) { \
OPCODE_EXEC_HOOK; \
sbegin = s; \
switch (*p++) {
#define VM_LOOP_END } sprev = sbegin; }
#define CASE(x) case x:
#define DEFAULT default:
#define NEXT break
#define JUMP continue; break
#endif
#ifdef USE_SUBEXP_CALL
/* Stack #0 is used to store the pattern itself and used for (?R), \g<0>, etc. */
n = reg->num_repeat + (reg->num_mem + 1) * 2;
@ -1435,192 +1625,6 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
#endif
#if USE_DIRECT_THREADED_VM
#define VM_LOOP JUMP;
#define VM_LOOP_END
#define CASE(x) L_##x: sbegin = s; OPCODE_EXEC_HOOK;
#define DEFAULT L_DEFAULT:
#define NEXT sprev = sbegin; JUMP
#define JUMP goto *oplabels[*p++]
static void *oplabels[] = {
&&L_OP_FINISH , /* matching process terminator (no more alternative) */
&&L_OP_END, /* pattern code terminator (success end) */
&&L_OP_EXACT1, /* single byte, N = 1 */
&&L_OP_EXACT2, /* single byte, N = 2 */
&&L_OP_EXACT3, /* single byte, N = 3 */
&&L_OP_EXACT4, /* single byte, N = 4 */
&&L_OP_EXACT5, /* single byte, N = 5 */
&&L_OP_EXACTN, /* single byte */
&&L_OP_EXACTMB2N1, /* mb-length = 2 N = 1 */
&&L_OP_EXACTMB2N2, /* mb-length = 2 N = 2 */
&&L_OP_EXACTMB2N3, /* mb-length = 2 N = 3 */
&&L_OP_EXACTMB2N, /* mb-length = 2 */
&&L_OP_EXACTMB3N, /* mb-length = 3 */
&&L_OP_EXACTMBN, /* other length */
&&L_OP_EXACT1_IC, /* single byte, N = 1, ignore case */
&&L_OP_EXACTN_IC, /* single byte, ignore case */
&&L_OP_CCLASS,
&&L_OP_CCLASS_MB,
&&L_OP_CCLASS_MIX,
&&L_OP_CCLASS_NOT,
&&L_OP_CCLASS_MB_NOT,
&&L_OP_CCLASS_MIX_NOT,
&&L_OP_CCLASS_NODE, /* pointer to CClassNode node */
&&L_OP_ANYCHAR, /* "." */
&&L_OP_ANYCHAR_ML, /* "." multi-line */
&&L_OP_ANYCHAR_STAR, /* ".*" */
&&L_OP_ANYCHAR_ML_STAR, /* ".*" multi-line */
&&L_OP_ANYCHAR_STAR_PEEK_NEXT,
&&L_OP_ANYCHAR_ML_STAR_PEEK_NEXT,
&&L_OP_WORD,
&&L_OP_NOT_WORD,
&&L_OP_WORD_BOUND,
&&L_OP_NOT_WORD_BOUND,
#ifdef USE_WORD_BEGIN_END
&&L_OP_WORD_BEGIN,
&&L_OP_WORD_END,
#else
&&L_DEFAULT,
&&L_DEFAULT,
#endif
&&L_OP_ASCII_WORD,
&&L_OP_NOT_ASCII_WORD,
&&L_OP_ASCII_WORD_BOUND,
&&L_OP_NOT_ASCII_WORD_BOUND,
#ifdef USE_WORD_BEGIN_END
&&L_OP_ASCII_WORD_BEGIN,
&&L_OP_ASCII_WORD_END,
#else
&&L_DEFAULT,
&&L_DEFAULT,
#endif
&&L_OP_BEGIN_BUF,
&&L_OP_END_BUF,
&&L_OP_BEGIN_LINE,
&&L_OP_END_LINE,
&&L_OP_SEMI_END_BUF,
&&L_OP_BEGIN_POSITION,
&&L_OP_BEGIN_POS_OR_LINE, /* used for implicit anchor optimization */
&&L_OP_BACKREF1,
&&L_OP_BACKREF2,
&&L_OP_BACKREFN,
&&L_OP_BACKREFN_IC,
&&L_OP_BACKREF_MULTI,
&&L_OP_BACKREF_MULTI_IC,
#ifdef USE_BACKREF_WITH_LEVEL
&&L_OP_BACKREF_WITH_LEVEL, /* \k<xxx+n>, \k<xxx-n> */
#else
&&L_DEFAULT,
#endif
&&L_OP_MEMORY_START,
&&L_OP_MEMORY_START_PUSH, /* push back-tracker to stack */
&&L_OP_MEMORY_END_PUSH, /* push back-tracker to stack */
#ifdef USE_SUBEXP_CALL
&&L_OP_MEMORY_END_PUSH_REC, /* push back-tracker to stack */
#else
&&L_DEFAULT,
#endif
&&L_OP_MEMORY_END,
#ifdef USE_SUBEXP_CALL
&&L_OP_MEMORY_END_REC, /* push marker to stack */
#else
&&L_DEFAULT,
#endif
&&L_OP_KEEP,
&&L_OP_FAIL, /* pop stack and move */
&&L_OP_JUMP,
&&L_OP_PUSH,
&&L_OP_POP,
&&L_OP_PUSH_OR_JUMP_EXACT1, /* if match exact then push, else jump. */
&&L_OP_PUSH_IF_PEEK_NEXT, /* if match exact then push, else none. */
&&L_OP_REPEAT, /* {n,m} */
&&L_OP_REPEAT_NG, /* {n,m}? (non greedy) */
&&L_OP_REPEAT_INC,
&&L_OP_REPEAT_INC_NG, /* non greedy */
&&L_OP_REPEAT_INC_SG, /* search and get in stack */
&&L_OP_REPEAT_INC_NG_SG, /* search and get in stack (non greedy) */
&&L_OP_NULL_CHECK_START, /* null loop checker start */
&&L_OP_NULL_CHECK_END, /* null loop checker end */
#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
&&L_OP_NULL_CHECK_END_MEMST, /* null loop checker end (with capture status) */
#else
&&L_DEFAULT,
#endif
#ifdef USE_SUBEXP_CALL
&&L_OP_NULL_CHECK_END_MEMST_PUSH, /* with capture status and push check-end */
#else
&&L_DEFAULT,
#endif
&&L_OP_PUSH_POS, /* (?=...) start */
&&L_OP_POP_POS, /* (?=...) end */
&&L_OP_PUSH_POS_NOT, /* (?!...) start */
&&L_OP_FAIL_POS, /* (?!...) end */
&&L_OP_PUSH_STOP_BT, /* (?>...) start */
&&L_OP_POP_STOP_BT, /* (?>...) end */
&&L_OP_LOOK_BEHIND, /* (?<=...) start (no needs end opcode) */
&&L_OP_PUSH_LOOK_BEHIND_NOT, /* (?<!...) start */
&&L_OP_FAIL_LOOK_BEHIND_NOT, /* (?<!...) end */
#ifdef USE_SUBEXP_CALL
&&L_OP_CALL, /* \g<name> */
&&L_OP_RETURN,
#else
&&L_DEFAULT,
&&L_DEFAULT,
#endif
&&L_OP_CONDITION,
#ifdef USE_COMBINATION_EXPLOSION_CHECK
&&L_OP_STATE_CHECK_PUSH, /* combination explosion check and push */
&&L_OP_STATE_CHECK_PUSH_OR_JUMP, /* check ok -> push, else jump */
&&L_OP_STATE_CHECK, /* check only */
#else
&&L_DEFAULT,
&&L_DEFAULT,
&&L_DEFAULT,
#endif
#ifdef USE_COMBINATION_EXPLOSION_CHECK
&&L_OP_STATE_CHECK_ANYCHAR_STAR,
&&L_OP_STATE_CHECK_ANYCHAR_ML_STAR,
#else
&&L_DEFAULT,
&&L_DEFAULT,
#endif
/* no need: IS_DYNAMIC_OPTION() == 0 */
#if 0 /* no need: IS_DYNAMIC_OPTION() == 0 */
&&L_OP_SET_OPTION_PUSH, /* set option and push recover option */
&&L_OP_SET_OPTION /* set option */
#else
&&L_DEFAULT,
&&L_DEFAULT
#endif
};
#else
#define VM_LOOP \
while (1) { \
OPCODE_EXEC_HOOK; \
sbegin = s; \
switch (*p++) {
#define VM_LOOP_END } sprev = sbegin; }
#define CASE(x) case x:
#define DEFAULT default:
#define NEXT break
#define JUMP continue; break
#endif
VM_LOOP {
CASE(OP_END) MOP_IN(OP_END);
n = s - sstart;