Ignore:
Timestamp:
Nov 11, 2007, 10:56:13 AM (18 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

Reviewed by Sam.

This is a combination of converting to C++, tweaking the API, and adding
some additional optimizations.

Future steps will involve getting rid of the use of UTF-8 completely
(we'll use UTF-16 exclusively instead), eliminating more source files,
and some more speed-ups.

SunSpider says the current round is an 0.9% speed-up overall, and a
5.3% speed-up for regexp.

  • kjs/regexp.cpp: (KJS::RegExp::RegExp): Changed to use the error message without calling strdup on it and to pass the new types and options. (KJS::RegExp::~RegExp): Removed the now-unneeded free of the error message. (KJS::RegExp::match): Pass the new types and options.
  • kjs/regexp.h: Update type of m_constructionError.
  • pcre/AUTHORS: Update to reflect the status of the project -- we don't include the Google parts, and this isn't the PCRE library, per se.
  • pcre/COPYING: Ditto.
  • pcre/dftables.cpp: Copied from JavaScriptCore/pcre/dftables.c. (main): Removed unneeded ctype_digit.
  • pcre/pcre.h: Convert to C++, tweak API a bit. Use UChar instead of JSRegExpChar.
  • pcre/pcre_compile.cpp: Copied from JavaScriptCore/pcre/pcre_compile.c. Moved a lot of private stuff used only within this file here from pcre_internal.h. Renumbered the error codes. (error_text): Use a single string with embedded nulls for the error text (I got this idea from newer versions of PCRE). (check_escape): Changed return type to be enum instead of int. Replaced ctype_digit uses with isASCIIDigit. (is_counted_repeat): Ditto. (read_repeat_counts): Ditto. (first_significant_code): Ditto. (find_fixedlength): Ditto. (could_be_empty_branch): Ditto. (compile_branch): Ditto. Also removed some code that handles changing options. JavaScript doesn't have any of the features that allow options to change. (compile_regex): Updated for change to options parameter. (is_anchored): Ditto. (find_firstassertedchar): Ditto. (jsRegExpCompile): Changed to take separate flags instead of an options int. Also changed to call new/delete instead of pcre_malloc/free. (jsRegExpFree): Ditto.
  • pcre/pcre_exec.cpp: Copied from JavaScriptCore/pcre/pcre_exec.c. Added a case that uses computed goto for the opcode loop, but did not turn it on. Changed the RMATCH macro to handle returns more efficiently by putting the where pointer in the new frame instead of the old one, allowing us to branch to the return with a single statement. Switched to new/delete from pcre_malloc/free. Changed many RRETURN callers to not set the return value since it's already set correctly. Replaced the rrc variable with an is_match variable. Values other than "match" and "no match" are now handled differently. This allows us to remove the code to check for those cases in various rules. (match): All the case statements use a macro BEGIN_OPCODE instead. And all the continue statements, or break statements that break out of the outer case use a macro NEXT_OPCODE instead. Replaced a few if statements with assertions. (jsRegExpExecute): Use new/delete instead of pcre_malloc/free. Removed unused start_match field from the match block.
  • pcre/pcre_internal.h: Moved the last few configuration macros from pcre-config.h in here. Removed various unused types. Converted from JSRegExpChar to UChar. Eliminated pcre_malloc/free. Replaced the opcode enum with a macro that can be used in multiple places. Unfortunately we lose the comments for each opcode; we should find a place to put those back. Removed ctype_digit.
  • pcre/pcre_maketables.cpp: Copied from JavaScriptCore/pcre/pcre_maketables.c. (pcre_maketables): Got rid of the conditional code that allows this to be compiled in -- it's only used for dftables now (and soon may be obsolete entirely). Changed code for cbit_digit to not use isdigit, and took the "_" case out of the loop. Removed ctype_digit.
  • pcre/pcre_ord2utf8.cpp: Copied from JavaScriptCore/pcre/pcre_ord2utf8.c.
  • pcre/pcre_tables.cpp: Copied from JavaScriptCore/pcre/pcre_tables.c. Moved _pcre_OP_lengths out of here into pcre_exec.cpp.
  • pcre/pcre_ucp_searchfuncs.cpp: Copied from JavaScriptCore/pcre/pcre_ucp_searchfuncs.c. Updated for other file name changes.
  • pcre/ucpinternal.h: Updated header.
  • wtf/ASCIICType.h: (WTF::isASCIIDigit): Removed a branch by changing from && to & for this operation. Also added an overload that takes an int because that's useful for PCRE. Later we could optimize for int and overload other functions in this file; stuck to this simple one for now.
  • wtf/unicode/icu/UnicodeIcu.h: Removed unused isUpper.
  • wtf/unicode/qt4/UnicodeQt4.h: Ditto.
  • pcre/LICENCE: Removed.
  • pcre/pcre-config.h: Removed.
  • wtf/FastMallocPCRE.cpp: Removed.
  • pcre/dftables.c: Renamed to cpp.
  • pcre/pcre_compile.c: Ditto.
  • pcre/pcre_exec.c: Ditto.
  • pcre/pcre_maketables.c: Ditto.
  • pcre/pcre_ord2utf8.c: Ditto.
  • pcre/pcre_tables.c: Ditto.
  • pcre/pcre_ucp_searchfuncs.c: Ditto.
  • pcre/pcre_xclass.c: Ditto.
  • pcre/ucptable.c: Ditto.

WebCore:

Reviewed by Sam.

  • updated for JSRegExp function changes
  • platform/RegularExpression.cpp: (WebCore::RegularExpression::Private::compile): (WebCore::RegularExpression::match):
File:
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/pcre/pcre_exec.cpp

    r27681 r27686  
    1 /*************************************************
    2 *      Perl-Compatible Regular Expressions       *
    3 *************************************************/
    4 
    5 /* PCRE is a library of functions to support regular expressions whose syntax
    6 and semantics are as close as possible to those of the Perl 5 language.
    7 
    8                        Written by Philip Hazel
     1/* This is JavaScriptCore's variant of the PCRE library. While this library
     2started out as a copy of PCRE, many of the features of PCRE have been
     3removed. This library now supports only the regular expression features
     4required by the JavaScript language specification, and has only the functions
     5needed by JavaScriptCore and the rest of WebKit.
     6
     7                 Originally written by Philip Hazel
    98           Copyright (c) 1997-2006 University of Cambridge
    10 
    119    Copyright (C) 2002, 2004, 2006, 2007 Apple Inc. All rights reserved.
    1210
     
    4038*/
    4139
    42 
    43 /* This module contains pcre_exec(), the externally visible function that does
    44 pattern matching using an NFA algorithm, trying to mimic Perl as closely as
    45 possible. There are also some static supporting functions. */
    46 
     40/* This module contains jsRegExpExecute(), the externally visible function
     41that does pattern matching using an NFA algorithm, following the rules from
     42the JavaScript specification. There are also some supporting functions. */
    4743
    4844#include "pcre_internal.h"
     45
     46#include <wtf/ASCIICType.h>
     47#include <wtf/Vector.h>
     48
     49using namespace WTF;
     50
     51#ifdef __GNUC__
     52#define USE_COMPUTED_GOTO_FOR_MATCH_RECURSION
     53//#define USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
     54#endif
    4955
    5056/* Avoid warnings on Windows. */
     
    6268  USPTR epb_saved_eptr;
    6369} eptrblock;
     70
     71/* Structure for remembering the local variables in a private frame */
     72
     73typedef struct matchframe {
     74  /* Where to jump back to */
     75#ifndef USE_COMPUTED_GOTO_FOR_MATCH_RECURSION
     76  int where;
     77#else
     78  void *where;
     79#endif
     80
     81  struct matchframe *prevframe;
     82
     83  /* Function arguments that may change */
     84
     85  const pcre_uchar *eptr;
     86  const uschar *ecode;
     87  int offset_top;
     88  eptrblock *eptrb;
     89
     90  /* Function local variables */
     91
     92  const uschar *data;
     93  const uschar *next;
     94  const pcre_uchar *pp;
     95  const uschar *prev;
     96  const pcre_uchar *saved_eptr;
     97
     98  int repeat_othercase;
     99
     100  int ctype;
     101  int fc;
     102  int fi;
     103  int length;
     104  int max;
     105  int number;
     106  int offset;
     107  int save_offset1, save_offset2, save_offset3;
     108
     109  eptrblock newptrb;
     110} matchframe;
     111
     112/* Structure for passing "static" information around between the functions
     113doing traditional NFA matching, so that they are thread-safe. */
     114
     115typedef struct match_data {
     116  unsigned long int match_call_count;      /* As it says */
     117  int   *offset_vector;         /* Offset vector */
     118  int    offset_end;            /* One past the end */
     119  int    offset_max;            /* The maximum usable for return data */
     120  const uschar *lcc;            /* Points to lower casing table */
     121  const uschar *ctypes;         /* Points to table of type maps */
     122  BOOL   offset_overflow;       /* Set if too many extractions */
     123  USPTR  start_subject;         /* Start of the subject string */
     124  USPTR  end_subject;           /* End of the subject string */
     125  USPTR  end_match_ptr;         /* Subject position at end match */
     126  int    end_offset_top;        /* Highwater mark at end of match */
     127  BOOL   multiline;
     128  BOOL   caseless;
     129} match_data;
    64130
    65131#define match_isgroup      TRUE    /* Set if start of bracketed group */
     
    171237                   RECURSION IN THE match() FUNCTION
    172238
    173 The match() function is highly recursive, though not every recursive call
    174 increases the recursive depth. Nevertheless, some regular expressions can cause
    175 it to recurse to a great depth. I was writing for Unix, so I just let it call
    176 itself recursively. This uses the stack for saving everything that has to be
    177 saved for a recursive call. On Unix, the stack can be large, and this works
    178 fine.
    179 
    180 It turns out that on some non-Unix-like systems there are problems with
    181 programs that use a lot of stack. (This despite the fact that every last chip
    182 has oodles of memory these days, and techniques for extending the stack have
    183 been known for decades.) So....
    184 
    185 There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
    186 calls by keeping local variables that need to be preserved in blocks of memory
    187 obtained from malloc() instead instead of on the stack. Macros are used to
    188 achieve this so that the actual code doesn't look very different to what it
    189 always used to.
     239The original match() function was highly recursive. The current version
     240still has the remnants of the original in that recursive processing of the
     241regular expression is triggered by invoking a macro named RMATCH. This is
     242no longer really much like a recursive call to match() itself.
    190243****************************************************************************
    191244***************************************************************************/
    192245
    193 
    194246/* These versions of the macros use the stack, as normal. There are debugging
    195247versions and production versions. */
    196248
    197 #ifndef __GNUC__
     249#ifndef USE_COMPUTED_GOTO_FOR_MATCH_RECURSION
    198250
    199251/* Use numbered labels and switch statement at the bottom of the match function. */
     
    215267
    216268#endif
    217 
    218269
    219270#define RMATCH(num, ra, rb, rc)\
     
    222273    newframe = frame + 1;\
    223274  else\
    224     newframe = (pcre_malloc)(sizeof(matchframe));\
    225   frame->where = RMATCH_WHERE(num);\
     275    newframe = new matchframe;\
    226276  newframe->eptr = frame->eptr;\
    227277  newframe->ecode = (ra);\
     
    232282  newframe->prevframe = frame;\
    233283  frame = newframe;\
     284  frame->where = RMATCH_WHERE(num);\
    234285  DPRINTF(("restarting from line %d\n", __LINE__));\
    235   goto HEAP_RECURSE;\
     286  goto RECURSE;\
    236287RRETURN_##num:\
     288  newframe = frame;\
     289  frame = frame->prevframe;\
     290  if (!(newframe >= stackframes && newframe < stackframesend))\
     291    delete newframe;\
    237292  --rdepth;\
    238293  DPRINTF(("did a goto back to line %d\n", __LINE__));\
    239294  }
    240 
    241 #define RRETURN(ra)\
     295 
     296#define RRETURN goto RRETURN_LABEL
     297
     298#define RRETURN_NO_MATCH \
    242299  {\
    243   newframe = frame;\
    244   frame = newframe->prevframe;\
    245   if (!(newframe >= stackframes && newframe < stackframesend))\
    246     (pcre_free)(newframe);\
    247   if (frame != NULL)\
    248     {\
    249     rrc = (ra);\
    250     goto RRETURN_LABEL;\
    251     }\
    252   return ra;\
     300    is_match = FALSE;\
     301    RRETURN;\
    253302  }
    254303
    255 /* Structure for remembering the local variables in a private frame */
    256 
    257 typedef struct matchframe {
    258   struct matchframe *prevframe;
    259 
    260   /* Function arguments that may change */
    261 
    262   const pcre_uchar *eptr;
    263   const uschar *ecode;
    264   int offset_top;
    265   eptrblock *eptrb;
    266 
    267   /* Function local variables */
    268 
    269   const uschar *data;
    270   const uschar *next;
    271   const pcre_uchar *pp;
    272   const uschar *prev;
    273   const pcre_uchar *saved_eptr;
    274 
    275   int repeat_othercase;
    276 
    277   int ctype;
    278   int fc;
    279   int fi;
    280   int length;
    281   int max;
    282   int number;
    283   int offset;
    284   int save_offset1, save_offset2, save_offset3;
    285 
    286   eptrblock newptrb;
    287 
    288   /* Where to jump back to */
    289 
    290 #ifndef __GNUC__
    291   int where;
    292 #else
    293   void *where;
    294 #endif
    295 
    296 } matchframe;
    297 
    298 
    299 /***************************************************************************
    300 ***************************************************************************/
    301 
    302 
     304#define RRETURN_ERROR(error) \
     305  { \
     306    i = (error); \
     307    goto RETURN_ERROR; \
     308  }
    303309
    304310/*************************************************
     
    325331*/
    326332
    327 static int
    328 match(USPTR eptr, const uschar *ecode, int offset_top, match_data *md)
     333static int match(USPTR eptr, const uschar *ecode, int offset_top, match_data *md)
    329334{
    330 /* These variables do not need to be preserved over recursion in this function,
    331 so they can be ordinary variables in all cases. Mark them with "register"
    332 because they are used a lot in loops. */
    333 
    334 register int  rrc;    /* Returns from recursive calls */
    335 register int  i;      /* Used for loops not involving calls to RMATCH() */
    336 register int  c;      /* Character values not kept over RMATCH() calls */
     335register int is_match = FALSE;
     336register int i;
     337register int c;
     338
    337339unsigned rdepth = 0;
    338340
     
    343345BOOL minimize = FALSE; /* Initialization not really needed, but some compilers think so. */
    344346
    345 /* When recursion is not being used, all "local" variables that have to be
    346 preserved over calls to RMATCH() are part of a "frame" which is obtained from
    347 heap storage. Set up the top-level frame here; others are obtained from the
    348 heap whenever RMATCH() does a "recursion". See the macro definitions above. */
    349 
    350347/* The value 16 here is large enough that most regular expressions don't require
    351348any calls to pcre_stack_malloc, yet the amount of stack used for the array is
     
    356353matchframe *frame = stackframes;
    357354matchframe *newframe;
    358 frame->prevframe = NULL;            /* Marks the top level */
    359 
    360 /* Copy in the original argument variables */
     355
     356/* The opcode jump table. */
     357#ifdef USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
     358#define EMIT_JUMP_TABLE_ENTRY(opcode) &&LABEL_OP_##opcode,
     359static void* opcode_jump_table[256] = { FOR_EACH_OPCODE(EMIT_JUMP_TABLE_ENTRY) };
     360#undef EMIT_JUMP_TABLE_ENTRY
     361#endif
     362
     363/* One-time setup of the opcode jump table. */
     364#ifdef USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
     365i = 255;
     366while (!opcode_jump_table[i])
     367  opcode_jump_table[i--] = &&CAPTURING_BRACKET;
     368#endif
     369
     370#ifdef USE_COMPUTED_GOTO_FOR_MATCH_RECURSION
     371frame->where = &&RETURN;
     372#else
     373frame->where = 0;
     374#endif
    361375
    362376frame->eptr = eptr;
     
    367381/* This is where control jumps back to to effect "recursion" */
    368382
    369 HEAP_RECURSE:
     383RECURSE:
    370384
    371385/* OK, now we can get on with the real code of the function. Recursive calls
     
    380394haven't exceeded the recursive call limit. */
    381395
    382 if (md->match_call_count++ >= MATCH_LIMIT) RRETURN(JS_REGEXP_ERROR_MATCHLIMIT);
    383 if (rdepth >= MATCH_LIMIT_RECURSION) RRETURN(JS_REGEXP_ERROR_RECURSIONLIMIT);
     396if (md->match_call_count++ >= MATCH_LIMIT) RRETURN_ERROR(JSRegExpErrorMatchLimit);
     397if (rdepth >= MATCH_LIMIT_RECURSION) RRETURN_ERROR(JSRegExpErrorRecursionLimit);
    384398
    385399/* At the start of a bracketed group, add the current subject pointer to the
     
    397411/* Now start processing the operations. */
    398412
     413#ifndef USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
    399414for (;;)
     415#endif
    400416  {
     417
     418#ifdef USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
     419  #define BEGIN_OPCODE(opcode) LABEL_OP_##opcode
     420  #define NEXT_OPCODE goto *opcode_jump_table[*frame->ecode]
     421#else
     422  #define BEGIN_OPCODE(opcode) case OP_##opcode
     423  #define NEXT_OPCODE continue
     424#endif
     425
     426#ifdef USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
     427  NEXT_OPCODE;
     428#else
    401429  switch (*frame->ecode)
     430#endif
    402431    {
    403     case OP_BRA:     /* Non-capturing bracket: optimized */
     432    /* Non-capturing bracket: optimized */
     433
     434    BEGIN_OPCODE(BRA):
    404435    NON_CAPTURING_BRACKET:
    405436    DPRINTF(("start bracket 0\n"));
     
    407438      {
    408439      RMATCH(2, frame->ecode + 1 + LINK_SIZE, frame->eptrb, match_isgroup);
    409       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     440      if (is_match) RRETURN;
    410441      frame->ecode += GET(frame->ecode, 1);
    411442      }
    412443    while (*frame->ecode == OP_ALT);
    413444    DPRINTF(("bracket 0 failed\n"));
    414     RRETURN(MATCH_NOMATCH);
     445    RRETURN;
    415446
    416447    /* End of the pattern. */
    417448
    418     case OP_END:
     449    BEGIN_OPCODE(END):
    419450    md->end_match_ptr = frame->eptr;          /* Record where we ended */
    420451    md->end_offset_top = frame->offset_top;   /* and how many extracts were taken */
    421     RRETURN(MATCH_MATCH);
     452    is_match = TRUE;
     453    RRETURN;
    422454
    423455    /* Assertion brackets. Check the alternative branches in turn - the
     
    427459    this level is identical to the lookahead case. */
    428460
    429     case OP_ASSERT:
     461    BEGIN_OPCODE(ASSERT):
    430462    do
    431463      {
    432464      RMATCH(6, frame->ecode + 1 + LINK_SIZE, NULL, match_isgroup);
    433       if (rrc == MATCH_MATCH) break;
    434       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     465      if (is_match) break;
    435466      frame->ecode += GET(frame->ecode, 1);
    436467      }
    437468    while (*frame->ecode == OP_ALT);
    438     if (*frame->ecode == OP_KET) RRETURN(MATCH_NOMATCH);
     469    if (*frame->ecode == OP_KET) RRETURN_NO_MATCH;
    439470
    440471    /* Continue from after the assertion, updating the offsets high water
     
    444475    frame->ecode += 1 + LINK_SIZE;
    445476    frame->offset_top = md->end_offset_top;
    446     continue;
     477    NEXT_OPCODE;
    447478
    448479    /* Negative assertion: all branches must fail to match */
    449480
    450     case OP_ASSERT_NOT:
     481    BEGIN_OPCODE(ASSERT_NOT):
    451482    do
    452483      {
    453484      RMATCH(7, frame->ecode + 1 + LINK_SIZE, NULL, match_isgroup);
    454       if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
    455       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     485      if (is_match) RRETURN_NO_MATCH;
    456486      frame->ecode += GET(frame->ecode,1);
    457487      }
     
    459489
    460490    frame->ecode += 1 + LINK_SIZE;
    461     continue;
     491    NEXT_OPCODE;
    462492
    463493    /* "Once" brackets are like assertion brackets except that after a match,
     
    468498    the end of a normal bracket, leaving the subject pointer. */
    469499
    470     case OP_ONCE:
     500    BEGIN_OPCODE(ONCE):
    471501      {
    472502      frame->prev = frame->ecode;
     
    476506        {
    477507        RMATCH(9, frame->ecode + 1 + LINK_SIZE, frame->eptrb, match_isgroup);
    478         if (rrc == MATCH_MATCH) break;
    479         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     508        if (is_match) break;
    480509        frame->ecode += GET(frame->ecode,1);
    481510        }
     
    484513      /* If hit the end of the group (which could be repeated), fail */
    485514
    486       if (*frame->ecode != OP_ONCE && *frame->ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
     515      if (*frame->ecode != OP_ONCE && *frame->ecode != OP_ALT) RRETURN;
    487516
    488517      /* Continue as from after the assertion, updating the offsets high water
     
    503532        {
    504533        frame->ecode += 1+LINK_SIZE;
    505         break;
     534        NEXT_OPCODE;
    506535        }
    507536
     
    514543        {
    515544        RMATCH(10, frame->ecode + 1 + LINK_SIZE, frame->eptrb, 0);
    516         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     545        if (is_match) RRETURN;
    517546        RMATCH(11, frame->prev, frame->eptrb, match_isgroup);
    518         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     547        if (is_match) RRETURN;
    519548        }
    520549      else  /* OP_KETRMAX */
    521550        {
    522551        RMATCH(12, frame->prev, frame->eptrb, match_isgroup);
    523         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     552        if (is_match) RRETURN;
    524553        RMATCH(13, frame->ecode + 1+LINK_SIZE, frame->eptrb, 0);
    525         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
    526         }
    527       }
    528     RRETURN(MATCH_NOMATCH);
     554        if (is_match) RRETURN;
     555        }
     556      }
     557    RRETURN;
    529558
    530559    /* An alternation is the end of a branch; scan along to find the end of the
    531560    bracketed group and go to there. */
    532561
    533     case OP_ALT:
     562    BEGIN_OPCODE(ALT):
    534563    do frame->ecode += GET(frame->ecode,1); while (*frame->ecode == OP_ALT);
    535     break;
     564    NEXT_OPCODE;
    536565
    537566    /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating
     
    541570    preceded by BRAZERO or BRAMINZERO. */
    542571
    543     case OP_BRAZERO:
     572    BEGIN_OPCODE(BRAZERO):
    544573      {
    545574      frame->next = frame->ecode+1;
    546575      RMATCH(14, frame->next, frame->eptrb, match_isgroup);
    547       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     576      if (is_match) RRETURN;
    548577      do frame->next += GET(frame->next,1); while (*frame->next == OP_ALT);
    549578      frame->ecode = frame->next + 1+LINK_SIZE;
    550579      }
    551     break;
    552 
    553     case OP_BRAMINZERO:
     580    NEXT_OPCODE;
     581
     582    BEGIN_OPCODE(BRAMINZERO):
    554583      {
    555584      frame->next = frame->ecode+1;
    556585      do frame->next += GET(frame->next,1); while (*frame->next == OP_ALT);
    557586      RMATCH(15, frame->next + 1+LINK_SIZE, frame->eptrb, match_isgroup);
    558       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     587      if (is_match) RRETURN;
    559588      frame->ecode++;
    560589      }
    561     break;
     590    NEXT_OPCODE;
    562591
    563592    /* End of a group, repeated or non-repeating. If we are at the end of
     
    566595    for the "once" (not-backup up) groups. */
    567596
    568     case OP_KET:
    569     case OP_KETRMIN:
    570     case OP_KETRMAX:
     597    BEGIN_OPCODE(KET):
     598    BEGIN_OPCODE(KETRMIN):
     599    BEGIN_OPCODE(KETRMAX):
    571600      {
    572601      frame->prev = frame->ecode - GET(frame->ecode, 1);
     
    581610        md->end_match_ptr = frame->eptr;      /* For ONCE */
    582611        md->end_offset_top = frame->offset_top;
    583         RRETURN(MATCH_MATCH);
     612        is_match = TRUE;
     613        RRETURN;
    584614        }
    585615
     
    628658        {
    629659        frame->ecode += 1 + LINK_SIZE;
    630         break;
     660        NEXT_OPCODE;
    631661        }
    632662
     
    637667        {
    638668        RMATCH(16, frame->ecode + 1+LINK_SIZE, frame->eptrb, 0);
    639         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     669        if (is_match) RRETURN;
    640670        RMATCH(17, frame->prev, frame->eptrb, match_isgroup);
    641         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     671        if (is_match) RRETURN;
    642672        }
    643673      else  /* OP_KETRMAX */
    644674        {
    645675        RMATCH(18, frame->prev, frame->eptrb, match_isgroup);
    646         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     676        if (is_match) RRETURN;
    647677        RMATCH(19, frame->ecode + 1+LINK_SIZE, frame->eptrb, 0);
    648         if (rrc != MATCH_NOMATCH) RRETURN(rrc);
    649         }
    650       }
    651 
    652     RRETURN(MATCH_NOMATCH);
     678        if (is_match) RRETURN;
     679        }
     680      }
     681    RRETURN;
    653682
    654683    /* Start of subject unless notbol, or after internal newline if multiline */
    655684
    656     case OP_CIRC:
     685    BEGIN_OPCODE(CIRC):
    657686    if (md->multiline)
    658687      {
    659688      if (frame->eptr != md->start_subject && !IS_NEWLINE(frame->eptr[-1]))
    660         RRETURN(MATCH_NOMATCH);
     689        RRETURN_NO_MATCH;
    661690      frame->ecode++;
    662       break;
    663       }
    664     if (frame->eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
     691      NEXT_OPCODE;
     692      }
     693    if (frame->eptr != md->start_subject) RRETURN_NO_MATCH;
    665694    frame->ecode++;
    666     break;
     695    NEXT_OPCODE;
    667696
    668697    /* Assert before internal newline if multiline, or before a terminating
    669698    newline unless endonly is set, else end of subject unless noteol is set. */
    670699
    671     case OP_DOLL:
     700    BEGIN_OPCODE(DOLL):
    672701    if (md->multiline)
    673702      {
    674703      if (frame->eptr < md->end_subject)
    675         { if (!IS_NEWLINE(*frame->eptr)) RRETURN(MATCH_NOMATCH); }
     704        { if (!IS_NEWLINE(*frame->eptr)) RRETURN_NO_MATCH; }
    676705      frame->ecode++;
    677       break;
    678706      }
    679707    else
     
    681709      if (frame->eptr < md->end_subject - 1 ||
    682710         (frame->eptr == md->end_subject - 1 && !IS_NEWLINE(*frame->eptr)))
    683         RRETURN(MATCH_NOMATCH);
     711        RRETURN_NO_MATCH;
    684712      frame->ecode++;
    685       break;
    686       }
    687     break;
     713      }
     714    NEXT_OPCODE;
    688715
    689716    /* Word boundary assertions */
    690717
    691     case OP_NOT_WORD_BOUNDARY:
    692     case OP_WORD_BOUNDARY:
     718    BEGIN_OPCODE(NOT_WORD_BOUNDARY):
     719    BEGIN_OPCODE(WORD_BOUNDARY):
    693720      {
    694721      /* Find out if the previous and current characters are "word" characters.
     
    715742      if ((*frame->ecode++ == OP_WORD_BOUNDARY)?
    716743           cur_is_word == prev_is_word : cur_is_word != prev_is_word)
    717         RRETURN(MATCH_NOMATCH);
    718       }
    719     break;
     744        RRETURN_NO_MATCH;
     745      }
     746    NEXT_OPCODE;
    720747
    721748    /* Match a single character type; inline for speed */
    722749
    723     case OP_ANY:
     750    BEGIN_OPCODE(ANY):
    724751    if (frame->eptr < md->end_subject && IS_NEWLINE(*frame->eptr))
    725       RRETURN(MATCH_NOMATCH);
    726     if (frame->eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);
     752      RRETURN_NO_MATCH;
     753    if (frame->eptr++ >= md->end_subject) RRETURN_NO_MATCH;
    727754      while (frame->eptr < md->end_subject && ISMIDCHAR(*frame->eptr)) frame->eptr++;
    728755    frame->ecode++;
    729     break;
    730 
    731     case OP_NOT_DIGIT:
    732     if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     756    NEXT_OPCODE;
     757
     758    BEGIN_OPCODE(NOT_DIGIT):
     759    if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    733760    GETCHARINCTEST(c, frame->eptr);
    734     if (
    735        c < 128 &&
    736        (md->ctypes[c] & ctype_digit) != 0
    737        )
    738       RRETURN(MATCH_NOMATCH);
     761    if (isASCIIDigit(c))
     762      RRETURN_NO_MATCH;
    739763    frame->ecode++;
    740     break;
    741 
    742     case OP_DIGIT:
    743     if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     764    NEXT_OPCODE;
     765
     766    BEGIN_OPCODE(DIGIT):
     767    if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    744768    GETCHARINCTEST(c, frame->eptr);
    745     if (
    746        c >= 128 ||
    747        (md->ctypes[c] & ctype_digit) == 0
    748        )
    749       RRETURN(MATCH_NOMATCH);
     769    if (!isASCIIDigit(c))
     770      RRETURN_NO_MATCH;
    750771    frame->ecode++;
    751     break;
    752 
    753     case OP_NOT_WHITESPACE:
    754     if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     772    NEXT_OPCODE;
     773
     774    BEGIN_OPCODE(NOT_WHITESPACE):
     775    if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    755776    GETCHARINCTEST(c, frame->eptr);
    756     if (
    757        c < 128 &&
    758        (md->ctypes[c] & ctype_space) != 0
    759        )
    760       RRETURN(MATCH_NOMATCH);
     777    if (c < 128 && (md->ctypes[c] & ctype_space) != 0)
     778      RRETURN_NO_MATCH;
    761779    frame->ecode++;
    762     break;
    763 
    764     case OP_WHITESPACE:
    765     if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     780    NEXT_OPCODE;
     781
     782    BEGIN_OPCODE(WHITESPACE):
     783    if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    766784    GETCHARINCTEST(c, frame->eptr);
    767     if (
    768        c >= 128 ||
    769        (md->ctypes[c] & ctype_space) == 0
    770        )
    771       RRETURN(MATCH_NOMATCH);
     785    if (c >= 128 || (md->ctypes[c] & ctype_space) == 0)
     786      RRETURN_NO_MATCH;
    772787    frame->ecode++;
    773     break;
    774 
    775     case OP_NOT_WORDCHAR:
    776     if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     788    NEXT_OPCODE;
     789
     790    BEGIN_OPCODE(NOT_WORDCHAR):
     791    if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    777792    GETCHARINCTEST(c, frame->eptr);
    778     if (
    779        c < 128 &&
    780        (md->ctypes[c] & ctype_word) != 0
    781        )
    782       RRETURN(MATCH_NOMATCH);
     793    if (c < 128 && (md->ctypes[c] & ctype_word) != 0)
     794      RRETURN_NO_MATCH;
    783795    frame->ecode++;
    784     break;
    785 
    786     case OP_WORDCHAR:
    787     if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     796    NEXT_OPCODE;
     797
     798    BEGIN_OPCODE(WORDCHAR):
     799    if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    788800    GETCHARINCTEST(c, frame->eptr);
    789     if (
    790        c >= 128 ||
    791        (md->ctypes[c] & ctype_word) == 0
    792        )
    793       RRETURN(MATCH_NOMATCH);
     801    if (c >= 128 || (md->ctypes[c] & ctype_word) == 0)
     802      RRETURN_NO_MATCH;
    794803    frame->ecode++;
    795     break;
     804    NEXT_OPCODE;
    796805
    797806    /* Match a back reference, possibly repeatedly. Look past the end of the
     
    803812    loops). */
    804813
    805     case OP_REF:
     814    BEGIN_OPCODE(REF):
    806815      {
    807816      frame->offset = GET2(frame->ecode, 1) << 1;               /* Doubled ref number */
     
    844853
    845854        default:               /* No repeat follows */
    846         if (!match_ref(frame->offset, frame->eptr, frame->length, md)) RRETURN(MATCH_NOMATCH);
     855        if (!match_ref(frame->offset, frame->eptr, frame->length, md)) RRETURN_NO_MATCH;
    847856        frame->eptr += frame->length;
    848         continue;              /* With the main loop */
     857        NEXT_OPCODE;
    849858        }
    850859
     
    852861      main loop. */
    853862
    854       if (frame->length == 0) continue;
     863      if (frame->length == 0)
     864        NEXT_OPCODE;
    855865
    856866      /* First, ensure the minimum number of matches are present. */
     
    858868      for (i = 1; i <= min; i++)
    859869        {
    860         if (!match_ref(frame->offset, frame->eptr, frame->length, md)) RRETURN(MATCH_NOMATCH);
     870        if (!match_ref(frame->offset, frame->eptr, frame->length, md)) RRETURN_NO_MATCH;
    861871        frame->eptr += frame->length;
    862872        }
     
    865875      They are not both allowed to be zero. */
    866876
    867       if (min == frame->max) continue;
     877      if (min == frame->max)
     878        NEXT_OPCODE;
    868879
    869880      /* If minimizing, keep trying and advancing the pointer */
     
    874885          {
    875886          RMATCH(20, frame->ecode, frame->eptrb, 0);
    876           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     887          if (is_match) RRETURN;
    877888          if (frame->fi >= frame->max || !match_ref(frame->offset, frame->eptr, frame->length, md))
    878             RRETURN(MATCH_NOMATCH);
     889            RRETURN;
    879890          frame->eptr += frame->length;
    880891          }
     
    895906          {
    896907          RMATCH(21, frame->ecode, frame->eptrb, 0);
    897           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     908          if (is_match) RRETURN;
    898909          frame->eptr -= frame->length;
    899910          }
    900         RRETURN(MATCH_NOMATCH);
     911        RRETURN_NO_MATCH;
    901912        }
    902913      }
    903914    /* Control never gets here */
    904 
    905 
    906915
    907916    /* Match a bit-mapped character class, possibly repeatedly. This op code is
     
    916925    again for speed. */
    917926
    918     case OP_NCLASS:
    919     case OP_CLASS:
     927    BEGIN_OPCODE(NCLASS):
     928    BEGIN_OPCODE(CLASS):
    920929      {
    921930      frame->data = frame->ecode + 1;                /* Save for matching */
     
    956965        for (i = 1; i <= min; i++)
    957966          {
    958           if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     967          if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    959968          GETCHARINC(c, frame->eptr);
    960969          if (c > 255)
    961970            {
    962             if (frame->data[-1] == OP_CLASS) RRETURN(MATCH_NOMATCH);
     971            if (frame->data[-1] == OP_CLASS) RRETURN_NO_MATCH;
    963972            }
    964973          else
    965974            {
    966             if ((frame->data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
     975            if ((frame->data[c/8] & (1 << (c&7))) == 0) RRETURN_NO_MATCH;
    967976            }
    968977          }
     
    972981      need to recurse. */
    973982
    974       if (min == frame->max) continue;
     983      if (min == frame->max)
     984        NEXT_OPCODE;     
    975985
    976986      /* If minimizing, keep testing the rest of the expression and advancing
    977987      the pointer while it matches the class. */
    978 
    979988      if (minimize)
    980989        {
     
    983992            {
    984993            RMATCH(22, frame->ecode, frame->eptrb, 0);
    985             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
    986             if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     994            if (is_match) RRETURN;
     995            if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN;
    987996            GETCHARINC(c, frame->eptr);
    988997            if (c > 255)
    989998              {
    990               if (frame->data[-1] == OP_CLASS) RRETURN(MATCH_NOMATCH);
     999              if (frame->data[-1] == OP_CLASS) RRETURN;
    9911000              }
    9921001            else
    9931002              {
    994               if ((frame->data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
     1003              if ((frame->data[c/8] & (1 << (c&7))) == 0) RRETURN;
    9951004              }
    9961005            }
     
    9981007        /* Control never gets here */
    9991008        }
    1000 
    10011009      /* If maximizing, find the longest possible run, then work backwards. */
    1002 
    10031010      else
    10041011        {
    10051012        frame->pp = frame->eptr;
    10061013
    1007           {
    10081014          for (i = min; i < frame->max; i++)
    10091015            {
     
    10241030            {
    10251031            RMATCH(24, frame->ecode, frame->eptrb, 0);
    1026             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1032            if (is_match) RRETURN;
    10271033            if (frame->eptr-- == frame->pp) break;        /* Stop if tried at original pos */
    10281034            BACKCHAR(frame->eptr);
    10291035            }
    1030           }
    1031         RRETURN(MATCH_NOMATCH);
     1036
     1037        RRETURN;
    10321038        }
    10331039      }
    10341040    /* Control never gets here */
    1035 
    10361041
    10371042    /* Match an extended character class. This opcode is encountered only
    10381043    in UTF-8 mode, because that's the only time it is compiled. */
    10391044
    1040     case OP_XCLASS:
     1045    BEGIN_OPCODE(XCLASS):
    10411046      {
    10421047      frame->data = frame->ecode + 1 + LINK_SIZE;                /* Save for matching */
     
    10691074        default:               /* No repeat follows */
    10701075        min = frame->max = 1;
    1071         break;
    10721076        }
    10731077
     
    10761080      for (i = 1; i <= min; i++)
    10771081        {
    1078         if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     1082        if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    10791083        GETCHARINC(c, frame->eptr);
    1080         if (!_pcre_xclass(c, frame->data)) RRETURN(MATCH_NOMATCH);
     1084        if (!_pcre_xclass(c, frame->data)) RRETURN_NO_MATCH;
    10811085        }
    10821086
     
    10841088      need to recurse. */
    10851089
    1086       if (min == frame->max) continue;
     1090      if (min == frame->max)
     1091        NEXT_OPCODE;
    10871092
    10881093      /* If minimizing, keep testing the rest of the expression and advancing
     
    10941099          {
    10951100          RMATCH(26, frame->ecode, frame->eptrb, 0);
    1096           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
    1097           if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     1101          if (is_match) RRETURN;
     1102          if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN;
    10981103          GETCHARINC(c, frame->eptr);
    1099           if (!_pcre_xclass(c, frame->data)) RRETURN(MATCH_NOMATCH);
     1104          if (!_pcre_xclass(c, frame->data)) RRETURN;
    11001105          }
    11011106        /* Control never gets here */
     
    11181123          {
    11191124          RMATCH(27, frame->ecode, frame->eptrb, 0);
    1120           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1125          if (is_match) RRETURN;
    11211126          if (frame->eptr-- == frame->pp) break;        /* Stop if tried at original pos */
    11221127          BACKCHAR(frame->eptr)
    11231128          }
    1124         RRETURN(MATCH_NOMATCH);
     1129        RRETURN;
    11251130        }
    11261131
     
    11301135    /* Match a single character, casefully */
    11311136
    1132     case OP_CHAR:
     1137    BEGIN_OPCODE(CHAR):
    11331138      {
    11341139      frame->length = 1;
     
    11411146        {
    11421147          case 0:
    1143             RRETURN(MATCH_NOMATCH);
     1148            RRETURN_NO_MATCH;
    11441149          case 1:
    11451150            dc = *frame->eptr++;
    11461151            if (IS_LEADING_SURROGATE(dc))
    1147               RRETURN(MATCH_NOMATCH);
     1152              RRETURN_NO_MATCH;
    11481153            break;
    11491154          default:
    11501155            GETCHARINC(dc, frame->eptr);
    11511156        }
    1152         if (frame->fc != dc) RRETURN(MATCH_NOMATCH);
    1153      
    1154       }
    1155     break;
     1157        if (frame->fc != dc) RRETURN_NO_MATCH;
     1158      }
     1159      }
     1160    NEXT_OPCODE;
    11561161
    11571162    /* Match a single character, caselessly */
    11581163
    1159     case OP_CHARNC:
     1164    BEGIN_OPCODE(CHARNC):
    11601165      {
    11611166      frame->length = 1;
     
    11631168      GETUTF8CHARLEN(frame->fc, frame->ecode, frame->length);
    11641169
    1165       if (md->end_subject - frame->eptr == 0) RRETURN(MATCH_NOMATCH);
    1166 
    1167       /* If the pattern character's value is < 128, we have only one byte, and
    1168       can use the fast lookup table. */
    1169 
    1170       if (frame->fc < 128)
    1171         {
    1172         int dc;
    1173         frame->ecode++;
    1174         dc = *frame->eptr++;
    1175         if (dc >= 128 || md->lcc[frame->fc] != md->lcc[dc]) RRETURN(MATCH_NOMATCH);
    1176         }
    1177 
    1178       /* Otherwise we must pick up the subject character */
    1179 
    1180       else
     1170      if (md->end_subject - frame->eptr == 0) RRETURN_NO_MATCH;
     1171
    11811172        {
    11821173        int dc;
     
    11841175          dc = *frame->eptr++;
    11851176          if (IS_LEADING_SURROGATE(dc))
    1186             RRETURN(MATCH_NOMATCH);
     1177            RRETURN_NO_MATCH;
    11871178        } else
    11881179        GETCHARINC(dc, frame->eptr);
     
    11951186          {
    11961187          if (dc != _pcre_ucp_othercase(frame->fc))
    1197             RRETURN(MATCH_NOMATCH);
    1198           }
    1199         }
    1200       }
    1201     break;
     1188            RRETURN_NO_MATCH;
     1189          }
     1190        }
     1191      }
     1192    NEXT_OPCODE;
    12021193
    12031194    /* Match a single ASCII character. */
    12041195
    1205     case OP_ASCII_CHAR:
     1196    BEGIN_OPCODE(ASCII_CHAR):
    12061197    if (md->end_subject == frame->eptr)
    1207       RRETURN(MATCH_NOMATCH);
     1198      RRETURN_NO_MATCH;
    12081199    if (*frame->eptr != frame->ecode[1])
    1209       RRETURN(MATCH_NOMATCH);
     1200      RRETURN_NO_MATCH;
    12101201    ++frame->eptr;
    12111202    frame->ecode += 2;
    1212     break;
     1203    NEXT_OPCODE;
    12131204
    12141205    /* Match one of two cases of an ASCII character. */
    12151206
    1216     case OP_ASCII_LETTER_NC:
     1207    BEGIN_OPCODE(ASCII_LETTER_NC):
    12171208    if (md->end_subject == frame->eptr)
    1218       RRETURN(MATCH_NOMATCH);
     1209      RRETURN_NO_MATCH;
    12191210    if ((*frame->eptr | 0x20) != frame->ecode[1])
    1220       RRETURN(MATCH_NOMATCH);
     1211      RRETURN_NO_MATCH;
    12211212    ++frame->eptr;
    12221213    frame->ecode += 2;
    1223     break;
     1214    NEXT_OPCODE;
    12241215
    12251216    /* Match a single character repeatedly; different opcodes share code. */
    12261217
    1227     case OP_EXACT:
     1218    BEGIN_OPCODE(EXACT):
    12281219    min = frame->max = GET2(frame->ecode, 1);
    12291220    minimize = FALSE;
     
    12311222    goto REPEATCHAR;
    12321223
    1233     case OP_UPTO:
    1234     case OP_MINUPTO:
     1224    BEGIN_OPCODE(UPTO):
     1225    BEGIN_OPCODE(MINUPTO):
    12351226    min = 0;
    12361227    frame->max = GET2(frame->ecode, 1);
     
    12391230    goto REPEATCHAR;
    12401231
    1241     case OP_STAR:
    1242     case OP_MINSTAR:
    1243     case OP_PLUS:
    1244     case OP_MINPLUS:
    1245     case OP_QUERY:
    1246     case OP_MINQUERY:
     1232    BEGIN_OPCODE(STAR):
     1233    BEGIN_OPCODE(MINSTAR):
     1234    BEGIN_OPCODE(PLUS):
     1235    BEGIN_OPCODE(MINPLUS):
     1236    BEGIN_OPCODE(QUERY):
     1237    BEGIN_OPCODE(MINQUERY):
    12471238    c = *frame->ecode++ - OP_STAR;
    12481239    minimize = (c & 1) != 0;
     
    12601251      GETUTF8CHARLEN(frame->fc, frame->ecode, frame->length);
    12611252      {
    1262       if (min * (frame->fc > 0xFFFF ? 2 : 1) > md->end_subject - frame->eptr) RRETURN(MATCH_NOMATCH);
     1253      if (min * (frame->fc > 0xFFFF ? 2 : 1) > md->end_subject - frame->eptr) RRETURN_NO_MATCH;
    12631254      frame->ecode += frame->length;
    12641255
     
    12691260        for (i = 1; i <= min; i++)
    12701261          {
    1271           if (*frame->eptr != frame->fc && *frame->eptr != othercase) RRETURN(MATCH_NOMATCH);
     1262          if (*frame->eptr != frame->fc && *frame->eptr != othercase) RRETURN_NO_MATCH;
    12721263          ++frame->eptr;
    12731264          }
    12741265
    1275         if (min == frame->max) continue;
     1266        if (min == frame->max)
     1267          NEXT_OPCODE;
    12761268
    12771269        if (minimize)
     
    12811273            {
    12821274            RMATCH(28, frame->ecode, frame->eptrb, 0);
    1283             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
    1284             if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
    1285             if (*frame->eptr != frame->fc && *frame->eptr != frame->repeat_othercase) RRETURN(MATCH_NOMATCH);
     1275            if (is_match) RRETURN;
     1276            if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN;
     1277            if (*frame->eptr != frame->fc && *frame->eptr != frame->repeat_othercase) RRETURN;
    12861278            ++frame->eptr;
    12871279            }
     
    13001292           {
    13011293           RMATCH(29, frame->ecode, frame->eptrb, 0);
    1302            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1294           if (is_match) RRETURN;
    13031295           --frame->eptr;
    13041296           }
    1305           RRETURN(MATCH_NOMATCH);
     1297          RRETURN_NO_MATCH;
    13061298          }
    13071299        /* Control never gets here */
     
    13151307          int nc;
    13161308          GETCHAR(nc, frame->eptr);
    1317           if (nc != frame->fc) RRETURN(MATCH_NOMATCH);
     1309          if (nc != frame->fc) RRETURN_NO_MATCH;
    13181310          frame->eptr += 2;
    13191311          }
    13201312
    1321         if (min == frame->max) continue;
     1313        if (min == frame->max)
     1314          NEXT_OPCODE;
    13221315
    13231316        if (minimize)
     
    13271320            int nc;
    13281321            RMATCH(30, frame->ecode, frame->eptrb, 0);
    1329             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
    1330             if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     1322            if (is_match) RRETURN;
     1323            if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN;
    13311324            GETCHAR(nc, frame->eptr);
    1332             if (*frame->eptr != frame->fc) RRETURN(MATCH_NOMATCH);
     1325            if (*frame->eptr != frame->fc) RRETURN;
    13331326            frame->eptr += 2;
    13341327            }
     
    13491342           {
    13501343           RMATCH(31, frame->ecode, frame->eptrb, 0);
    1351            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1344           if (is_match) RRETURN;
    13521345           frame->eptr -= 2;
    13531346           }
    1354           RRETURN(MATCH_NOMATCH);
     1347          RRETURN_NO_MATCH;
    13551348          }
    13561349          /* Control never gets here */
     
    13621355    checking can be multibyte. */
    13631356
    1364     case OP_NOT:
    1365     if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     1357    BEGIN_OPCODE(NOT):
     1358    if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    13661359    frame->ecode++;
    13671360    GETCHARINCTEST(c, frame->eptr);
     
    13701363      if (c < 128)
    13711364        c = md->lcc[c];
    1372       if (md->lcc[*frame->ecode++] == c) RRETURN(MATCH_NOMATCH);
     1365      if (md->lcc[*frame->ecode++] == c) RRETURN_NO_MATCH;
    13731366      }
    13741367    else
    13751368      {
    1376       if (*frame->ecode++ == c) RRETURN(MATCH_NOMATCH);
    1377       }
    1378     break;
     1369      if (*frame->ecode++ == c) RRETURN_NO_MATCH;
     1370      }
     1371    NEXT_OPCODE;
    13791372
    13801373    /* Match a negated single one-byte character repeatedly. This is almost a
     
    13851378    about... */
    13861379
    1387     case OP_NOTEXACT:
     1380    BEGIN_OPCODE(NOTEXACT):
    13881381    min = frame->max = GET2(frame->ecode, 1);
    13891382    minimize = FALSE;
     
    13911384    goto REPEATNOTCHAR;
    13921385
    1393     case OP_NOTUPTO:
    1394     case OP_NOTMINUPTO:
     1386    BEGIN_OPCODE(NOTUPTO):
     1387    BEGIN_OPCODE(NOTMINUPTO):
    13951388    min = 0;
    13961389    frame->max = GET2(frame->ecode, 1);
     
    13991392    goto REPEATNOTCHAR;
    14001393
    1401     case OP_NOTSTAR:
    1402     case OP_NOTMINSTAR:
    1403     case OP_NOTPLUS:
    1404     case OP_NOTMINPLUS:
    1405     case OP_NOTQUERY:
    1406     case OP_NOTMINQUERY:
     1394    BEGIN_OPCODE(NOTSTAR):
     1395    BEGIN_OPCODE(NOTMINSTAR):
     1396    BEGIN_OPCODE(NOTPLUS):
     1397    BEGIN_OPCODE(NOTMINPLUS):
     1398    BEGIN_OPCODE(NOTQUERY):
     1399    BEGIN_OPCODE(NOTMINQUERY):
    14071400    c = *frame->ecode++ - OP_NOTSTAR;
    14081401    minimize = (c & 1) != 0;
     
    14161409
    14171410    REPEATNOTCHAR:
    1418     if (min > md->end_subject - frame->eptr) RRETURN(MATCH_NOMATCH);
     1411    if (min > md->end_subject - frame->eptr) RRETURN_NO_MATCH;
    14191412    frame->fc = *frame->ecode++;
    14201413
     
    14311424    if (md->caseless)
    14321425      {
    1433       frame->fc = md->lcc[frame->fc];
     1426      if (frame->fc < 128)
     1427        frame->fc = md->lcc[frame->fc];
    14341428
    14351429        {
     
    14391433          GETCHARINC(d, frame->eptr);
    14401434          if (d < 128) d = md->lcc[d];
    1441           if (frame->fc == d) RRETURN(MATCH_NOMATCH);
    1442           }
    1443         }
    1444 
    1445       if (min == frame->max) continue;
     1435          if (frame->fc == d) RRETURN_NO_MATCH;
     1436          }
     1437        }
     1438
     1439      if (min == frame->max)
     1440        NEXT_OPCODE;     
    14461441
    14471442      if (minimize)
     
    14521447            {
    14531448            RMATCH(38, frame->ecode, frame->eptrb, 0);
    1454             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1449            if (is_match) RRETURN;
    14551450            GETCHARINC(d, frame->eptr);
    14561451            if (d < 128) d = md->lcc[d];
    14571452            if (frame->fi >= frame->max || frame->eptr >= md->end_subject || frame->fc == d)
    1458               RRETURN(MATCH_NOMATCH);
     1453              RRETURN;
    14591454            }
    14601455          }
     
    14821477            {
    14831478            RMATCH(40, frame->ecode, frame->eptrb, 0);
    1484             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1479            if (is_match) RRETURN;
    14851480            if (frame->eptr-- == frame->pp) break;        /* Stop if tried at original pos */
    14861481            BACKCHAR(frame->eptr);
     
    14881483          }
    14891484
    1490         RRETURN(MATCH_NOMATCH);
     1485        RRETURN;
    14911486        }
    14921487      /* Control never gets here */
     
    15021497          {
    15031498          GETCHARINC(d, frame->eptr);
    1504           if (frame->fc == d) RRETURN(MATCH_NOMATCH);
    1505           }
    1506         }
    1507 
    1508       if (min == frame->max) continue;
     1499          if (frame->fc == d) RRETURN_NO_MATCH;
     1500          }
     1501        }
     1502
     1503      if (min == frame->max)
     1504        NEXT_OPCODE;
    15091505
    15101506      if (minimize)
     
    15151511            {
    15161512            RMATCH(42, frame->ecode, frame->eptrb, 0);
    1517             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1513            if (is_match) RRETURN;
    15181514            GETCHARINC(d, frame->eptr);
    15191515            if (frame->fi >= frame->max || frame->eptr >= md->end_subject || frame->fc == d)
    1520               RRETURN(MATCH_NOMATCH);
     1516              RRETURN;
    15211517            }
    15221518          }
     
    15431539            {
    15441540            RMATCH(44, frame->ecode, frame->eptrb, 0);
    1545             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1541            if (is_match) RRETURN;
    15461542            if (frame->eptr-- == frame->pp) break;        /* Stop if tried at original pos */
    15471543            BACKCHAR(frame->eptr);
     
    15491545          }
    15501546
    1551         RRETURN(MATCH_NOMATCH);
     1547        RRETURN;
    15521548        }
    15531549      }
     
    15581554    repeat it in the interests of efficiency. */
    15591555
    1560     case OP_TYPEEXACT:
     1556    BEGIN_OPCODE(TYPEEXACT):
    15611557    min = frame->max = GET2(frame->ecode, 1);
    15621558    minimize = TRUE;
     
    15641560    goto REPEATTYPE;
    15651561
    1566     case OP_TYPEUPTO:
    1567     case OP_TYPEMINUPTO:
     1562    BEGIN_OPCODE(TYPEUPTO):
     1563    BEGIN_OPCODE(TYPEMINUPTO):
    15681564    min = 0;
    15691565    frame->max = GET2(frame->ecode, 1);
     
    15721568    goto REPEATTYPE;
    15731569
    1574     case OP_TYPESTAR:
    1575     case OP_TYPEMINSTAR:
    1576     case OP_TYPEPLUS:
    1577     case OP_TYPEMINPLUS:
    1578     case OP_TYPEQUERY:
    1579     case OP_TYPEMINQUERY:
     1570    BEGIN_OPCODE(TYPESTAR):
     1571    BEGIN_OPCODE(TYPEMINSTAR):
     1572    BEGIN_OPCODE(TYPEPLUS):
     1573    BEGIN_OPCODE(TYPEMINPLUS):
     1574    BEGIN_OPCODE(TYPEQUERY):
     1575    BEGIN_OPCODE(TYPEMINQUERY):
    15801576    c = *frame->ecode++ - OP_TYPESTAR;
    15811577    minimize = (c & 1) != 0;
     
    15991595    and single-bytes. */
    16001596
    1601     if (min > md->end_subject - frame->eptr) RRETURN(MATCH_NOMATCH);
     1597    if (min > md->end_subject - frame->eptr) RRETURN_NO_MATCH;
    16021598    if (min > 0)
    16031599      {
     
    16081604          {
    16091605          if (frame->eptr >= md->end_subject || IS_NEWLINE(*frame->eptr))
    1610             RRETURN(MATCH_NOMATCH);
     1606            RRETURN_NO_MATCH;
    16111607          ++frame->eptr;
    16121608          while (frame->eptr < md->end_subject && ISMIDCHAR(*frame->eptr)) frame->eptr++;
     
    16171613        for (i = 1; i <= min; i++)
    16181614          {
    1619           if (frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     1615          if (frame->eptr >= md->end_subject) RRETURN_NO_MATCH;
    16201616          GETCHARINC(c, frame->eptr);
    1621           if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
    1622             RRETURN(MATCH_NOMATCH);
     1617          if (isASCIIDigit(c))
     1618            RRETURN_NO_MATCH;
    16231619          }
    16241620        break;
     
    16271623        for (i = 1; i <= min; i++)
    16281624          {
    1629           if (frame->eptr >= md->end_subject ||
    1630              *frame->eptr >= 128 || (md->ctypes[*frame->eptr++] & ctype_digit) == 0)
    1631             RRETURN(MATCH_NOMATCH);
     1625          if (frame->eptr >= md->end_subject || !isASCIIDigit(*frame->eptr++))
     1626            RRETURN_NO_MATCH;
    16321627          /* No need to skip more bytes - we know it's a 1-byte character */
    16331628          }
     
    16391634          if (frame->eptr >= md->end_subject ||
    16401635             (*frame->eptr < 128 && (md->ctypes[*frame->eptr] & ctype_space) != 0))
    1641             RRETURN(MATCH_NOMATCH);
     1636            RRETURN_NO_MATCH;
    16421637          while (++frame->eptr < md->end_subject && ISMIDCHAR(*frame->eptr));
    16431638          }
     
    16491644          if (frame->eptr >= md->end_subject ||
    16501645             *frame->eptr >= 128 || (md->ctypes[*frame->eptr++] & ctype_space) == 0)
    1651             RRETURN(MATCH_NOMATCH);
     1646            RRETURN_NO_MATCH;
    16521647          /* No need to skip more bytes - we know it's a 1-byte character */
    16531648          }
     
    16591654          if (frame->eptr >= md->end_subject ||
    16601655             (*frame->eptr < 128 && (md->ctypes[*frame->eptr] & ctype_word) != 0))
    1661             RRETURN(MATCH_NOMATCH);
     1656            RRETURN_NO_MATCH;
    16621657          while (++frame->eptr < md->end_subject && ISMIDCHAR(*frame->eptr));
    16631658          }
     
    16691664          if (frame->eptr >= md->end_subject ||
    16701665             *frame->eptr >= 128 || (md->ctypes[*frame->eptr++] & ctype_word) == 0)
    1671             RRETURN(MATCH_NOMATCH);
     1666            RRETURN_NO_MATCH;
    16721667          /* No need to skip more bytes - we know it's a 1-byte character */
    16731668          }
     
    16751670
    16761671        default:
    1677         RRETURN(JS_REGEXP_ERROR_INTERNAL);
     1672        ASSERT_NOT_REACHED();
     1673        RRETURN_ERROR(JSRegExpErrorInternal);
    16781674        }  /* End switch(frame->ctype) */
    16791675      }
     
    16811677    /* If min = max, continue at the same level without recursing */
    16821678
    1683     if (min == frame->max) continue;
     1679    if (min == frame->max)
     1680      NEXT_OPCODE;   
    16841681
    16851682    /* If minimizing, we have to test the rest of the pattern before each
     
    16921689          {
    16931690          RMATCH(48, frame->ecode, frame->eptrb, 0);
    1694           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
    1695           if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
     1691          if (is_match) RRETURN;
     1692          if (frame->fi >= frame->max || frame->eptr >= md->end_subject) RRETURN;
    16961693
    16971694          GETCHARINC(c, frame->eptr);
     
    16991696            {
    17001697            case OP_ANY:
    1701             if (IS_NEWLINE(c)) RRETURN(MATCH_NOMATCH);
     1698            if (IS_NEWLINE(c)) RRETURN;
    17021699            break;
    17031700
    17041701            case OP_NOT_DIGIT:
    1705             if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
    1706               RRETURN(MATCH_NOMATCH);
     1702            if (isASCIIDigit(c))
     1703              RRETURN;
    17071704            break;
    17081705
    17091706            case OP_DIGIT:
    1710             if (c >= 128 || (md->ctypes[c] & ctype_digit) == 0)
    1711               RRETURN(MATCH_NOMATCH);
     1707            if (!isASCIIDigit(c))
     1708              RRETURN;
    17121709            break;
    17131710
    17141711            case OP_NOT_WHITESPACE:
    17151712            if (c < 128 && (md->ctypes[c] & ctype_space) != 0)
    1716               RRETURN(MATCH_NOMATCH);
     1713              RRETURN;
    17171714            break;
    17181715
    17191716            case OP_WHITESPACE:
    17201717            if  (c >= 128 || (md->ctypes[c] & ctype_space) == 0)
    1721               RRETURN(MATCH_NOMATCH);
     1718              RRETURN;
    17221719            break;
    17231720
    17241721            case OP_NOT_WORDCHAR:
    17251722            if (c < 128 && (md->ctypes[c] & ctype_word) != 0)
    1726               RRETURN(MATCH_NOMATCH);
     1723              RRETURN;
    17271724            break;
    17281725
    17291726            case OP_WORDCHAR:
    17301727            if (c >= 128 || (md->ctypes[c] & ctype_word) == 0)
    1731               RRETURN(MATCH_NOMATCH);
     1728              RRETURN;
    17321729            break;
    17331730
    17341731            default:
    1735             RRETURN(JS_REGEXP_ERROR_INTERNAL);
     1732            ASSERT_NOT_REACHED();
     1733            RRETURN_ERROR(JSRegExpErrorInternal);
    17361734            }
    17371735          }
     
    17471745      frame->pp = frame->eptr;  /* Remember where we started */
    17481746
    1749         {
    17501747        switch(frame->ctype)
    17511748          {
     
    17891786            if (frame->eptr >= md->end_subject) break;
    17901787            GETCHARLEN(c, frame->eptr, len);
    1791             if (c < 128 && (md->ctypes[c] & ctype_digit) != 0) break;
     1788            if (isASCIIDigit(c)) break;
    17921789            frame->eptr+= len;
    17931790            }
     
    18001797            if (frame->eptr >= md->end_subject) break;
    18011798            GETCHARLEN(c, frame->eptr, len);
    1802             if (c >= 128 ||(md->ctypes[c] & ctype_digit) == 0) break;
     1799            if (!isASCIIDigit(c)) break;
    18031800            frame->eptr+= len;
    18041801            }
     
    18501847
    18511848          default:
    1852           RRETURN(JS_REGEXP_ERROR_INTERNAL);
     1849          ASSERT_NOT_REACHED();
     1850          RRETURN_ERROR(JSRegExpErrorInternal);
    18531851          }
    18541852
     
    18581856          {
    18591857          RMATCH(52, frame->ecode, frame->eptrb, 0);
    1860           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1858          if (is_match) RRETURN;
    18611859          if (frame->eptr-- == frame->pp) break;        /* Stop if tried at original pos */
    18621860          BACKCHAR(frame->eptr);
    18631861          }
    1864         }
    18651862
    18661863      /* Get here if we can't make it match with any permitted repetitions */
    18671864
    1868       RRETURN(MATCH_NOMATCH);
     1865      RRETURN;
    18691866      }
    18701867    /* Control never gets here */
    18711868
     1869    BEGIN_OPCODE(BRANUMBER):
     1870    BEGIN_OPCODE(CRMINPLUS):
     1871    BEGIN_OPCODE(CRMINQUERY):
     1872    BEGIN_OPCODE(CRMINRANGE):
     1873    BEGIN_OPCODE(CRMINSTAR):
     1874    BEGIN_OPCODE(CRPLUS):
     1875    BEGIN_OPCODE(CRQUERY):
     1876    BEGIN_OPCODE(CRRANGE):
     1877    BEGIN_OPCODE(CRSTAR):
     1878      ASSERT_NOT_REACHED();
     1879      RRETURN_ERROR(JSRegExpErrorInternal);
     1880
     1881#ifdef USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
     1882    CAPTURING_BRACKET:
     1883#else
    18721884    default:
     1885#endif
    18731886      /* Opening capturing bracket. If there is space in the offset vector, save
    18741887      the current subject position in the working slot at the top of the vector. We
     
    18851898      here; that is handled in the code for KET. */
    18861899
    1887       if (*frame->ecode > OP_BRA)
    1888         {
     1900      ASSERT(*frame->ecode > OP_BRA);
     1901
    18891902        frame->number = *frame->ecode - OP_BRA;
    18901903
     
    19051918          {
    19061919          frame->save_offset1 = md->offset_vector[frame->offset];
    1907           frame->save_offset2 = md->offset_vector[frame->offset+1];
     1920          frame->save_offset2 = md->offset_vector[frame->offset + 1];
    19081921          frame->save_offset3 = md->offset_vector[md->offset_end - frame->number];
    19091922
     
    19141927            {
    19151928            RMATCH(1, frame->ecode + 1 + LINK_SIZE, frame->eptrb, match_isgroup);
    1916             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     1929            if (is_match) RRETURN;
    19171930            frame->ecode += GET(frame->ecode, 1);
    19181931            }
     
    19221935
    19231936          md->offset_vector[frame->offset] = frame->save_offset1;
    1924           md->offset_vector[frame->offset+1] = frame->save_offset2;
     1937          md->offset_vector[frame->offset + 1] = frame->save_offset2;
    19251938          md->offset_vector[md->offset_end - frame->number] = frame->save_offset3;
    19261939
    1927           RRETURN(MATCH_NOMATCH);
     1940          RRETURN;
    19281941          }
    19291942
     
    19311944
    19321945        goto NON_CAPTURING_BRACKET;
    1933         }
    1934 
    1935     /* There's been some horrible disaster. Since all codes > OP_BRA are
    1936     for capturing brackets, and there shouldn't be any gaps between 0 and
    1937     OP_BRA, arrival here can only mean there is something seriously wrong
    1938     in the code above or the OP_xxx definitions. */
    1939 
    1940     DPRINTF(("Unknown opcode %d\n", *frame->ecode));
    1941     RRETURN(JS_REGEXP_ERROR_INTERNAL);
    19421946    }
    19431947
     
    19461950  loop. */
    19471951
    1948   }             /* End of main loop */
     1952  } /* End of main loop */
     1953
    19491954/* Control never reaches here */
    19501955
    1951 #ifndef __GNUC__
     1956#ifndef USE_COMPUTED_GOTO_FOR_MATCH_RECURSION
    19521957
    19531958RRETURN_SWITCH:
    19541959switch (frame->where)
    19551960  {
     1961  case 0: goto RETURN;
    19561962  case 1: goto RRETURN_1;
    19571963  case 2: goto RRETURN_2;
     
    19881994
    19891995abort();
    1990 return 0;
     1996RRETURN_ERROR(JSRegExpErrorInternal);
    19911997
    19921998#endif
    19931999
     2000RETURN:
     2001    return is_match ? MATCH_MATCH : MATCH_NOMATCH;
     2002
     2003RETURN_ERROR:
     2004    while (!(frame >= stackframes && frame < stackframesend)) {
     2005        newframe = frame->prevframe;
     2006        delete frame;
     2007        frame = newframe;
     2008    }
     2009    return i;
    19942010}
    19952011
     
    20212037int
    20222038jsRegExpExecute(const pcre *argument_re,
    2023   const JSRegExpChar* subject, int length, int start_offset, int *offsets,
     2039  const UChar* subject, int length, int start_offset, int *offsets,
    20242040  int offsetcount)
    20252041{
     
    20762092  {
    20772093  ocount = re->top_backref * 3 + 3;
    2078   match_block.offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
    2079   if (match_block.offset_vector == NULL) return JS_REGEXP_ERROR_NOMEMORY;
     2094  match_block.offset_vector = new int[ocount];
     2095  if (match_block.offset_vector == NULL) return JSRegExpErrorNoMemory;
    20802096  using_temporary_offsets = TRUE;
    20812097  DPRINTF(("Got memory to hold back references\n"));
     
    21112127studied, there may be a bitmap of possible first characters. */
    21122128
    2113   {
    21142129  if ((re->options & PCRE_FIRSTSET) != 0)
    21152130    {
     
    21182133      first_byte = match_block.lcc[first_byte];
    21192134    }
    2120   }
    21212135
    21222136/* For anchored or unanchored matches, there may be a "last known required
     
    22542268  if certain parts of the pattern were not used. */
    22552269
    2256   match_block.start_match = start_match;
    22572270  match_block.match_call_count = 0;
    22582271
     
    22952308
    22962309    DPRINTF(("Freeing temporary memory\n"));
    2297     (pcre_free)(match_block.offset_vector);
     2310    delete [] match_block.offset_vector;
    22982311    }
    22992312
     
    23172330  {
    23182331  DPRINTF(("Freeing temporary memory\n"));
    2319   (pcre_free)(match_block.offset_vector);
     2332  delete [] match_block.offset_vector;
    23202333  }
    23212334
    23222335  DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
    2323   return JS_REGEXP_ERROR_NOMATCH;
     2336  return JSRegExpErrorNoMatch;
    23242337}
    2325 
    2326 /* End of pcre_exec.c */
Note: See TracChangeset for help on using the changeset viewer.