/[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 1627 by zherczeg, Tue Feb 9 08:55:32 2016 UTC revision 1629 by zherczeg, Tue Feb 9 14:22:55 2016 UTC
# Line 424  typedef struct compiler_common { Line 424  typedef struct compiler_common {
424    BOOL utf;    BOOL utf;
425  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
426    BOOL use_ucp;    BOOL use_ucp;
427      jump_list *getucd;
428  #endif  #endif
429  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
430    jump_list *utfreadchar;    jump_list *utfreadchar;
# Line 431  typedef struct compiler_common { Line 432  typedef struct compiler_common {
432    jump_list *utfreadtype8;    jump_list *utfreadtype8;
433  #endif  #endif
434  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
 #ifdef SUPPORT_UCP  
   jump_list *getucd;  
 #endif  
435  } compiler_common;  } compiler_common;
436    
437  /* For byte_sequence_compare. */  /* For byte_sequence_compare. */
# Line 2578  else Line 2576  else
2576  JUMPHERE(jump);  JUMPHERE(jump);
2577  }  }
2578    
2579  static void peek_char(compiler_common *common, pcre_uint32 max)  static void peek_char(compiler_common *common, sljit_ui max)
2580  {  {
2581  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2582  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
# Line 2623  if (common->utf) Line 2621  if (common->utf)
2621    
2622  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2623    
2624  static BOOL is_char7_bitset(const pcre_uint8 *bitset, BOOL nclass)  static BOOL is_char7_bitset(const sljit_ub *bitset, BOOL nclass)
2625  {  {
2626  /* Tells whether the character codes below 128 are enough  /* Tells whether the character codes below 128 are enough
2627  to determine a match. */  to determine a match. */
# Line 2666  if (full_read) Line 2664  if (full_read)
2664    
2665  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2666    
2667  static void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr)  static void read_char_range(compiler_common *common, sljit_ui min, sljit_ui max, BOOL update_str_ptr)
2668  {  {
2669  /* Reads the precise value of a character into TMP1, if the character is  /* Reads the precise value of a character into TMP1, if the character is
2670  between min and max (c >= min && c <= max). Otherwise it returns with a value  between min and max (c >= min && c <= max). Otherwise it returns with a value
# Line 3575  while (TRUE) Line 3573  while (TRUE)
3573    }    }
3574  }  }
3575    
3576    #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
3577    
3578    static sljit_si character_to_int32(pcre_uchar chr)
3579    {
3580    sljit_si value = (sljit_si)chr;
3581    #if defined COMPILE_PCRE8
3582    #define SSE2_COMPARE_TYPE_INDEX 0
3583    return (value << 24) | (value << 16) | (value << 8) | value;
3584    #elif defined COMPILE_PCRE16
3585    #define SSE2_COMPARE_TYPE_INDEX 1
3586    return (value << 16) | value;
3587    #elif defined COMPILE_PCRE32
3588    #define SSE2_COMPARE_TYPE_INDEX 2
3589    return value;
3590    #else
3591    #error "Unsupported unit width"
3592    #endif
3593    }
3594    
3595    static SLJIT_INLINE void fast_forward_first_char2_sse2(compiler_common *common, pcre_uchar char1, pcre_uchar char2)
3596    {
3597    DEFINE_COMPILER;
3598    struct sljit_label *start;
3599    struct sljit_jump *quit[3];
3600    struct sljit_jump *nomatch;
3601    sljit_ub instruction[8];
3602    sljit_si tmp1_ind = sljit_get_register_index(TMP1);
3603    sljit_si tmp2_ind = sljit_get_register_index(TMP2);
3604    sljit_si str_ptr_ind = sljit_get_register_index(STR_PTR);
3605    BOOL load_twice = FALSE;
3606    pcre_uchar bit;
3607    
3608    bit = char1 ^ char2;
3609    if (!is_powerof2(bit))
3610      bit = 0;
3611    
3612    if ((char1 != char2) && bit == 0)
3613      load_twice = TRUE;
3614    
3615    quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3616    
3617    /* First part (unaligned start) */
3618    
3619    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
3620    
3621    SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1);
3622    
3623    /* MOVD xmm, r/m32 */
3624    instruction[0] = 0x66;
3625    instruction[1] = 0x0f;
3626    instruction[2] = 0x6e;
3627    instruction[3] = 0xc0 | (2 << 3) | tmp1_ind;
3628    sljit_emit_op_custom(compiler, instruction, 4);
3629    
3630    if (char1 != char2)
3631      {
3632      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
3633    
3634      /* MOVD xmm, r/m32 */
3635      instruction[3] = 0xc0 | (3 << 3) | tmp1_ind;
3636      sljit_emit_op_custom(compiler, instruction, 4);
3637      }
3638    
3639    /* PSHUFD xmm1, xmm2/m128, imm8 */
3640    instruction[2] = 0x70;
3641    instruction[3] = 0xc0 | (2 << 3) | 2;
3642    instruction[4] = 0;
3643    sljit_emit_op_custom(compiler, instruction, 5);
3644    
3645    if (char1 != char2)
3646      {
3647      /* PSHUFD xmm1, xmm2/m128, imm8 */
3648      instruction[3] = 0xc0 | (3 << 3) | 3;
3649      instruction[4] = 0;
3650      sljit_emit_op_custom(compiler, instruction, 5);
3651      }
3652    
3653    OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 0xf);
3654    OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
3655    
3656    /* MOVDQA xmm1, xmm2/m128 */
3657    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
3658    
3659    if (str_ptr_ind < 8)
3660      {
3661      instruction[2] = 0x6f;
3662      instruction[3] = (0 << 3) | str_ptr_ind;
3663      sljit_emit_op_custom(compiler, instruction, 4);
3664    
3665      if (load_twice)
3666        {
3667        instruction[3] = (1 << 3) | str_ptr_ind;
3668        sljit_emit_op_custom(compiler, instruction, 4);
3669        }
3670      }
3671    else
3672      {
3673      instruction[1] = 0x41;
3674      instruction[2] = 0x0f;
3675      instruction[3] = 0x6f;
3676      instruction[4] = (0 << 3) | (str_ptr_ind & 0x7);
3677      sljit_emit_op_custom(compiler, instruction, 5);
3678    
3679      if (load_twice)
3680        {
3681        instruction[4] = (1 << 3) | str_ptr_ind;
3682        sljit_emit_op_custom(compiler, instruction, 5);
3683        }
3684      instruction[1] = 0x0f;
3685      }
3686    
3687    #else
3688    
3689    instruction[2] = 0x6f;
3690    instruction[3] = (0 << 3) | str_ptr_ind;
3691    sljit_emit_op_custom(compiler, instruction, 4);
3692    
3693    if (load_twice)
3694      {
3695      instruction[3] = (1 << 3) | str_ptr_ind;
3696      sljit_emit_op_custom(compiler, instruction, 4);
3697      }
3698    
3699    #endif
3700    
3701    if (bit != 0)
3702      {
3703      /* POR xmm1, xmm2/m128 */
3704      instruction[2] = 0xeb;
3705      instruction[3] = 0xc0 | (0 << 3) | 3;
3706      sljit_emit_op_custom(compiler, instruction, 4);
3707      }
3708    
3709    /* PCMPEQB/W/D xmm1, xmm2/m128 */
3710    instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
3711    instruction[3] = 0xc0 | (0 << 3) | 2;
3712    sljit_emit_op_custom(compiler, instruction, 4);
3713    
3714    if (load_twice)
3715      {
3716      instruction[3] = 0xc0 | (1 << 3) | 3;
3717      sljit_emit_op_custom(compiler, instruction, 4);
3718      }
3719    
3720    /* PMOVMSKB reg, xmm */
3721    instruction[2] = 0xd7;
3722    instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
3723    sljit_emit_op_custom(compiler, instruction, 4);
3724    
3725    if (load_twice)
3726      {
3727      OP1(SLJIT_MOV, TMP3, 0, TMP2, 0);
3728      instruction[3] = 0xc0 | (tmp2_ind << 3) | 1;
3729      sljit_emit_op_custom(compiler, instruction, 4);
3730    
3731      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3732      OP1(SLJIT_MOV, TMP2, 0, TMP3, 0);
3733      }
3734    
3735    OP2(SLJIT_ASHR, TMP1, 0, TMP1, 0, TMP2, 0);
3736    
3737    /* BSF r32, r/m32 */
3738    instruction[0] = 0x0f;
3739    instruction[1] = 0xbc;
3740    instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
3741    sljit_emit_op_custom(compiler, instruction, 3);
3742    
3743    nomatch = JUMP(SLJIT_ZERO);
3744    
3745    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3746    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3747    quit[1] = JUMP(SLJIT_JUMP);
3748    
3749    JUMPHERE(nomatch);
3750    
3751    start = LABEL();
3752    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
3753    quit[2] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3754    
3755    /* Second part (aligned) */
3756    
3757    instruction[0] = 0x66;
3758    instruction[1] = 0x0f;
3759    
3760    /* MOVDQA xmm1, xmm2/m128 */
3761    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
3762    
3763    if (str_ptr_ind < 8)
3764      {
3765      instruction[2] = 0x6f;
3766      instruction[3] = (0 << 3) | str_ptr_ind;
3767      sljit_emit_op_custom(compiler, instruction, 4);
3768    
3769      if (load_twice)
3770        {
3771        instruction[3] = (1 << 3) | str_ptr_ind;
3772        sljit_emit_op_custom(compiler, instruction, 4);
3773        }
3774      }
3775    else
3776      {
3777      instruction[1] = 0x41;
3778      instruction[2] = 0x0f;
3779      instruction[3] = 0x6f;
3780      instruction[4] = (0 << 3) | (str_ptr_ind & 0x7);
3781      sljit_emit_op_custom(compiler, instruction, 5);
3782    
3783      if (load_twice)
3784        {
3785        instruction[4] = (1 << 3) | str_ptr_ind;
3786        sljit_emit_op_custom(compiler, instruction, 5);
3787        }
3788      instruction[1] = 0x0f;
3789      }
3790    
3791    #else
3792    
3793    instruction[2] = 0x6f;
3794    instruction[3] = (0 << 3) | str_ptr_ind;
3795    sljit_emit_op_custom(compiler, instruction, 4);
3796    
3797    if (load_twice)
3798      {
3799      instruction[3] = (1 << 3) | str_ptr_ind;
3800      sljit_emit_op_custom(compiler, instruction, 4);
3801      }
3802    
3803    #endif
3804    
3805    if (bit != 0)
3806      {
3807      /* POR xmm1, xmm2/m128 */
3808      instruction[2] = 0xeb;
3809      instruction[3] = 0xc0 | (0 << 3) | 3;
3810      sljit_emit_op_custom(compiler, instruction, 4);
3811      }
3812    
3813    /* PCMPEQB/W/D xmm1, xmm2/m128 */
3814    instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
3815    instruction[3] = 0xc0 | (0 << 3) | 2;
3816    sljit_emit_op_custom(compiler, instruction, 4);
3817    
3818    if (load_twice)
3819      {
3820      instruction[3] = 0xc0 | (1 << 3) | 3;
3821      sljit_emit_op_custom(compiler, instruction, 4);
3822      }
3823    
3824    /* PMOVMSKB reg, xmm */
3825    instruction[2] = 0xd7;
3826    instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
3827    sljit_emit_op_custom(compiler, instruction, 4);
3828    
3829    if (load_twice)
3830      {
3831      instruction[3] = 0xc0 | (tmp2_ind << 3) | 1;
3832      sljit_emit_op_custom(compiler, instruction, 4);
3833    
3834      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3835      }
3836    
3837    /* BSF r32, r/m32 */
3838    instruction[0] = 0x0f;
3839    instruction[1] = 0xbc;
3840    instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
3841    sljit_emit_op_custom(compiler, instruction, 3);
3842    
3843    JUMPTO(SLJIT_ZERO, start);
3844    
3845    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3846    
3847    start = LABEL();
3848    SET_LABEL(quit[0], start);
3849    SET_LABEL(quit[1], start);
3850    SET_LABEL(quit[2], start);
3851    }
3852    
3853    #undef SSE2_COMPARE_TYPE_INDEX
3854    
3855    #endif
3856    
3857    static void fast_forward_first_char2(compiler_common *common, pcre_uchar char1, pcre_uchar char2, sljit_si offset)
3858    {
3859    DEFINE_COMPILER;
3860    struct sljit_label *start;
3861    struct sljit_jump *quit;
3862    struct sljit_jump *found;
3863    pcre_uchar mask;
3864    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3865    struct sljit_label *utf_start = NULL;
3866    struct sljit_jump *utf_quit = NULL;
3867    #endif
3868    BOOL has_first_line_end = (common->first_line_end != 0);
3869    
3870    if (offset > 0)
3871      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
3872    
3873    if (has_first_line_end)
3874      {
3875      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3876    
3877      OP2(SLJIT_ADD, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end, SLJIT_IMM, IN_UCHARS(offset + 1));
3878    #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
3879      if (sljit_x86_is_cmov_available())
3880        {
3881        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_END, 0, TMP3, 0);
3882        sljit_x86_emit_cmov(compiler, SLJIT_GREATER, STR_END, TMP3, 0);
3883        }
3884    #endif
3885        {
3886        quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP3, 0);
3887        OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3888        JUMPHERE(quit);
3889        }
3890      }
3891    
3892    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3893    if (common->utf && offset > 0)
3894      utf_start = LABEL();
3895    #endif
3896    
3897    #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
3898    
3899    /* SSE2 accelerated first character search. */
3900    
3901    if (sljit_x86_is_sse2_available())
3902      {
3903      fast_forward_first_char2_sse2(common, char1, char2);
3904    
3905      SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0);
3906      if (common->mode == JIT_COMPILE)
3907        {
3908        /* In complete mode, we don't need to run a match when STR_PTR == STR_END. */
3909        SLJIT_ASSERT(common->forced_quit_label == NULL);
3910        OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
3911        add_jump(compiler, &common->forced_quit, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
3912    
3913    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3914        if (common->utf && offset > 0)
3915          {
3916          SLJIT_ASSERT(common->mode == JIT_COMPILE);
3917    
3918          OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
3919          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3920    #if defined COMPILE_PCRE8
3921          OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
3922          CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start);
3923    #elif defined COMPILE_PCRE16
3924          OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3925          CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start);
3926    #else
3927    #error "Unknown code width"
3928    #endif
3929          OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3930          }
3931    #endif
3932    
3933        if (offset > 0)
3934          OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
3935        }
3936      else if (sljit_x86_is_cmov_available())
3937        {
3938        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
3939        sljit_x86_emit_cmov(compiler, SLJIT_GREATER_EQUAL, STR_PTR, has_first_line_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_first_line_end ? common->first_line_end : 0);
3940        }
3941      else
3942        {
3943        quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
3944        OP1(SLJIT_MOV, STR_PTR, 0, has_first_line_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_first_line_end ? common->first_line_end : 0);
3945        JUMPHERE(quit);
3946        }
3947    
3948      if (has_first_line_end)
3949        OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3950      return;
3951      }
3952    
3953    #endif
3954    
3955    quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3956    
3957    start = LABEL();
3958    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3959    
3960    if (char1 == char2)
3961      found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);
3962    else
3963      {
3964      mask = char1 ^ char2;
3965      if (is_powerof2(mask))
3966        {
3967        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
3968        found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask);
3969        }
3970      else
3971        {
3972        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char1);
3973        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
3974        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char2);
3975        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
3976        found = JUMP(SLJIT_NOT_ZERO);
3977        }
3978      }
3979    
3980    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3981    CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, start);
3982    
3983    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3984    if (common->utf && offset > 0)
3985      utf_quit = JUMP(SLJIT_JUMP);
3986    #endif
3987    
3988    JUMPHERE(found);
3989    
3990    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3991    if (common->utf && offset > 0)
3992      {
3993      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
3994      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3995    #if defined COMPILE_PCRE8
3996      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
3997      CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start);
3998    #elif defined COMPILE_PCRE16
3999      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4000      CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start);
4001    #else
4002    #error "Unknown code width"
4003    #endif
4004      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4005      JUMPHERE(utf_quit);
4006      }
4007    #endif
4008    
4009    JUMPHERE(quit);
4010    
4011    if (has_first_line_end)
4012      {
4013      quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
4014      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
4015      if (offset > 0)
4016        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
4017      JUMPHERE(quit);
4018      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4019      }
4020    
4021    if (offset > 0)
4022      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
4023    }
4024    
4025  static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)  static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
4026  {  {
4027  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 3819  return TRUE; Line 4266  return TRUE;
4266  #undef MAX_N_CHARS  #undef MAX_N_CHARS
4267  #undef MAX_N_BYTES  #undef MAX_N_BYTES
4268    
4269  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless)
4270  {  {
4271  DEFINE_COMPILER;  pcre_uchar oc;
 struct sljit_label *start;  
 struct sljit_jump *quit;  
 struct sljit_jump *found;  
 pcre_uchar oc, bit;  
   
 if (firstline)  
   {  
   SLJIT_ASSERT(common->first_line_end != 0);  
   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);  
   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);  
   }  
   
 start = LABEL();  
 quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
4272    
4273  oc = first_char;  oc = first_char;
4274  if (caseless)  if (caseless)
4275    {    {
4276    oc = TABLE_GET(first_char, common->fcc, first_char);    oc = TABLE_GET(first_char, common->fcc, first_char);
4277  #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)  #if defined SUPPORT_UTF && !defined COMPILE_PCRE8
4278    if (first_char > 127 && common->utf)    if (first_char > 127 && common->utf)
4279      oc = UCD_OTHERCASE(first_char);      oc = UCD_OTHERCASE(first_char);
4280  #endif  #endif
4281    }    }
 if (first_char == oc)  
   found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, first_char);  
 else  
   {  
   bit = first_char ^ oc;  
   if (is_powerof2(bit))  
     {  
     OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);  
     found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);  
     }  
   else  
     {  
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);  
     OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);  
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);  
     OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);  
     found = JUMP(SLJIT_NOT_ZERO);  
     }  
   }  
   
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 JUMPTO(SLJIT_JUMP, start);  
 JUMPHERE(found);  
 JUMPHERE(quit);  
