/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 924 by zherczeg, Wed Feb 22 10:23:56 2012 UTC revision 941 by zherczeg, Tue Feb 28 11:33:34 2012 UTC
# Line 152  typedef struct jit_arguments { Line 152  typedef struct jit_arguments {
152    const pcre_uchar *begin;    const pcre_uchar *begin;
153    const pcre_uchar *end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    pcre_uchar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    int calllimit;    int calllimit;
# Line 287  typedef struct compiler_common { Line 288  typedef struct compiler_common {
288    int hit_start;    int hit_start;
289    /* End pointer of the first line. */    /* End pointer of the first line. */
290    int first_line_end;    int first_line_end;
291      /* Points to the marked string. */
292      int mark_ptr;
293    
294    /* Other  */    /* Other  */
295    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
# Line 296  typedef struct compiler_common { Line 299  typedef struct compiler_common {
299    int newline;    int newline;
300    int bsr_nltype;    int bsr_nltype;
301    int endonly;    int endonly;
302      BOOL has_set_som;
303    sljit_w ctypes;    sljit_w ctypes;
304    sljit_uw name_table;    sljit_uw name_table;
305    sljit_w name_count;    sljit_w name_count;
# Line 303  typedef struct compiler_common { Line 307  typedef struct compiler_common {
307    
308    /* Labels and jump lists. */    /* Labels and jump lists. */
309    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
310      struct sljit_label *leavelabel;
311    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
312    stub_list *stubs;    stub_list *stubs;
313    recurse_entry *entries;    recurse_entry *entries;
314    recurse_entry *currententry;    recurse_entry *currententry;
315    jump_list *partialmatch;    jump_list *partialmatch;
316      jump_list *leave;
317    jump_list *accept;    jump_list *accept;
318    jump_list *calllimit;    jump_list *calllimit;
319    jump_list *stackalloc;    jump_list *stackalloc;
# Line 370  typedef struct compare_context { Line 376  typedef struct compare_context {
376    
377  enum {  enum {
378    frame_end = 0,    frame_end = 0,
379    frame_setstrbegin = -1    frame_setstrbegin = -1,
380      frame_setmark = -2
381  };  };
382    
383  /* Undefine sljit macros. */  /* Undefine sljit macros. */
# Line 512  switch(*cc) Line 519  switch(*cc)
519    case OP_BRAZERO:    case OP_BRAZERO:
520    case OP_BRAMINZERO:    case OP_BRAMINZERO:
521    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
522      case OP_COMMIT:
523    case OP_FAIL:    case OP_FAIL:
524    case OP_ACCEPT:    case OP_ACCEPT:
525    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 650  switch(*cc) Line 658  switch(*cc)
658    case OP_SCBRAPOS:    case OP_SCBRAPOS:
659    return cc + 1 + LINK_SIZE + IMM2_SIZE;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
660    
661      case OP_MARK:
662      return cc + 1 + 2 + cc[1];
663    
664    default:    default:
665    return NULL;    return NULL;
666    }    }
# Line 664  while (cc < ccend) Line 675  while (cc < ccend)
675    {    {
676    switch(*cc)    switch(*cc)
677      {      {
678        case OP_SET_SOM:
679        common->has_set_som = TRUE;
680        cc += 1;
681        break;
682    
683      case OP_ASSERT:      case OP_ASSERT:
684      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
685      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 702  while (cc < ccend) Line 718  while (cc < ccend)
718      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
719      break;      break;
720    
721        case OP_MARK:
722        if (common->mark_ptr == 0)
723          {
724          common->mark_ptr = common->ovector_start;
725          common->ovector_start += sizeof(sljit_w);
726          }
727        cc += 1 + 2 + cc[1];
728        break;
729    
730      default:      default:
731      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
732      if (cc == NULL)      if (cc == NULL)
# Line 767  static int get_framesize(compiler_common Line 792  static int get_framesize(compiler_common
792  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
793  int length = 0;  int length = 0;
794  BOOL possessive = FALSE;  BOOL possessive = FALSE;
795  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
796    BOOL setmark_found = recursive;
797    
798  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
799    {    {
# Line 781  while (cc < ccend) Line 807  while (cc < ccend)
807    switch(*cc)    switch(*cc)
808      {      {
809      case OP_SET_SOM:      case OP_SET_SOM:
810      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
811      if (!setsom_found)      if (!setsom_found)
812        {        {
813        length += 2;        length += 2;
814        setsom_found = TRUE;        setsom_found = TRUE;
815        }        }
816      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
817        break;
818    
819        case OP_MARK:
820        SLJIT_ASSERT(common->mark_ptr != 0);
821        if (!setmark_found)
822          {
823          length += 2;
824          setmark_found = TRUE;
825          }
826        cc += 1 + 2 + cc[1];
827        break;
828    
829        case OP_RECURSE:
830        if (common->has_set_som && !setsom_found)
831          {
832          length += 2;
833          setsom_found = TRUE;
834          }
835        if (common->mark_ptr != 0 && !setmark_found)
836          {
837          length += 2;
838          setmark_found = TRUE;
839          }
840        cc += 1 + LINK_SIZE;
841      break;      break;
842    
843      case OP_CBRA:      case OP_CBRA:
# Line 817  static void init_frame(compiler_common * Line 867  static void init_frame(compiler_common *
867  {  {
868  DEFINE_COMPILER;  DEFINE_COMPILER;
869  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
870  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
871    BOOL setmark_found = recursive;
872  int offset;  int offset;
873    
874  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 832  while (cc < ccend) Line 883  while (cc < ccend)
883    switch(*cc)    switch(*cc)
884      {      {
885      case OP_SET_SOM:      case OP_SET_SOM:
886      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
887      if (!setsom_found)      if (!setsom_found)
888        {        {
889        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 842  while (cc < ccend) Line 893  while (cc < ccend)
893        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
894        setsom_found = TRUE;        setsom_found = TRUE;
895        }        }
896      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
897        break;
898    
899        case OP_MARK:
900        SLJIT_ASSERT(common->mark_ptr != 0);
901        if (!setmark_found)
902          {
903          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
904          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
905          stackpos += (int)sizeof(sljit_w);
906          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
907          stackpos += (int)sizeof(sljit_w);
908          setmark_found = TRUE;
909          }
910        cc += 1 + 2 + cc[1];
911        break;
912    
913        case OP_RECURSE:
914        if (common->has_set_som && !setsom_found)
915          {
916          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
917          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
918          stackpos += (int)sizeof(sljit_w);
919          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
920          stackpos += (int)sizeof(sljit_w);
921          setsom_found = TRUE;
922          }
923        if (common->mark_ptr != 0 && !setmark_found)
924          {
925          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
926          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
927          stackpos += (int)sizeof(sljit_w);
928          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
929          stackpos += (int)sizeof(sljit_w);
930          setmark_found = TRUE;
931          }
932        cc += 1 + LINK_SIZE;
933      break;      break;
934    
935      case OP_CBRA:      case OP_CBRA:
# Line 1258  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJI Line 1345  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJI
1345  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1346    
1347  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1348    if (common->mark_ptr != 0)
1349      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1350  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1351    if (common->mark_ptr != 0)
1352      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1353  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1354  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1355  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);
# Line 2320  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 2411  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
2411  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2412    
2413  JUMPHERE(jump);  JUMPHERE(jump);
2414    if (common->mark_ptr != 0)
2415      {
2416      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2417      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2418      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2419      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2420      JUMPTO(SLJIT_JUMP, mainloop);
2421    
2422      JUMPHERE(jump);
2423      }
2424    
2425  /* Unknown command. */  /* Unknown command. */
2426  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2427  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2612  static const pcre_uchar *SLJIT_CALL do_u Line 2714  static const pcre_uchar *SLJIT_CALL do_u
2714  {  {
2715  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2716  int c1, c2;  int c1, c2;
2717  const pcre_uchar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
2718  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
2719    
2720  while (src1 < end1)  while (src1 < end1)
# Line 3815  if (common->utf && *cc == OP_REFI) Line 3917  if (common->utf && *cc == OP_REFI)
3917    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3918    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3919    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3920    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
3921    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
3922    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3923    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
# Line 4050  if (entry == NULL) Line 4152  if (entry == NULL)
4152      common->entries = entry;      common->entries = entry;
4153    }    }
4154    
4155  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4156  allocate_stack(common, 1);    {
4157  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4158      allocate_stack(common, 2);
4159      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4160      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4161      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4162      }
4163    else if (common->has_set_som || common->mark_ptr != 0)
4164      {
4165      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4166      allocate_stack(common, 1);
4167      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4168      }
4169    
4170  if (entry->entry == NULL)  if (entry->entry == NULL)
4171    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
# Line 4076  jump_list *tmp = NULL; Line 4189  jump_list *tmp = NULL;
4189  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4190  jump_list **found;  jump_list **found;
4191  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4192    struct sljit_label *save_leavelabel = common->leavelabel;
4193  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4194    jump_list *save_leave = common->leave;
4195    jump_list *save_accept = common->accept;
4196  struct sljit_jump *jump;  struct sljit_jump *jump;
4197  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
4198    
4199  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4200    {    {
# Line 4124  else Line 4239  else
4239    }    }
4240    
4241  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
4242    common->leavelabel = NULL;
4243    common->leave = NULL;
4244  while (1)  while (1)
4245    {    {
4246    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4138  while (1) Line 4255  while (1)
4255    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
4256    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4257      {      {
4258        common->leavelabel = save_leavelabel;
4259      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4260        common->leave = save_leave;
4261      common->accept = save_accept;      common->accept = save_accept;
4262      return NULL;      return NULL;
4263      }      }
# Line 4191  while (1) Line 4310  while (1)
4310    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
4311    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4312      {      {
4313        common->leavelabel = save_leavelabel;
4314      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4315        common->leave = save_leave;
4316      common->accept = save_accept;      common->accept = save_accept;
4317      return NULL;      return NULL;
4318      }      }
# Line 4204  while (1) Line 4325  while (1)
4325    cc += GET(cc, 1);    cc += GET(cc, 1);
4326    }    }
4327  /* None of them matched. */  /* None of them matched. */
4328    if (common->leave != NULL)
4329      set_jumps(common->leave, LABEL());
4330    
4331  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
4332    {    {
# Line 4328  else Line 4451  else
4451      }      }
4452    }    }
4453    
4454    common->leavelabel = save_leavelabel;
4455  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
4456    common->leave = save_leave;
4457  common->accept = save_accept;  common->accept = save_accept;
4458  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4459  }  }
# Line 5519  while (cc < ccend) Line 5644  while (cc < ccend)
5644    
5645      case OP_SET_SOM:      case OP_SET_SOM:
5646      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5647        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5648      allocate_stack(common, 1);      allocate_stack(common, 1);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
5649      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
5650      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5651      cc++;      cc++;
5652      break;      break;
5653    
# Line 5687  while (cc < ccend) Line 5812  while (cc < ccend)
5812      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_hotpath(common, cc, parent);
5813      break;      break;
5814    
5815        case OP_MARK:
5816        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5817        SLJIT_ASSERT(common->mark_ptr != 0);
5818        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
5819        allocate_stack(common, 1);
5820        OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5821        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5822        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2));
5823        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
5824        OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
5825        cc += 1 + 2 + cc[1];
5826        break;
5827    
5828        case OP_COMMIT:
5829        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5830        cc += 1;
5831        break;
5832    
5833      case OP_FAIL:      case OP_FAIL:
5834      case OP_ACCEPT:      case OP_ACCEPT:
5835      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 5880  static void compile_recurse_fallbackpath Line 6023  static void compile_recurse_fallbackpath
6023  DEFINE_COMPILER;  DEFINE_COMPILER;
6024    
6025  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topfallbacks, LABEL());
6026  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6027  free_stack(common, 1);  if (common->has_set_som && common->mark_ptr != 0)
6028  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);    {
6029      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6030      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6031      free_stack(common, 2);
6032      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
6033      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6034      }
6035    else if (common->has_set_som || common->mark_ptr != 0)
6036      {
6037      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6038      free_stack(common, 1);
6039      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
6040      }
6041  }  }
6042    
6043  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
# Line 6518  while (current) Line 6673  while (current)
6673      compile_braminzero_fallbackpath(common, current);      compile_braminzero_fallbackpath(common, current);
6674      break;      break;
6675    
6676        case OP_MARK:
6677        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6678        free_stack(common, 1);
6679        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6680        break;
6681    
6682        case OP_COMMIT:
6683        OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6684        if (common->leavelabel == NULL)
6685          add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));
6686        else
6687          JUMPTO(SLJIT_JUMP, common->leavelabel);
6688        break;
6689    
6690      case OP_FAIL:      case OP_FAIL:
6691      case OP_ACCEPT:      case OP_ACCEPT:
6692      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 6543  int framesize = get_framesize(common, cc Line 6712  int framesize = get_framesize(common, cc
6712  int alternativesize;  int alternativesize;
6713  BOOL needsframe;  BOOL needsframe;
6714  fallback_common altfallback;  fallback_common altfallback;
6715    struct sljit_label *save_leavelabel = common->leavelabel;
6716    jump_list *save_leave = common->leave;
6717  struct sljit_jump *jump;  struct sljit_jump *jump;
6718    
6719  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
# Line 6561  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST Line 6732  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST
6732  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6733  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
6734  if (needsframe)  if (needsframe)
6735    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
6736    
6737  if (alternativesize > 0)  if (alternativesize > 0)
6738    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6739    
6740  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
6741    common->leavelabel = NULL;
6742  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6743    common->leave = NULL;
6744  common->accept = NULL;  common->accept = NULL;
6745  altfallback.cc = ccbegin;  altfallback.cc = ccbegin;
6746  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6581  while (1) Line 6754  while (1)
6754    
6755    compile_hotpath(common, altfallback.cc, cc, &altfallback);    compile_hotpath(common, altfallback.cc, cc, &altfallback);
6756    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6757        {
6758        common->leavelabel = save_leavelabel;
6759        common->leave = save_leave;
6760      return;      return;
6761        }
6762    
6763    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6764    
6765    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
6766    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6767        {
6768        common->leavelabel = save_leavelabel;
6769        common->leave = save_leave;
6770      return;      return;
6771        }
6772    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altfallback.topfallbacks, LABEL());
6773    
6774    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 6597  while (1) Line 6778  while (1)
6778    cc += GET(cc, 1);    cc += GET(cc, 1);
6779    }    }
6780  /* None of them matched. */  /* None of them matched. */
6781    if (common->leave != NULL)
6782      set_jumps(common->leave, LABEL());
6783    
6784  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6785  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6786    
# Line 6604  set_jumps(common->accept, LABEL()); Line 6788  set_jumps(common->accept, LABEL());
6788  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);
6789  if (needsframe)  if (needsframe)
6790    {    {
   OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
6791    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6792    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6793    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);  
6794    }    }
6795  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
6796    
# Line 6619  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK Line 6801  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK
6801  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6802  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
6803  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6804    
6805    common->leavelabel = save_leavelabel;
6806    common->leave = save_leave;
6807  }  }
6808    
6809  #undef COMPILE_FALLBACKPATH  #undef COMPILE_FALLBACKPATH
# Line 6637  pcre_uchar *ccend; Line 6822  pcre_uchar *ccend;
6822  executable_functions *functions;  executable_functions *functions;
6823  void *executable_func;  void *executable_func;
6824  sljit_uw executable_size;  sljit_uw executable_size;
 struct sljit_label *leave;  