4282    
4283  if (firstline)  fast_forward_first_char2(common, first_char, oc, 0);
   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);  
4284  }  }
4285    
4286  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common)
4287  {  {
4288  DEFINE_COMPILER;  DEFINE_COMPILER;
4289  struct sljit_label *loop;  struct sljit_label *loop;
# Line 3887  struct sljit_jump *foundcr = NULL; Line 4294  struct sljit_jump *foundcr = NULL;
4294  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
4295  jump_list *newline = NULL;  jump_list *newline = NULL;
4296    
4297  if (firstline)  if (common->first_line_end != 0)
4298    {    {
   SLJIT_ASSERT(common->first_line_end != 0);  
4299    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
4300    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
4301    }    }
# Line 3922  if (common->nltype == NLTYPE_FIXED && co Line 4328  if (common->nltype == NLTYPE_FIXED && co
4328    JUMPHERE(firstchar);    JUMPHERE(firstchar);
4329    JUMPHERE(lastchar);    JUMPHERE(lastchar);
4330    
4331    if (firstline)    if (common->first_line_end != 0)
4332      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4333    return;    return;
4334    }    }
# Line 3960  if (common->nltype == NLTYPE_ANY || comm Line 4366  if (common->nltype == NLTYPE_ANY || comm
4366  JUMPHERE(lastchar);  JUMPHERE(lastchar);
4367  JUMPHERE(firstchar);  JUMPHERE(firstchar);
4368    
4369  if (firstline)  if (common->first_line_end != 0)
4370    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4371  }  }
4372    
4373  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
4374    
4375  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, pcre_uint8 *start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_ub *start_bits)
4376  {  {
4377  DEFINE_COMPILER;  DEFINE_COMPILER;
4378  struct sljit_label *start;  struct sljit_label *start;
# Line 3977  jump_list *matches = NULL; Line 4383  jump_list *matches = NULL;
4383  struct sljit_jump *jump;  struct sljit_jump *jump;
4384  #endif  #endif
4385    
4386  if (firstline)  if (common->first_line_end != 0)
4387    {    {
   SLJIT_ASSERT(common->first_line_end != 0);  
4388    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
4389    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
4390    }    }
# Line 4039  if (matches != NULL) Line 4444  if (matches != NULL)
4444    set_jumps(matches, LABEL());    set_jumps(matches, LABEL());
4445  JUMPHERE(quit);  JUMPHERE(quit);
4446    
4447  if (firstline)  if (common->first_line_end != 0)
4448    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
4449  }  }
4450    
# Line 7646  while (*cc == OP_ALT) Line 8051  while (*cc == OP_ALT)
8051    cc += GET(cc, 1);    cc += GET(cc, 1);
8052  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
8053    
 /* Temporarily encoding the needs_control_head in framesize. */  
8054  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
8055      {
8056      /* We temporarily encode the needs_control_head in the lowest bit.
8057         Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns
8058         the same value for small signed numbers (including negative numbers). */
8059    BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);    BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
8060      }
8061  return cc + repeat_length;  return cc + repeat_length;
8062  }  }
8063    
# Line 10156  if ((re->options & PCRE_ANCHORED) == 0) Line 10565  if ((re->options & PCRE_ANCHORED) == 0)
10565      if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))      if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
10566        ;        ;
10567      else if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
10568        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0);
10569      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
10570        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common);
10571      else if (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)      else if (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
10572        fast_forward_start_bits(common, study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_start_bits(common, study->start_bits);
10573      }      }
10574    }    }
10575  else  else

Legend:
Removed from v.1627  
changed lines
  Added in v.1629

  ViewVC Help
Powered by ViewVC 1.1.5