6825  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6826  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6827  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
# Line 6799  if (mode == JIT_COMPILE && (re->flags & Line 6983  if (mode == JIT_COMPILE && (re->flags &
6983  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
6984  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6985  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6986    if (common->mark_ptr != 0)
6987      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
6988  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
6989  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6990    {    {
# Line 6826  if (common->accept != NULL) Line 7012  if (common->accept != NULL)
7012    
7013  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7014  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7015  leave = LABEL();  common->leavelabel = LABEL();
7016    if (common->leave != NULL)
7017      set_jumps(common->leave, common->leavelabel);
7018  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7019    
7020  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
7021    {    {
7022    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
7023    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
7024    return_with_partial_match(common, leave);    return_with_partial_match(common, common->leavelabel);
7025    }    }
7026    
7027  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6866  if ((re->options & PCRE_ANCHORED) == 0) Line 7054  if ((re->options & PCRE_ANCHORED) == 0)
7054      {      {
7055      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
7056        {        {
7057        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
7058        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
7059        }        }
7060      else      else
# Line 6877  if ((re->options & PCRE_ANCHORED) == 0) Line 7065  if ((re->options & PCRE_ANCHORED) == 0)
7065      SLJIT_ASSERT(common->first_line_end != 0);      SLJIT_ASSERT(common->first_line_end != 0);
7066      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
7067        {        {
7068        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
7069        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
7070        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
7071        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
# Line 6897  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7085  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7085    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
7086    
7087  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7088  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7089    
7090  flush_stubs(common);  flush_stubs(common);
7091    
# Line 6950  sljit_emit_fast_return(compiler, SLJIT_M Line 7138  sljit_emit_fast_return(compiler, SLJIT_M
7138  JUMPHERE(jump);  JUMPHERE(jump);
7139  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
7140  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
7141  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7142    
7143  /* Call limit reached. */  /* Call limit reached. */
7144  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
7145  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7146  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7147    
7148  if (common->revertframes != NULL)  if (common->revertframes != NULL)
7149    {    {
# Line 7062  return convert_executable_func.call_exec Line 7250  return convert_executable_func.call_exec
7250  }  }
7251    
7252  int  int
7253  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs,  PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject,
7254    const pcre_uchar *subject, int length, int start_offset, int options,    int length, int start_offset, int options, int *offsets, int offsetcount)
   int match_limit, int *offsets, int offsetcount)  
7255  {  {
7256  executable_functions *functions = (executable_functions *)executable_funcs;  executable_functions *functions = (executable_functions *)extra_data->executable_jit;
7257  union {  union {
7258     void* executable_func;     void* executable_func;
7259     jit_function call_executable_func;     jit_function call_executable_func;
# Line 7089  arguments.stack = NULL; Line 7276  arguments.stack = NULL;
7276  arguments.str = subject + start_offset;  arguments.str = subject + start_offset;
7277  arguments.begin = subject;  arguments.begin = subject;
7278  arguments.end = subject + length;  arguments.end = subject + length;
7279  arguments.calllimit = match_limit; /* JIT decreases this value less times. */  arguments.mark_ptr = NULL;
7280    /* JIT decreases this value less frequently than the interpreter. */
7281    arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
7282  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
7283  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
7284  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 7124  else Line 7313  else
7313    
7314  if (retval * 2 > offsetcount)  if (retval * 2 > offsetcount)
7315    retval = 0;    retval = 0;
7316    if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
7317      *(extra_data->mark) = arguments.mark_ptr;
7318    
7319  return retval;  return retval;
7320  }  }
7321    

Legend:
Removed from v.924  
changed lines
  Added in v.941

  ViewVC Help
Powered by ViewVC 1.1.5