1/************************************************* 2* Perl-Compatible Regular Expressions * 3*************************************************/ 4 5/* PCRE is a library of functions to support regular expressions whose syntax 6and semantics are as close as possible to those of the Perl 5 language. 7 8 Written by Philip Hazel 9 Copyright (c) 1997-2012 University of Cambridge 10 11 The machine code generator part (this module) was written by Zoltan Herczeg 12 Copyright (c) 2010-2012 13 14----------------------------------------------------------------------------- 15Redistribution and use in source and binary forms, with or without 16modification, are permitted provided that the following conditions are met: 17 18 * Redistributions of source code must retain the above copyright notice, 19 this list of conditions and the following disclaimer. 20 21 * Redistributions in binary form must reproduce the above copyright 22 notice, this list of conditions and the following disclaimer in the 23 documentation and/or other materials provided with the distribution. 24 25 * Neither the name of the University of Cambridge nor the names of its 26 contributors may be used to endorse or promote products derived from 27 this software without specific prior written permission. 28 29THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 30AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 33LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 34CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 35SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 36INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 37CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39POSSIBILITY OF SUCH DAMAGE. 40----------------------------------------------------------------------------- 41*/ 42 43#ifdef HAVE_CONFIG_H 44#include "config.h" 45#endif 46 47#include "pcre_internal.h" 48 49#ifdef SUPPORT_JIT 50 51/* All-in-one: Since we use the JIT compiler only from here, 52we just include it. This way we don't need to touch the build 53system files. */ 54 55#define SLJIT_MALLOC(size) (PUBL(malloc))(size) 56#define SLJIT_FREE(ptr) (PUBL(free))(ptr) 57#define SLJIT_CONFIG_AUTO 1 58#define SLJIT_CONFIG_STATIC 1 59#define SLJIT_VERBOSE 0 60#define SLJIT_DEBUG 0 61 62#include "sljit/sljitLir.c" 63 64#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED 65#error Unsupported architecture 66#endif 67 68/* Allocate memory on the stack. Fast, but limited size. */ 69#define LOCAL_SPACE_SIZE 32768 70 71#define STACK_GROWTH_RATE 8192 72 73/* Enable to check that the allocation could destroy temporaries. */ 74#if defined SLJIT_DEBUG && SLJIT_DEBUG 75#define DESTROY_REGISTERS 1 76#endif 77 78/* 79Short summary about the backtracking mechanism empolyed by the jit code generator: 80 81The code generator follows the recursive nature of the PERL compatible regular 82expressions. The basic blocks of regular expressions are condition checkers 83whose execute different commands depending on the result of the condition check. 84The relationship between the operators can be horizontal (concatenation) and 85vertical (sub-expression) (See struct backtrack_common for more details). 86 87 'ab' - 'a' and 'b' regexps are concatenated 88 'a+' - 'a' is the sub-expression of the '+' operator 89 90The condition checkers are boolean (true/false) checkers. Machine code is generated 91for the checker itself and for the actions depending on the result of the checker. 92The 'true' case is called as the try path (expected path), and the other is called as 93the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken 94branches on the try path. 95 96 Greedy star operator (*) : 97 Try path: match happens. 98 Backtrack path: match failed. 99 Non-greedy star operator (*?) : 100 Try path: no need to perform a match. 101 Backtrack path: match is required. 102 103The following example shows how the code generated for a capturing bracket 104with two alternatives. Let A, B, C, D are arbirary regular expressions, and 105we have the following regular expression: 106 107 A(B|C)D 108 109The generated code will be the following: 110 111 A try path 112 '(' try path (pushing arguments to the stack) 113 B try path 114 ')' try path (pushing arguments to the stack) 115 D try path 116 return with successful match 117 118 D backtrack path 119 ')' backtrack path (If we arrived from "C" jump to the backtrack of "C") 120 B backtrack path 121 C expected path 122 jump to D try path 123 C backtrack path 124 A backtrack path 125 126 Notice, that the order of backtrack code paths are the opposite of the fast 127 code paths. In this way the topmost value on the stack is always belong 128 to the current backtrack code path. The backtrack path must check 129 whether there is a next alternative. If so, it needs to jump back to 130 the try path eventually. Otherwise it needs to clear out its own stack 131 frame and continue the execution on the backtrack code paths. 132*/ 133 134/* 135Saved stack frames: 136 137Atomic blocks and asserts require reloading the values of local variables 138when the backtrack mechanism performed. Because of OP_RECURSE, the locals 139are not necessarly known in compile time, thus we need a dynamic restore 140mechanism. 141 142The stack frames are stored in a chain list, and have the following format: 143([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ] 144 145Thus we can restore the locals to a particular point in the stack. 146*/ 147 148typedef struct jit_arguments { 149 /* Pointers first. */ 150 struct sljit_stack *stack; 151 const pcre_uchar *str; 152 const pcre_uchar *begin; 153 const pcre_uchar *end; 154 int *offsets; 155 pcre_uchar *uchar_ptr; 156 pcre_uchar *mark_ptr; 157 /* Everything else after. */ 158 int offsetcount; 159 int calllimit; 160 pcre_uint8 notbol; 161 pcre_uint8 noteol; 162 pcre_uint8 notempty; 163 pcre_uint8 notempty_atstart; 164} jit_arguments; 165 166typedef struct executable_functions { 167 void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; 168 PUBL(jit_callback) callback; 169 void *userdata; 170 sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; 171} executable_functions; 172 173typedef struct jump_list { 174 struct sljit_jump *jump; 175 struct jump_list *next; 176} jump_list; 177 178enum stub_types { stack_alloc }; 179 180typedef struct stub_list { 181 enum stub_types type; 182 int data; 183 struct sljit_jump *start; 184 struct sljit_label *leave; 185 struct stub_list *next; 186} stub_list; 187 188typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); 189 190/* The following structure is the key data type for the recursive 191code generator. It is allocated by compile_trypath, and contains 192the aguments for compile_backtrackpath. Must be the first member 193of its descendants. */ 194typedef struct backtrack_common { 195 /* Concatenation stack. */ 196 struct backtrack_common *prev; 197 jump_list *nextbacktracks; 198 /* Internal stack (for component operators). */ 199 struct backtrack_common *top; 200 jump_list *topbacktracks; 201 /* Opcode pointer. */ 202 pcre_uchar *cc; 203} backtrack_common; 204 205typedef struct assert_backtrack { 206 backtrack_common common; 207 jump_list *condfailed; 208 /* Less than 0 (-1) if a frame is not needed. */ 209 int framesize; 210 /* Points to our private memory word on the stack. */ 211 int localptr; 212 /* For iterators. */ 213 struct sljit_label *trypath; 214} assert_backtrack; 215 216typedef struct bracket_backtrack { 217 backtrack_common common; 218 /* Where to coninue if an alternative is successfully matched. */ 219 struct sljit_label *alttrypath; 220 /* For rmin and rmax iterators. */ 221 struct sljit_label *recursivetrypath; 222 /* For greedy ? operator. */ 223 struct sljit_label *zerotrypath; 224 /* Contains the branches of a failed condition. */ 225 union { 226 /* Both for OP_COND, OP_SCOND. */ 227 jump_list *condfailed; 228 assert_backtrack *assert; 229 /* For OP_ONCE. -1 if not needed. */ 230 int framesize; 231 } u; 232 /* Points to our private memory word on the stack. */ 233 int localptr; 234} bracket_backtrack; 235 236typedef struct bracketpos_backtrack { 237 backtrack_common common; 238 /* Points to our private memory word on the stack. */ 239 int localptr; 240 /* Reverting stack is needed. */ 241 int framesize; 242 /* Allocated stack size. */ 243 int stacksize; 244} bracketpos_backtrack; 245 246typedef struct braminzero_backtrack { 247 backtrack_common common; 248 struct sljit_label *trypath; 249} braminzero_backtrack; 250 251typedef struct iterator_backtrack { 252 backtrack_common common; 253 /* Next iteration. */ 254 struct sljit_label *trypath; 255} iterator_backtrack; 256 257typedef struct recurse_entry { 258 struct recurse_entry *next; 259 /* Contains the function entry. */ 260 struct sljit_label *entry; 261 /* Collects the calls until the function is not created. */ 262 jump_list *calls; 263 /* Points to the starting opcode. */ 264 int start; 265} recurse_entry; 266 267typedef struct recurse_backtrack { 268 backtrack_common common; 269} recurse_backtrack; 270 271typedef struct compiler_common { 272 struct sljit_compiler *compiler; 273 pcre_uchar *start; 274 275 /* Opcode local area direct map. */ 276 int *localptrs; 277 int cbraptr; 278 /* OVector starting point. Must be divisible by 2. */ 279 int ovector_start; 280 /* Last known position of the requested byte. */ 281 int req_char_ptr; 282 /* Head of the last recursion. */ 283 int recursive_head; 284 /* First inspected character for partial matching. */ 285 int start_used_ptr; 286 /* Starting pointer for partial soft matches. */ 287 int hit_start; 288 /* End pointer of the first line. */ 289 int first_line_end; 290 /* Points to the marked string. */ 291 int mark_ptr; 292 293 /* Other */ 294 const pcre_uint8 *fcc; 295 sljit_w lcc; 296 int mode; 297 int nltype; 298 int newline; 299 int bsr_nltype; 300 int endonly; 301 BOOL has_set_som; 302 sljit_w ctypes; 303 sljit_uw name_table; 304 sljit_w name_count; 305 sljit_w name_entry_size; 306 307 /* Labels and jump lists. */ 308 struct sljit_label *partialmatchlabel; 309 struct sljit_label *leavelabel; 310 struct sljit_label *acceptlabel; 311 stub_list *stubs; 312 recurse_entry *entries; 313 recurse_entry *currententry; 314 jump_list *partialmatch; 315 jump_list *leave; 316 jump_list *accept; 317 jump_list *calllimit; 318 jump_list *stackalloc; 319 jump_list *revertframes; 320 jump_list *wordboundary; 321 jump_list *anynewline; 322 jump_list *hspace; 323 jump_list *vspace; 324 jump_list *casefulcmp; 325 jump_list *caselesscmp; 326 BOOL jscript_compat; 327#ifdef SUPPORT_UTF 328 BOOL utf; 329#ifdef SUPPORT_UCP 330 BOOL use_ucp; 331#endif 332 jump_list *utfreadchar; 333#ifdef COMPILE_PCRE8 334 jump_list *utfreadtype8; 335#endif 336#endif /* SUPPORT_UTF */ 337#ifdef SUPPORT_UCP 338 jump_list *getucd; 339#endif 340} compiler_common; 341 342/* For byte_sequence_compare. */ 343 344typedef struct compare_context { 345 int length; 346 int sourcereg; 347#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 348 int ucharptr; 349 union { 350 sljit_i asint; 351 sljit_uh asushort; 352#ifdef COMPILE_PCRE8 353 sljit_ub asbyte; 354 sljit_ub asuchars[4]; 355#else 356#ifdef COMPILE_PCRE16 357 sljit_uh asuchars[2]; 358#endif 359#endif 360 } c; 361 union { 362 sljit_i asint; 363 sljit_uh asushort; 364#ifdef COMPILE_PCRE8 365 sljit_ub asbyte; 366 sljit_ub asuchars[4]; 367#else 368#ifdef COMPILE_PCRE16 369 sljit_uh asuchars[2]; 370#endif 371#endif 372 } oc; 373#endif 374} compare_context; 375 376enum { 377 frame_end = 0, 378 frame_setstrbegin = -1, 379 frame_setmark = -2 380}; 381 382/* Undefine sljit macros. */ 383#undef CMP 384 385/* Used for accessing the elements of the stack. */ 386#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) 387 388#define TMP1 SLJIT_TEMPORARY_REG1 389#define TMP2 SLJIT_TEMPORARY_REG3 390#define TMP3 SLJIT_TEMPORARY_EREG2 391#define STR_PTR SLJIT_SAVED_REG1 392#define STR_END SLJIT_SAVED_REG2 393#define STACK_TOP SLJIT_TEMPORARY_REG2 394#define STACK_LIMIT SLJIT_SAVED_REG3 395#define ARGUMENTS SLJIT_SAVED_EREG1 396#define CALL_COUNT SLJIT_SAVED_EREG2 397#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 398 399/* Locals layout. */ 400/* These two locals can be used by the current opcode. */ 401#define LOCALS0 (0 * sizeof(sljit_w)) 402#define LOCALS1 (1 * sizeof(sljit_w)) 403/* Two local variables for possessive quantifiers (char1 cannot use them). */ 404#define POSSESSIVE0 (2 * sizeof(sljit_w)) 405#define POSSESSIVE1 (3 * sizeof(sljit_w)) 406/* Max limit of recursions. */ 407#define CALL_LIMIT (4 * sizeof(sljit_w)) 408/* The output vector is stored on the stack, and contains pointers 409to characters. The vector data is divided into two groups: the first 410group contains the start / end character pointers, and the second is 411the start pointers when the end of the capturing group has not yet reached. */ 412#define OVECTOR_START (common->ovector_start) 413#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) 414#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) 415#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) 416 417#ifdef COMPILE_PCRE8 418#define MOV_UCHAR SLJIT_MOV_UB 419#define MOVU_UCHAR SLJIT_MOVU_UB 420#else 421#ifdef COMPILE_PCRE16 422#define MOV_UCHAR SLJIT_MOV_UH 423#define MOVU_UCHAR SLJIT_MOVU_UH 424#else 425#error Unsupported compiling mode 426#endif 427#endif 428 429/* Shortcuts. */ 430#define DEFINE_COMPILER \ 431 struct sljit_compiler *compiler = common->compiler 432#define OP1(op, dst, dstw, src, srcw) \ 433 sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw)) 434#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \ 435 sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w)) 436#define LABEL() \ 437 sljit_emit_label(compiler) 438#define JUMP(type) \ 439 sljit_emit_jump(compiler, (type)) 440#define JUMPTO(type, label) \ 441 sljit_set_label(sljit_emit_jump(compiler, (type)), (label)) 442#define JUMPHERE(jump) \ 443 sljit_set_label((jump), sljit_emit_label(compiler)) 444#define CMP(type, src1, src1w, src2, src2w) \ 445 sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) 446#define CMPTO(type, src1, src1w, src2, src2w, label) \ 447 sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) 448#define COND_VALUE(op, dst, dstw, type) \ 449 sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type)) 450#define GET_LOCAL_BASE(dst, dstw, offset) \ 451 sljit_get_local_base(compiler, (dst), (dstw), (offset)) 452 453static pcre_uchar* bracketend(pcre_uchar* cc) 454{ 455SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); 456do cc += GET(cc, 1); while (*cc == OP_ALT); 457SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); 458cc += 1 + LINK_SIZE; 459return cc; 460} 461 462/* Functions whose might need modification for all new supported opcodes: 463 next_opcode 464 get_localspace 465 set_localptrs 466 get_framesize 467 init_frame 468 get_localsize 469 copy_locals 470 compile_trypath 471 compile_backtrackpath 472*/ 473 474static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc) 475{ 476SLJIT_UNUSED_ARG(common); 477switch(*cc) 478 { 479 case OP_SOD: 480 case OP_SOM: 481 case OP_SET_SOM: 482 case OP_NOT_WORD_BOUNDARY: 483 case OP_WORD_BOUNDARY: 484 case OP_NOT_DIGIT: 485 case OP_DIGIT: 486 case OP_NOT_WHITESPACE: 487 case OP_WHITESPACE: 488 case OP_NOT_WORDCHAR: 489 case OP_WORDCHAR: 490 case OP_ANY: 491 case OP_ALLANY: 492 case OP_ANYNL: 493 case OP_NOT_HSPACE: 494 case OP_HSPACE: 495 case OP_NOT_VSPACE: 496 case OP_VSPACE: 497 case OP_EXTUNI: 498 case OP_EODN: 499 case OP_EOD: 500 case OP_CIRC: 501 case OP_CIRCM: 502 case OP_DOLL: 503 case OP_DOLLM: 504 case OP_TYPESTAR: 505 case OP_TYPEMINSTAR: 506 case OP_TYPEPLUS: 507 case OP_TYPEMINPLUS: 508 case OP_TYPEQUERY: 509 case OP_TYPEMINQUERY: 510 case OP_TYPEPOSSTAR: 511 case OP_TYPEPOSPLUS: 512 case OP_TYPEPOSQUERY: 513 case OP_CRSTAR: 514 case OP_CRMINSTAR: 515 case OP_CRPLUS: 516 case OP_CRMINPLUS: 517 case OP_CRQUERY: 518 case OP_CRMINQUERY: 519 case OP_DEF: 520 case OP_BRAZERO: 521 case OP_BRAMINZERO: 522 case OP_BRAPOSZERO: 523 case OP_COMMIT: 524 case OP_FAIL: 525 case OP_ACCEPT: 526 case OP_ASSERT_ACCEPT: 527 case OP_SKIPZERO: 528 return cc + 1; 529 530 case OP_ANYBYTE: 531#ifdef SUPPORT_UTF 532 if (common->utf) return NULL; 533#endif 534 return cc + 1; 535 536 case OP_CHAR: 537 case OP_CHARI: 538 case OP_NOT: 539 case OP_NOTI: 540 case OP_STAR: 541 case OP_MINSTAR: 542 case OP_PLUS: 543 case OP_MINPLUS: 544 case OP_QUERY: 545 case OP_MINQUERY: 546 case OP_POSSTAR: 547 case OP_POSPLUS: 548 case OP_POSQUERY: 549 case OP_STARI: 550 case OP_MINSTARI: 551 case OP_PLUSI: 552 case OP_MINPLUSI: 553 case OP_QUERYI: 554 case OP_MINQUERYI: 555 case OP_POSSTARI: 556 case OP_POSPLUSI: 557 case OP_POSQUERYI: 558 case OP_NOTSTAR: 559 case OP_NOTMINSTAR: 560 case OP_NOTPLUS: 561 case OP_NOTMINPLUS: 562 case OP_NOTQUERY: 563 case OP_NOTMINQUERY: 564 case OP_NOTPOSSTAR: 565 case OP_NOTPOSPLUS: 566 case OP_NOTPOSQUERY: 567 case OP_NOTSTARI: 568 case OP_NOTMINSTARI: 569 case OP_NOTPLUSI: 570 case OP_NOTMINPLUSI: 571 case OP_NOTQUERYI: 572 case OP_NOTMINQUERYI: 573 case OP_NOTPOSSTARI: 574 case OP_NOTPOSPLUSI: 575 case OP_NOTPOSQUERYI: 576 cc += 2; 577#ifdef SUPPORT_UTF 578 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 579#endif 580 return cc; 581 582 case OP_UPTO: 583 case OP_MINUPTO: 584 case OP_EXACT: 585 case OP_POSUPTO: 586 case OP_UPTOI: 587 case OP_MINUPTOI: 588 case OP_EXACTI: 589 case OP_POSUPTOI: 590 case OP_NOTUPTO: 591 case OP_NOTMINUPTO: 592 case OP_NOTEXACT: 593 case OP_NOTPOSUPTO: 594 case OP_NOTUPTOI: 595 case OP_NOTMINUPTOI: 596 case OP_NOTEXACTI: 597 case OP_NOTPOSUPTOI: 598 cc += 2 + IMM2_SIZE; 599#ifdef SUPPORT_UTF 600 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 601#endif 602 return cc; 603 604 case OP_NOTPROP: 605 case OP_PROP: 606 return cc + 1 + 2; 607 608 case OP_TYPEUPTO: 609 case OP_TYPEMINUPTO: 610 case OP_TYPEEXACT: 611 case OP_TYPEPOSUPTO: 612 case OP_REF: 613 case OP_REFI: 614 case OP_CREF: 615 case OP_NCREF: 616 case OP_RREF: 617 case OP_NRREF: 618 case OP_CLOSE: 619 cc += 1 + IMM2_SIZE; 620 return cc; 621 622 case OP_CRRANGE: 623 case OP_CRMINRANGE: 624 return cc + 1 + 2 * IMM2_SIZE; 625 626 case OP_CLASS: 627 case OP_NCLASS: 628 return cc + 1 + 32 / sizeof(pcre_uchar); 629 630#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 631 case OP_XCLASS: 632 return cc + GET(cc, 1); 633#endif 634 635 case OP_RECURSE: 636 case OP_ASSERT: 637 case OP_ASSERT_NOT: 638 case OP_ASSERTBACK: 639 case OP_ASSERTBACK_NOT: 640 case OP_REVERSE: 641 case OP_ONCE: 642 case OP_ONCE_NC: 643 case OP_BRA: 644 case OP_BRAPOS: 645 case OP_COND: 646 case OP_SBRA: 647 case OP_SBRAPOS: 648 case OP_SCOND: 649 case OP_ALT: 650 case OP_KET: 651 case OP_KETRMAX: 652 case OP_KETRMIN: 653 case OP_KETRPOS: 654 return cc + 1 + LINK_SIZE; 655 656 case OP_CBRA: 657 case OP_CBRAPOS: 658 case OP_SCBRA: 659 case OP_SCBRAPOS: 660 return cc + 1 + LINK_SIZE + IMM2_SIZE; 661 662 case OP_MARK: 663 return cc + 1 + 2 + cc[1]; 664 665 default: 666 return NULL; 667 } 668} 669 670static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) 671{ 672int localspace = 0; 673pcre_uchar *alternative; 674/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ 675while (cc < ccend) 676 { 677 switch(*cc) 678 { 679 case OP_SET_SOM: 680 common->has_set_som = TRUE; 681 cc += 1; 682 break; 683 684 case OP_ASSERT: 685 case OP_ASSERT_NOT: 686 case OP_ASSERTBACK: 687 case OP_ASSERTBACK_NOT: 688 case OP_ONCE: 689 case OP_ONCE_NC: 690 case OP_BRAPOS: 691 case OP_SBRA: 692 case OP_SBRAPOS: 693 case OP_SCOND: 694 localspace += sizeof(sljit_w); 695 cc += 1 + LINK_SIZE; 696 break; 697 698 case OP_CBRAPOS: 699 case OP_SCBRAPOS: 700 localspace += sizeof(sljit_w); 701 cc += 1 + LINK_SIZE + IMM2_SIZE; 702 break; 703 704 case OP_COND: 705 /* Might be a hidden SCOND. */ 706 alternative = cc + GET(cc, 1); 707 if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) 708 localspace += sizeof(sljit_w); 709 cc += 1 + LINK_SIZE; 710 break; 711 712 case OP_RECURSE: 713 /* Set its value only once. */ 714 if (common->recursive_head == 0) 715 { 716 common->recursive_head = common->ovector_start; 717 common->ovector_start += sizeof(sljit_w); 718 } 719 cc += 1 + LINK_SIZE; 720 break; 721 722 case OP_MARK: 723 if (common->mark_ptr == 0) 724 { 725 common->mark_ptr = common->ovector_start; 726 common->ovector_start += sizeof(sljit_w); 727 } 728 cc += 1 + 2 + cc[1]; 729 break; 730 731 default: 732 cc = next_opcode(common, cc); 733 if (cc == NULL) 734 return -1; 735 break; 736 } 737 } 738return localspace; 739} 740 741static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend) 742{ 743pcre_uchar *cc = common->start; 744pcre_uchar *alternative; 745while (cc < ccend) 746 { 747 switch(*cc) 748 { 749 case OP_ASSERT: 750 case OP_ASSERT_NOT: 751 case OP_ASSERTBACK: 752 case OP_ASSERTBACK_NOT: 753 case OP_ONCE: 754 case OP_ONCE_NC: 755 case OP_BRAPOS: 756 case OP_SBRA: 757 case OP_SBRAPOS: 758 case OP_SCOND: 759 common->localptrs[cc - common->start] = localptr; 760 localptr += sizeof(sljit_w); 761 cc += 1 + LINK_SIZE; 762 break; 763 764 case OP_CBRAPOS: 765 case OP_SCBRAPOS: 766 common->localptrs[cc - common->start] = localptr; 767 localptr += sizeof(sljit_w); 768 cc += 1 + LINK_SIZE + IMM2_SIZE; 769 break; 770 771 case OP_COND: 772 /* Might be a hidden SCOND. */ 773 alternative = cc + GET(cc, 1); 774 if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) 775 { 776 common->localptrs[cc - common->start] = localptr; 777 localptr += sizeof(sljit_w); 778 } 779 cc += 1 + LINK_SIZE; 780 break; 781 782 default: 783 cc = next_opcode(common, cc); 784 SLJIT_ASSERT(cc != NULL); 785 break; 786 } 787 } 788} 789 790/* Returns with -1 if no need for frame. */ 791static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive) 792{ 793pcre_uchar *ccend = bracketend(cc); 794int length = 0; 795BOOL possessive = FALSE; 796BOOL setsom_found = recursive; 797BOOL setmark_found = recursive; 798 799if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) 800 { 801 length = 3; 802 possessive = TRUE; 803 } 804 805cc = next_opcode(common, cc); 806SLJIT_ASSERT(cc != NULL); 807while (cc < ccend) 808 switch(*cc) 809 { 810 case OP_SET_SOM: 811 SLJIT_ASSERT(common->has_set_som); 812 if (!setsom_found) 813 { 814 length += 2; 815 setsom_found = TRUE; 816 } 817 cc += 1; 818 break; 819 820 case OP_MARK: 821 SLJIT_ASSERT(common->mark_ptr != 0); 822 if (!setmark_found) 823 { 824 length += 2; 825 setmark_found = TRUE; 826 } 827 cc += 1 + 2 + cc[1]; 828 break; 829 830 case OP_RECURSE: 831 if (common->has_set_som && !setsom_found) 832 { 833 length += 2; 834 setsom_found = TRUE; 835 } 836 if (common->mark_ptr != 0 && !setmark_found) 837 { 838 length += 2; 839 setmark_found = TRUE; 840 } 841 cc += 1 + LINK_SIZE; 842 break; 843 844 case OP_CBRA: 845 case OP_CBRAPOS: 846 case OP_SCBRA: 847 case OP_SCBRAPOS: 848 length += 3; 849 cc += 1 + LINK_SIZE + IMM2_SIZE; 850 break; 851 852 default: 853 cc = next_opcode(common, cc); 854 SLJIT_ASSERT(cc != NULL); 855 break; 856 } 857 858/* Possessive quantifiers can use a special case. */ 859if (SLJIT_UNLIKELY(possessive) && length == 3) 860 return -1; 861 862if (length > 0) 863 return length + 1; 864return -1; 865} 866 867static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive) 868{ 869DEFINE_COMPILER; 870pcre_uchar *ccend = bracketend(cc); 871BOOL setsom_found = recursive; 872BOOL setmark_found = recursive; 873int offset; 874 875/* >= 1 + shortest item size (2) */ 876SLJIT_UNUSED_ARG(stacktop); 877SLJIT_ASSERT(stackpos >= stacktop + 2); 878 879stackpos = STACK(stackpos); 880if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) 881 cc = next_opcode(common, cc); 882SLJIT_ASSERT(cc != NULL); 883while (cc < ccend) 884 switch(*cc) 885 { 886 case OP_SET_SOM: 887 SLJIT_ASSERT(common->has_set_som); 888 if (!setsom_found) 889 { 890 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); 891 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); 892 stackpos += (int)sizeof(sljit_w); 893 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 894 stackpos += (int)sizeof(sljit_w); 895 setsom_found = TRUE; 896 } 897 cc += 1; 898 break; 899 900 case OP_MARK: 901 SLJIT_ASSERT(common->mark_ptr != 0); 902 if (!setmark_found) 903 { 904 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); 905 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); 906 stackpos += (int)sizeof(sljit_w); 907 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 908 stackpos += (int)sizeof(sljit_w); 909 setmark_found = TRUE; 910 } 911 cc += 1 + 2 + cc[1]; 912 break; 913 914 case OP_RECURSE: 915 if (common->has_set_som && !setsom_found) 916 { 917 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); 918 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); 919 stackpos += (int)sizeof(sljit_w); 920 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 921 stackpos += (int)sizeof(sljit_w); 922 setsom_found = TRUE; 923 } 924 if (common->mark_ptr != 0 && !setmark_found) 925 { 926 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); 927 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); 928 stackpos += (int)sizeof(sljit_w); 929 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 930 stackpos += (int)sizeof(sljit_w); 931 setmark_found = TRUE; 932 } 933 cc += 1 + LINK_SIZE; 934 break; 935 936 case OP_CBRA: 937 case OP_CBRAPOS: 938 case OP_SCBRA: 939 case OP_SCBRAPOS: 940 offset = (GET2(cc, 1 + LINK_SIZE)) << 1; 941 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); 942 stackpos += (int)sizeof(sljit_w); 943 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); 944 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); 945 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 946 stackpos += (int)sizeof(sljit_w); 947 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); 948 stackpos += (int)sizeof(sljit_w); 949 950 cc += 1 + LINK_SIZE + IMM2_SIZE; 951 break; 952 953 default: 954 cc = next_opcode(common, cc); 955 SLJIT_ASSERT(cc != NULL); 956 break; 957 } 958 959OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end); 960SLJIT_ASSERT(stackpos == STACK(stacktop)); 961} 962 963static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) 964{ 965int localsize = 2; 966pcre_uchar *alternative; 967/* Calculate the sum of the local variables. */ 968while (cc < ccend) 969 { 970 switch(*cc) 971 { 972 case OP_ASSERT: 973 case OP_ASSERT_NOT: 974 case OP_ASSERTBACK: 975 case OP_ASSERTBACK_NOT: 976 case OP_ONCE: 977 case OP_ONCE_NC: 978 case OP_BRAPOS: 979 case OP_SBRA: 980 case OP_SBRAPOS: 981 case OP_SCOND: 982 localsize++; 983 cc += 1 + LINK_SIZE; 984 break; 985 986 case OP_CBRA: 987 case OP_SCBRA: 988 localsize++; 989 cc += 1 + LINK_SIZE + IMM2_SIZE; 990 break; 991 992 case OP_CBRAPOS: 993 case OP_SCBRAPOS: 994 localsize += 2; 995 cc += 1 + LINK_SIZE + IMM2_SIZE; 996 break; 997 998 case OP_COND: 999 /* Might be a hidden SCOND. */ 1000 alternative = cc + GET(cc, 1); 1001 if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) 1002 localsize++; 1003 cc += 1 + LINK_SIZE; 1004 break; 1005 1006 default: 1007 cc = next_opcode(common, cc); 1008 SLJIT_ASSERT(cc != NULL); 1009 break; 1010 } 1011 } 1012SLJIT_ASSERT(cc == ccend); 1013return localsize; 1014} 1015 1016static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, 1017 BOOL save, int stackptr, int stacktop) 1018{ 1019DEFINE_COMPILER; 1020int srcw[2]; 1021int count; 1022BOOL tmp1next = TRUE; 1023BOOL tmp1empty = TRUE; 1024BOOL tmp2empty = TRUE; 1025pcre_uchar *alternative; 1026enum { 1027 start, 1028 loop, 1029 end 1030} status; 1031 1032status = save ? start : loop; 1033stackptr = STACK(stackptr - 2); 1034stacktop = STACK(stacktop - 1); 1035 1036if (!save) 1037 { 1038 stackptr += sizeof(sljit_w); 1039 if (stackptr < stacktop) 1040 { 1041 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); 1042 stackptr += sizeof(sljit_w); 1043 tmp1empty = FALSE; 1044 } 1045 if (stackptr < stacktop) 1046 { 1047 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); 1048 stackptr += sizeof(sljit_w); 1049 tmp2empty = FALSE; 1050 } 1051 /* The tmp1next must be TRUE in either way. */ 1052 } 1053 1054while (status != end) 1055 { 1056 count = 0; 1057 switch(status) 1058 { 1059 case start: 1060 SLJIT_ASSERT(save && common->recursive_head != 0); 1061 count = 1; 1062 srcw[0] = common->recursive_head; 1063 status = loop; 1064 break; 1065 1066 case loop: 1067 if (cc >= ccend) 1068 { 1069 status = end; 1070 break; 1071 } 1072 1073 switch(*cc) 1074 { 1075 case OP_ASSERT: 1076 case OP_ASSERT_NOT: 1077 case OP_ASSERTBACK: 1078 case OP_ASSERTBACK_NOT: 1079 case OP_ONCE: 1080 case OP_ONCE_NC: 1081 case OP_BRAPOS: 1082 case OP_SBRA: 1083 case OP_SBRAPOS: 1084 case OP_SCOND: 1085 count = 1; 1086 srcw[0] = PRIV_DATA(cc); 1087 SLJIT_ASSERT(srcw[0] != 0); 1088 cc += 1 + LINK_SIZE; 1089 break; 1090 1091 case OP_CBRA: 1092 case OP_SCBRA: 1093 count = 1; 1094 srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); 1095 cc += 1 + LINK_SIZE + IMM2_SIZE; 1096 break; 1097 1098 case OP_CBRAPOS: 1099 case OP_SCBRAPOS: 1100 count = 2; 1101 srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); 1102 srcw[0] = PRIV_DATA(cc); 1103 SLJIT_ASSERT(srcw[0] != 0); 1104 cc += 1 + LINK_SIZE + IMM2_SIZE; 1105 break; 1106 1107 case OP_COND: 1108 /* Might be a hidden SCOND. */ 1109 alternative = cc + GET(cc, 1); 1110 if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) 1111 { 1112 count = 1; 1113 srcw[0] = PRIV_DATA(cc); 1114 SLJIT_ASSERT(srcw[0] != 0); 1115 } 1116 cc += 1 + LINK_SIZE; 1117 break; 1118 1119 default: 1120 cc = next_opcode(common, cc); 1121 SLJIT_ASSERT(cc != NULL); 1122 break; 1123 } 1124 break; 1125 1126 case end: 1127 SLJIT_ASSERT_STOP(); 1128 break; 1129 } 1130 1131 while (count > 0) 1132 { 1133 count--; 1134 if (save) 1135 { 1136 if (tmp1next) 1137 { 1138 if (!tmp1empty) 1139 { 1140 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); 1141 stackptr += sizeof(sljit_w); 1142 } 1143 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); 1144 tmp1empty = FALSE; 1145 tmp1next = FALSE; 1146 } 1147 else 1148 { 1149 if (!tmp2empty) 1150 { 1151 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); 1152 stackptr += sizeof(sljit_w); 1153 } 1154 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); 1155 tmp2empty = FALSE; 1156 tmp1next = TRUE; 1157 } 1158 } 1159 else 1160 { 1161 if (tmp1next) 1162 { 1163 SLJIT_ASSERT(!tmp1empty); 1164 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0); 1165 tmp1empty = stackptr >= stacktop; 1166 if (!tmp1empty) 1167 { 1168 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); 1169 stackptr += sizeof(sljit_w); 1170 } 1171 tmp1next = FALSE; 1172 } 1173 else 1174 { 1175 SLJIT_ASSERT(!tmp2empty); 1176 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0); 1177 tmp2empty = stackptr >= stacktop; 1178 if (!tmp2empty) 1179 { 1180 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); 1181 stackptr += sizeof(sljit_w); 1182 } 1183 tmp1next = TRUE; 1184 } 1185 } 1186 } 1187 } 1188 1189if (save) 1190 { 1191 if (tmp1next) 1192 { 1193 if (!tmp1empty) 1194 { 1195 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); 1196 stackptr += sizeof(sljit_w); 1197 } 1198 if (!tmp2empty) 1199 { 1200 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); 1201 stackptr += sizeof(sljit_w); 1202 } 1203 } 1204 else 1205 { 1206 if (!tmp2empty) 1207 { 1208 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); 1209 stackptr += sizeof(sljit_w); 1210 } 1211 if (!tmp1empty) 1212 { 1213 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); 1214 stackptr += sizeof(sljit_w); 1215 } 1216 } 1217 } 1218SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); 1219} 1220 1221static SLJIT_INLINE BOOL ispowerof2(unsigned int value) 1222{ 1223return (value & (value - 1)) == 0; 1224} 1225 1226static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) 1227{ 1228while (list) 1229 { 1230 /* sljit_set_label is clever enough to do nothing 1231 if either the jump or the label is NULL */ 1232 sljit_set_label(list->jump, label); 1233 list = list->next; 1234 } 1235} 1236 1237static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump) 1238{ 1239jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); 1240if (list_item) 1241 { 1242 list_item->next = *list; 1243 list_item->jump = jump; 1244 *list = list_item; 1245 } 1246} 1247 1248static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start) 1249{ 1250DEFINE_COMPILER; 1251stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); 1252 1253if (list_item) 1254 { 1255 list_item->type = type; 1256 list_item->data = data; 1257 list_item->start = start; 1258 list_item->leave = LABEL(); 1259 list_item->next = common->stubs; 1260 common->stubs = list_item; 1261 } 1262} 1263 1264static void flush_stubs(compiler_common *common) 1265{ 1266DEFINE_COMPILER; 1267stub_list* list_item = common->stubs; 1268 1269while (list_item) 1270 { 1271 JUMPHERE(list_item->start); 1272 switch(list_item->type) 1273 { 1274 case stack_alloc: 1275 add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); 1276 break; 1277 } 1278 JUMPTO(SLJIT_JUMP, list_item->leave); 1279 list_item = list_item->next; 1280 } 1281common->stubs = NULL; 1282} 1283 1284static SLJIT_INLINE void decrease_call_count(compiler_common *common) 1285{ 1286DEFINE_COMPILER; 1287 1288OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); 1289add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); 1290} 1291 1292static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) 1293{ 1294/* May destroy all locals and registers except TMP2. */ 1295DEFINE_COMPILER; 1296 1297OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); 1298#ifdef DESTROY_REGISTERS 1299OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); 1300OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); 1301OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); 1302OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0); 1303OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0); 1304#endif 1305add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); 1306} 1307 1308static SLJIT_INLINE void free_stack(compiler_common *common, int size) 1309{ 1310DEFINE_COMPILER; 1311OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); 1312} 1313 1314static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) 1315{ 1316DEFINE_COMPILER; 1317struct sljit_label *loop; 1318int i; 1319/* At this point we can freely use all temporary registers. */ 1320/* TMP1 returns with begin - 1. */ 1321OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); 1322if (length < 8) 1323 { 1324 for (i = 0; i < length; i++) 1325 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0); 1326 } 1327else 1328 { 1329 GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w)); 1330 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length); 1331 loop = LABEL(); 1332 OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0); 1333 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); 1334 JUMPTO(SLJIT_C_NOT_ZERO, loop); 1335 } 1336} 1337 1338static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) 1339{ 1340DEFINE_COMPILER; 1341struct sljit_label *loop; 1342struct sljit_jump *earlyexit; 1343 1344/* At this point we can freely use all registers. */ 1345OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); 1346OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); 1347 1348OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); 1349if (common->mark_ptr != 0) 1350 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); 1351OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); 1352if (common->mark_ptr != 0) 1353 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0); 1354OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); 1355OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); 1356GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START); 1357/* Unlikely, but possible */ 1358earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); 1359loop = LABEL(); 1360OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0); 1361OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w)); 1362/* Copy the integer value to the output buffer */ 1363#ifdef COMPILE_PCRE16 1364OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); 1365#endif 1366OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); 1367OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); 1368JUMPTO(SLJIT_C_NOT_ZERO, loop); 1369JUMPHERE(earlyexit); 1370 1371/* Calculate the return value, which is the maximum ovector value. */ 1372if (topbracket > 1) 1373 { 1374 GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); 1375 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); 1376 1377 /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */ 1378 loop = LABEL(); 1379 OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w))); 1380 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); 1381 CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop); 1382 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); 1383 } 1384else 1385 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); 1386} 1387 1388static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave) 1389{ 1390DEFINE_COMPILER; 1391 1392SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); 1393SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); 1394 1395OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); 1396OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); 1397OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); 1398CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave); 1399 1400/* Store match begin and end. */ 1401OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); 1402OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); 1403OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); 1404OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); 1405#ifdef COMPILE_PCRE16 1406OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); 1407#endif 1408OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); 1409 1410OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0); 1411#ifdef COMPILE_PCRE16 1412OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); 1413#endif 1414OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0); 1415 1416JUMPTO(SLJIT_JUMP, leave); 1417} 1418 1419static SLJIT_INLINE void check_start_used_ptr(compiler_common *common) 1420{ 1421/* May destroy TMP1. */ 1422DEFINE_COMPILER; 1423struct sljit_jump *jump; 1424 1425if (common->mode == JIT_PARTIAL_SOFT_COMPILE) 1426 { 1427 /* The value of -1 must be kept for start_used_ptr! */ 1428 OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1); 1429 /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting 1430 is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ 1431 jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); 1432 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); 1433 JUMPHERE(jump); 1434 } 1435else if (common->mode == JIT_PARTIAL_HARD_COMPILE) 1436 { 1437 jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); 1438 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); 1439 JUMPHERE(jump); 1440 } 1441} 1442 1443static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc) 1444{ 1445/* Detects if the character has an othercase. */ 1446unsigned int c; 1447 1448#ifdef SUPPORT_UTF 1449if (common->utf) 1450 { 1451 GETCHAR(c, cc); 1452 if (c > 127) 1453 { 1454#ifdef SUPPORT_UCP 1455 return c != UCD_OTHERCASE(c); 1456#else 1457 return FALSE; 1458#endif 1459 } 1460#ifndef COMPILE_PCRE8 1461 return common->fcc[c] != c; 1462#endif 1463 } 1464else 1465#endif 1466 c = *cc; 1467return MAX_255(c) ? common->fcc[c] != c : FALSE; 1468} 1469 1470static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c) 1471{ 1472/* Returns with the othercase. */ 1473#ifdef SUPPORT_UTF 1474if (common->utf && c > 127) 1475 { 1476#ifdef SUPPORT_UCP 1477 return UCD_OTHERCASE(c); 1478#else 1479 return c; 1480#endif 1481 } 1482#endif 1483return TABLE_GET(c, common->fcc, c); 1484} 1485 1486static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc) 1487{ 1488/* Detects if the character and its othercase has only 1 bit difference. */ 1489unsigned int c, oc, bit; 1490#if defined SUPPORT_UTF && defined COMPILE_PCRE8 1491int n; 1492#endif 1493 1494#ifdef SUPPORT_UTF 1495if (common->utf) 1496 { 1497 GETCHAR(c, cc); 1498 if (c <= 127) 1499 oc = common->fcc[c]; 1500 else 1501 { 1502#ifdef SUPPORT_UCP 1503 oc = UCD_OTHERCASE(c); 1504#else 1505 oc = c; 1506#endif 1507 } 1508 } 1509else 1510 { 1511 c = *cc; 1512 oc = TABLE_GET(c, common->fcc, c); 1513 } 1514#else 1515c = *cc; 1516oc = TABLE_GET(c, common->fcc, c); 1517#endif 1518 1519SLJIT_ASSERT(c != oc); 1520 1521bit = c ^ oc; 1522/* Optimized for English alphabet. */ 1523if (c <= 127 && bit == 0x20) 1524 return (0 << 8) | 0x20; 1525 1526/* Since c != oc, they must have at least 1 bit difference. */ 1527if (!ispowerof2(bit)) 1528 return 0; 1529 1530#ifdef COMPILE_PCRE8 1531 1532#ifdef SUPPORT_UTF 1533if (common->utf && c > 127) 1534 { 1535 n = GET_EXTRALEN(*cc); 1536 while ((bit & 0x3f) == 0) 1537 { 1538 n--; 1539 bit >>= 6; 1540 } 1541 return (n << 8) | bit; 1542 } 1543#endif /* SUPPORT_UTF */ 1544return (0 << 8) | bit; 1545 1546#else /* COMPILE_PCRE8 */ 1547 1548#ifdef COMPILE_PCRE16 1549#ifdef SUPPORT_UTF 1550if (common->utf && c > 65535) 1551 { 1552 if (bit >= (1 << 10)) 1553 bit >>= 10; 1554 else 1555 return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8)); 1556 } 1557#endif /* SUPPORT_UTF */ 1558return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); 1559#endif /* COMPILE_PCRE16 */ 1560 1561#endif /* COMPILE_PCRE8 */ 1562} 1563 1564static void check_partial(compiler_common *common, BOOL force) 1565{ 1566/* Checks whether a partial matching is occured. Does not modify registers. */ 1567DEFINE_COMPILER; 1568struct sljit_jump *jump = NULL; 1569 1570SLJIT_ASSERT(!force || common->mode != JIT_COMPILE); 1571 1572if (common->mode == JIT_COMPILE) 1573 return; 1574 1575if (!force) 1576 jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); 1577else if (common->mode == JIT_PARTIAL_SOFT_COMPILE) 1578 jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); 1579 1580if (common->mode == JIT_PARTIAL_SOFT_COMPILE) 1581 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); 1582else 1583 { 1584 if (common->partialmatchlabel != NULL) 1585 JUMPTO(SLJIT_JUMP, common->partialmatchlabel); 1586 else 1587 add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); 1588 } 1589 1590if (jump != NULL) 1591 JUMPHERE(jump); 1592} 1593 1594static struct sljit_jump *check_str_end(compiler_common *common) 1595{ 1596/* Does not affect registers. Usually used in a tight spot. */ 1597DEFINE_COMPILER; 1598struct sljit_jump *jump; 1599struct sljit_jump *nohit; 1600struct sljit_jump *return_value; 1601 1602if (common->mode == JIT_COMPILE) 1603 return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 1604 1605jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); 1606if (common->mode == JIT_PARTIAL_SOFT_COMPILE) 1607 { 1608 nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); 1609 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); 1610 JUMPHERE(nohit); 1611 return_value = JUMP(SLJIT_JUMP); 1612 } 1613else 1614 { 1615 return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); 1616 if (common->partialmatchlabel != NULL) 1617 JUMPTO(SLJIT_JUMP, common->partialmatchlabel); 1618 else 1619 add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); 1620 } 1621JUMPHERE(jump); 1622return return_value; 1623} 1624 1625static void detect_partial_match(compiler_common *common, jump_list **backtracks) 1626{ 1627DEFINE_COMPILER; 1628struct sljit_jump *jump; 1629 1630if (common->mode == JIT_COMPILE) 1631 { 1632 add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); 1633 return; 1634 } 1635 1636/* Partial matching mode. */ 1637jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); 1638add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0)); 1639if (common->mode == JIT_PARTIAL_SOFT_COMPILE) 1640 { 1641 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); 1642 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 1643 } 1644else 1645 { 1646 if (common->partialmatchlabel != NULL) 1647 JUMPTO(SLJIT_JUMP, common->partialmatchlabel); 1648 else 1649 add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); 1650 } 1651JUMPHERE(jump); 1652} 1653 1654static void read_char(compiler_common *common) 1655{ 1656/* Reads the character into TMP1, updates STR_PTR. 1657Does not check STR_END. TMP2 Destroyed. */ 1658DEFINE_COMPILER; 1659#ifdef SUPPORT_UTF 1660struct sljit_jump *jump; 1661#endif 1662 1663OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 1664#ifdef SUPPORT_UTF 1665if (common->utf) 1666 { 1667#ifdef COMPILE_PCRE8 1668 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 1669#else 1670#ifdef COMPILE_PCRE16 1671 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); 1672#endif 1673#endif /* COMPILE_PCRE8 */ 1674 add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); 1675 JUMPHERE(jump); 1676 } 1677#endif 1678OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1679} 1680 1681static void peek_char(compiler_common *common) 1682{ 1683/* Reads the character into TMP1, keeps STR_PTR. 1684Does not check STR_END. TMP2 Destroyed. */ 1685DEFINE_COMPILER; 1686#ifdef SUPPORT_UTF 1687struct sljit_jump *jump; 1688#endif 1689 1690OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 1691#ifdef SUPPORT_UTF 1692if (common->utf) 1693 { 1694#ifdef COMPILE_PCRE8 1695 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 1696#else 1697#ifdef COMPILE_PCRE16 1698 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); 1699#endif 1700#endif /* COMPILE_PCRE8 */ 1701 add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); 1702 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 1703 JUMPHERE(jump); 1704 } 1705#endif 1706} 1707 1708static void read_char8_type(compiler_common *common) 1709{ 1710/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ 1711DEFINE_COMPILER; 1712#if defined SUPPORT_UTF || defined COMPILE_PCRE16 1713struct sljit_jump *jump; 1714#endif 1715 1716#ifdef SUPPORT_UTF 1717if (common->utf) 1718 { 1719 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); 1720 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1721#ifdef COMPILE_PCRE8 1722 /* This can be an extra read in some situations, but hopefully 1723 it is needed in most cases. */ 1724 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 1725 jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); 1726 add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); 1727 JUMPHERE(jump); 1728#else 1729#ifdef COMPILE_PCRE16 1730 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); 1731 jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); 1732 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 1733 JUMPHERE(jump); 1734 /* Skip low surrogate if necessary. */ 1735 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00); 1736 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800); 1737 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); 1738 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); 1739 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 1740#endif 1741#endif /* COMPILE_PCRE8 */ 1742 return; 1743 } 1744#endif 1745OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); 1746OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1747#ifdef COMPILE_PCRE16 1748/* The ctypes array contains only 256 values. */ 1749OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); 1750jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); 1751#endif 1752OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 1753#ifdef COMPILE_PCRE16 1754JUMPHERE(jump); 1755#endif 1756} 1757 1758static void skip_char_back(compiler_common *common) 1759{ 1760/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */ 1761DEFINE_COMPILER; 1762#if defined SUPPORT_UTF && defined COMPILE_PCRE8 1763struct sljit_label *label; 1764 1765if (common->utf) 1766 { 1767 label = LABEL(); 1768 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); 1769 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1770 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); 1771 CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); 1772 return; 1773 } 1774#endif 1775#if defined SUPPORT_UTF && defined COMPILE_PCRE16 1776if (common->utf) 1777 { 1778 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); 1779 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1780 /* Skip low surrogate if necessary. */ 1781 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 1782 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); 1783 COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); 1784 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 1785 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 1786 return; 1787 } 1788#endif 1789OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1790} 1791 1792static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue) 1793{ 1794/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ 1795DEFINE_COMPILER; 1796 1797if (nltype == NLTYPE_ANY) 1798 { 1799 add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); 1800 add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 1801 } 1802else if (nltype == NLTYPE_ANYCRLF) 1803 { 1804 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR); 1805 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); 1806 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); 1807 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 1808 add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 1809 } 1810else 1811 { 1812 SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); 1813 add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); 1814 } 1815} 1816 1817#ifdef SUPPORT_UTF 1818 1819#ifdef COMPILE_PCRE8 1820static void do_utfreadchar(compiler_common *common) 1821{ 1822/* Fast decoding a UTF-8 character. TMP1 contains the first byte 1823of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */ 1824DEFINE_COMPILER; 1825struct sljit_jump *jump; 1826 1827sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 1828/* Searching for the first zero. */ 1829OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); 1830jump = JUMP(SLJIT_C_NOT_ZERO); 1831/* Two byte sequence. */ 1832OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 1833OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1834OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f); 1835OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 1836OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 1837OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 1838OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); 1839sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1840JUMPHERE(jump); 1841 1842OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10); 1843jump = JUMP(SLJIT_C_NOT_ZERO); 1844/* Three byte sequence. */ 1845OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 1846OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f); 1847OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12); 1848OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 1849OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); 1850OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 1851OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); 1852OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 1853OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 1854OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 1855OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); 1856sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1857JUMPHERE(jump); 1858 1859/* Four byte sequence. */ 1860OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 1861OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07); 1862OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18); 1863OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 1864OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12); 1865OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 1866OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); 1867OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 1868OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); 1869OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 1870OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3)); 1871OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); 1872OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 1873OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 1874OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); 1875sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1876} 1877 1878static void do_utfreadtype8(compiler_common *common) 1879{ 1880/* Fast decoding a UTF-8 character type. TMP2 contains the first byte 1881of the character (>= 0xc0). Return value in TMP1. */ 1882DEFINE_COMPILER; 1883struct sljit_jump *jump; 1884struct sljit_jump *compare; 1885 1886sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 1887 1888OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); 1889jump = JUMP(SLJIT_C_NOT_ZERO); 1890/* Two byte sequence. */ 1891OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 1892OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1893OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); 1894OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); 1895OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 1896OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); 1897compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); 1898OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 1899sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1900 1901JUMPHERE(compare); 1902OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); 1903sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1904JUMPHERE(jump); 1905 1906/* We only have types for characters less than 256. */ 1907OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0); 1908OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 1909OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); 1910sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1911} 1912 1913#else /* COMPILE_PCRE8 */ 1914 1915#ifdef COMPILE_PCRE16 1916static void do_utfreadchar(compiler_common *common) 1917{ 1918/* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char 1919of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */ 1920DEFINE_COMPILER; 1921struct sljit_jump *jump; 1922 1923sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 1924jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00); 1925/* Do nothing, only return. */ 1926sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1927 1928JUMPHERE(jump); 1929/* Combine two 16 bit characters. */ 1930OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 1931OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 1932OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); 1933OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10); 1934OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff); 1935OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 1936OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); 1937OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); 1938sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1939} 1940#endif /* COMPILE_PCRE16 */ 1941 1942#endif /* COMPILE_PCRE8 */ 1943 1944#endif /* SUPPORT_UTF */ 1945 1946#ifdef SUPPORT_UCP 1947 1948/* UCD_BLOCK_SIZE must be 128 (see the assert below). */ 1949#define UCD_BLOCK_MASK 127 1950#define UCD_BLOCK_SHIFT 7 1951 1952static void do_getucd(compiler_common *common) 1953{ 1954/* Search the UCD record for the character comes in TMP1. 1955Returns chartype in TMP1 and UCD offset in TMP2. */ 1956DEFINE_COMPILER; 1957 1958SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); 1959 1960sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 1961OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); 1962OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1)); 1963OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); 1964OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); 1965OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); 1966OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2)); 1967OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); 1968OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); 1969OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); 1970sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 1971} 1972#endif 1973 1974static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline) 1975{ 1976DEFINE_COMPILER; 1977struct sljit_label *mainloop; 1978struct sljit_label *newlinelabel = NULL; 1979struct sljit_jump *start; 1980struct sljit_jump *end = NULL; 1981struct sljit_jump *nl = NULL; 1982#ifdef SUPPORT_UTF 1983struct sljit_jump *singlechar; 1984#endif 1985jump_list *newline = NULL; 1986BOOL newlinecheck = FALSE; 1987BOOL readuchar = FALSE; 1988 1989if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY || 1990 common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) 1991 newlinecheck = TRUE; 1992 1993if (firstline) 1994 { 1995 /* Search for the end of the first line. */ 1996 SLJIT_ASSERT(common->first_line_end != 0); 1997 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); 1998 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0); 1999 2000 if (common->nltype == NLTYPE_FIXED && common->newline > 255) 2001 { 2002 mainloop = LABEL(); 2003 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2004 end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2005 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); 2006 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 2007 CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); 2008 CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); 2009 OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2010 } 2011 else 2012 { 2013 end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2014 mainloop = LABEL(); 2015 /* Continual stores does not cause data dependency. */ 2016 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); 2017 read_char(common); 2018 check_newlinechar(common, common->nltype, &newline, TRUE); 2019 CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); 2020 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); 2021 set_jumps(newline, LABEL()); 2022 } 2023 2024 JUMPHERE(end); 2025 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 2026 } 2027 2028start = JUMP(SLJIT_JUMP); 2029 2030if (newlinecheck) 2031 { 2032 newlinelabel = LABEL(); 2033 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2034 end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2035 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 2036 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); 2037 COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); 2038#ifdef COMPILE_PCRE16 2039 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 2040#endif 2041 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 2042 nl = JUMP(SLJIT_JUMP); 2043 } 2044 2045mainloop = LABEL(); 2046 2047/* Increasing the STR_PTR here requires one less jump in the most common case. */ 2048#ifdef SUPPORT_UTF 2049if (common->utf) readuchar = TRUE; 2050#endif 2051if (newlinecheck) readuchar = TRUE; 2052 2053if (readuchar) 2054 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 2055 2056if (newlinecheck) 2057 CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); 2058 2059OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2060#if defined SUPPORT_UTF && defined COMPILE_PCRE8 2061if (common->utf) 2062 { 2063 singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 2064 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); 2065 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 2066 JUMPHERE(singlechar); 2067 } 2068#endif 2069#if defined SUPPORT_UTF && defined COMPILE_PCRE16 2070if (common->utf) 2071 { 2072 singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); 2073 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 2074 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); 2075 COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); 2076 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 2077 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 2078 JUMPHERE(singlechar); 2079 } 2080#endif 2081JUMPHERE(start); 2082 2083if (newlinecheck) 2084 { 2085 JUMPHERE(end); 2086 JUMPHERE(nl); 2087 } 2088 2089return mainloop; 2090} 2091 2092static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline) 2093{ 2094DEFINE_COMPILER; 2095struct sljit_label *start; 2096struct sljit_jump *leave; 2097struct sljit_jump *found; 2098pcre_uchar oc, bit; 2099 2100if (firstline) 2101 { 2102 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); 2103 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); 2104 } 2105 2106start = LABEL(); 2107leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2108OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 2109 2110oc = first_char; 2111if (caseless) 2112 { 2113 oc = TABLE_GET(first_char, common->fcc, first_char); 2114#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) 2115 if (first_char > 127 && common->utf) 2116 oc = UCD_OTHERCASE(first_char); 2117#endif 2118 } 2119if (first_char == oc) 2120 found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char); 2121else 2122 { 2123 bit = first_char ^ oc; 2124 if (ispowerof2(bit)) 2125 { 2126 OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); 2127 found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit); 2128 } 2129 else 2130 { 2131 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char); 2132 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); 2133 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); 2134 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 2135 found = JUMP(SLJIT_C_NOT_ZERO); 2136 } 2137 } 2138 2139OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2140#if defined SUPPORT_UTF && defined COMPILE_PCRE8 2141if (common->utf) 2142 { 2143 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); 2144 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); 2145 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 2146 } 2147#endif 2148#if defined SUPPORT_UTF && defined COMPILE_PCRE16 2149if (common->utf) 2150 { 2151 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); 2152 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 2153 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); 2154 COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); 2155 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 2156 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 2157 } 2158#endif 2159JUMPTO(SLJIT_JUMP, start); 2160JUMPHERE(found); 2161JUMPHERE(leave); 2162 2163if (firstline) 2164 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); 2165} 2166 2167static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline) 2168{ 2169DEFINE_COMPILER; 2170struct sljit_label *loop; 2171struct sljit_jump *lastchar; 2172struct sljit_jump *firstchar; 2173struct sljit_jump *leave; 2174struct sljit_jump *foundcr = NULL; 2175struct sljit_jump *notfoundnl; 2176jump_list *newline = NULL; 2177 2178if (firstline) 2179 { 2180 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); 2181 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); 2182 } 2183 2184if (common->nltype == NLTYPE_FIXED && common->newline > 255) 2185 { 2186 lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2187 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 2188 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 2189 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 2190 firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); 2191 2192 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); 2193 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); 2194 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL); 2195#ifdef COMPILE_PCRE16 2196 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); 2197#endif 2198 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 2199 2200 loop = LABEL(); 2201 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2202 leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2203 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); 2204 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); 2205 CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); 2206 CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); 2207 2208 JUMPHERE(leave); 2209 JUMPHERE(firstchar); 2210 JUMPHERE(lastchar); 2211 2212 if (firstline) 2213 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); 2214 return; 2215 } 2216 2217OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 2218OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 2219firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); 2220skip_char_back(common); 2221 2222loop = LABEL(); 2223read_char(common); 2224lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2225if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) 2226 foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); 2227check_newlinechar(common, common->nltype, &newline, FALSE); 2228set_jumps(newline, loop); 2229 2230if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) 2231 { 2232 leave = JUMP(SLJIT_JUMP); 2233 JUMPHERE(foundcr); 2234 notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2235 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 2236 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); 2237 COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); 2238#ifdef COMPILE_PCRE16 2239 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 2240#endif 2241 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 2242 JUMPHERE(notfoundnl); 2243 JUMPHERE(leave); 2244 } 2245JUMPHERE(lastchar); 2246JUMPHERE(firstchar); 2247 2248if (firstline) 2249 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); 2250} 2251 2252static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline) 2253{ 2254DEFINE_COMPILER; 2255struct sljit_label *start; 2256struct sljit_jump *leave; 2257struct sljit_jump *found; 2258#ifndef COMPILE_PCRE8 2259struct sljit_jump *jump; 2260#endif 2261 2262if (firstline) 2263 { 2264 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); 2265 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); 2266 } 2267 2268start = LABEL(); 2269leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 2270OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 2271#ifdef SUPPORT_UTF 2272if (common->utf) 2273 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); 2274#endif 2275#ifndef COMPILE_PCRE8 2276jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255); 2277OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); 2278JUMPHERE(jump); 2279#endif 2280OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); 2281OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); 2282OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits); 2283OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); 2284OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); 2285found = JUMP(SLJIT_C_NOT_ZERO); 2286 2287#ifdef SUPPORT_UTF 2288if (common->utf) 2289 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 2290#endif 2291OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2292#if defined SUPPORT_UTF && defined COMPILE_PCRE8 2293if (common->utf) 2294 { 2295 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); 2296 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); 2297 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 2298 } 2299#endif 2300#if defined SUPPORT_UTF && defined COMPILE_PCRE16 2301if (common->utf) 2302 { 2303 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); 2304 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 2305 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); 2306 COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); 2307 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 2308 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 2309 } 2310#endif 2311JUMPTO(SLJIT_JUMP, start); 2312JUMPHERE(found); 2313JUMPHERE(leave); 2314 2315if (firstline) 2316 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); 2317} 2318 2319static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar) 2320{ 2321DEFINE_COMPILER; 2322struct sljit_label *loop; 2323struct sljit_jump *toolong; 2324struct sljit_jump *alreadyfound; 2325struct sljit_jump *found; 2326struct sljit_jump *foundoc = NULL; 2327struct sljit_jump *notfound; 2328pcre_uchar oc, bit; 2329 2330SLJIT_ASSERT(common->req_char_ptr != 0); 2331OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr); 2332OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX); 2333toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); 2334alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); 2335 2336if (has_firstchar) 2337 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2338else 2339 OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); 2340 2341loop = LABEL(); 2342notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0); 2343 2344OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); 2345oc = req_char; 2346if (caseless) 2347 { 2348 oc = TABLE_GET(req_char, common->fcc, req_char); 2349#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) 2350 if (req_char > 127 && common->utf) 2351 oc = UCD_OTHERCASE(req_char); 2352#endif 2353 } 2354if (req_char == oc) 2355 found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); 2356else 2357 { 2358 bit = req_char ^ oc; 2359 if (ispowerof2(bit)) 2360 { 2361 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); 2362 found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); 2363 } 2364 else 2365 { 2366 found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); 2367 foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc); 2368 } 2369 } 2370OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); 2371JUMPTO(SLJIT_JUMP, loop); 2372 2373JUMPHERE(found); 2374if (foundoc) 2375 JUMPHERE(foundoc); 2376OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0); 2377JUMPHERE(alreadyfound); 2378JUMPHERE(toolong); 2379return notfound; 2380} 2381 2382static void do_revertframes(compiler_common *common) 2383{ 2384DEFINE_COMPILER; 2385struct sljit_jump *jump; 2386struct sljit_label *mainloop; 2387 2388sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 2389OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); 2390GET_LOCAL_BASE(TMP3, 0, 0); 2391 2392/* Drop frames until we reach STACK_TOP. */ 2393mainloop = LABEL(); 2394OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); 2395jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); 2396OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); 2397OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); 2398OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w)); 2399OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w)); 2400JUMPTO(SLJIT_JUMP, mainloop); 2401 2402JUMPHERE(jump); 2403jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); 2404/* End of dropping frames. */ 2405sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 2406 2407JUMPHERE(jump); 2408jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin); 2409/* Set string begin. */ 2410OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); 2411OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); 2412OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); 2413JUMPTO(SLJIT_JUMP, mainloop); 2414 2415JUMPHERE(jump); 2416if (common->mark_ptr != 0) 2417 { 2418 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark); 2419 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); 2420 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); 2421 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); 2422 JUMPTO(SLJIT_JUMP, mainloop); 2423 2424 JUMPHERE(jump); 2425 } 2426 2427/* Unknown command. */ 2428OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); 2429JUMPTO(SLJIT_JUMP, mainloop); 2430} 2431 2432static void check_wordboundary(compiler_common *common) 2433{ 2434DEFINE_COMPILER; 2435struct sljit_jump *skipread; 2436#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF 2437struct sljit_jump *jump; 2438#endif 2439 2440SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); 2441 2442sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 2443/* Get type of the previous char, and put it to LOCALS1. */ 2444OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 2445OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 2446OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0); 2447skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); 2448skip_char_back(common); 2449check_start_used_ptr(common); 2450read_char(common); 2451 2452/* Testing char type. */ 2453#ifdef SUPPORT_UCP 2454if (common->use_ucp) 2455 { 2456 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); 2457 jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); 2458 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 2459 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); 2460 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); 2461 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); 2462 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); 2463 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); 2464 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); 2465 JUMPHERE(jump); 2466 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); 2467 } 2468else 2469#endif 2470 { 2471#ifndef COMPILE_PCRE8 2472 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 2473#elif defined SUPPORT_UTF 2474 /* Here LOCALS1 has already been zeroed. */ 2475 jump = NULL; 2476 if (common->utf) 2477 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 2478#endif /* COMPILE_PCRE8 */ 2479 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); 2480 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); 2481 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 2482 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0); 2483#ifndef COMPILE_PCRE8 2484 JUMPHERE(jump); 2485#elif defined SUPPORT_UTF 2486 if (jump != NULL) 2487 JUMPHERE(jump); 2488#endif /* COMPILE_PCRE8 */ 2489 } 2490JUMPHERE(skipread); 2491 2492OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); 2493skipread = check_str_end(common); 2494peek_char(common); 2495 2496/* Testing char type. This is a code duplication. */ 2497#ifdef SUPPORT_UCP 2498if (common->use_ucp) 2499 { 2500 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); 2501 jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); 2502 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 2503 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); 2504 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); 2505 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); 2506 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); 2507 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); 2508 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); 2509 JUMPHERE(jump); 2510 } 2511else 2512#endif 2513 { 2514#ifndef COMPILE_PCRE8 2515 /* TMP2 may be destroyed by peek_char. */ 2516 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); 2517 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 2518#elif defined SUPPORT_UTF 2519 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); 2520 jump = NULL; 2521 if (common->utf) 2522 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 2523#endif 2524 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); 2525 OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); 2526 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); 2527#ifndef COMPILE_PCRE8 2528 JUMPHERE(jump); 2529#elif defined SUPPORT_UTF 2530 if (jump != NULL) 2531 JUMPHERE(jump); 2532#endif /* COMPILE_PCRE8 */ 2533 } 2534JUMPHERE(skipread); 2535 2536OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); 2537sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 2538} 2539 2540static void check_anynewline(compiler_common *common) 2541{ 2542/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ 2543DEFINE_COMPILER; 2544 2545sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 2546 2547OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); 2548OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); 2549COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); 2550OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); 2551#if defined SUPPORT_UTF || defined COMPILE_PCRE16 2552#ifdef COMPILE_PCRE8 2553if (common->utf) 2554 { 2555#endif 2556 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 2557 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); 2558 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); 2559#ifdef COMPILE_PCRE8 2560 } 2561#endif 2562#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ 2563COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 2564sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 2565} 2566 2567static void check_hspace(compiler_common *common) 2568{ 2569/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ 2570DEFINE_COMPILER; 2571 2572sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 2573 2574OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); 2575COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); 2576OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); 2577COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 2578OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); 2579#if defined SUPPORT_UTF || defined COMPILE_PCRE16 2580#ifdef COMPILE_PCRE8 2581if (common->utf) 2582 { 2583#endif 2584 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 2585 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); 2586 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 2587 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); 2588 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 2589 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); 2590 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); 2591 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); 2592 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); 2593 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 2594 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); 2595 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 2596 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); 2597#ifdef COMPILE_PCRE8 2598 } 2599#endif 2600#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ 2601COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 2602 2603sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 2604} 2605 2606static void check_vspace(compiler_common *common) 2607{ 2608/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ 2609DEFINE_COMPILER; 2610 2611sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 2612 2613OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); 2614OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); 2615COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); 2616OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); 2617#if defined SUPPORT_UTF || defined COMPILE_PCRE16 2618#ifdef COMPILE_PCRE8 2619if (common->utf) 2620 { 2621#endif 2622 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 2623 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); 2624 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); 2625#ifdef COMPILE_PCRE8 2626 } 2627#endif 2628#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ 2629COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 2630 2631sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 2632} 2633 2634#define CHAR1 STR_END 2635#define CHAR2 STACK_TOP 2636 2637static void do_casefulcmp(compiler_common *common) 2638{ 2639DEFINE_COMPILER; 2640struct sljit_jump *jump; 2641struct sljit_label *label; 2642 2643sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 2644OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 2645OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); 2646OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0); 2647OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); 2648OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2649 2650label = LABEL(); 2651OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); 2652OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 2653jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); 2654OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); 2655JUMPTO(SLJIT_C_NOT_ZERO, label); 2656 2657JUMPHERE(jump); 2658OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2659OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0); 2660OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 2661sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 2662} 2663 2664#define LCC_TABLE STACK_LIMIT 2665 2666static void do_caselesscmp(compiler_common *common) 2667{ 2668DEFINE_COMPILER; 2669struct sljit_jump *jump; 2670struct sljit_label *label; 2671 2672sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 2673OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 2674 2675OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); 2676OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0); 2677OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0); 2678OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc); 2679OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); 2680OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2681 2682label = LABEL(); 2683OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); 2684OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 2685#ifndef COMPILE_PCRE8 2686jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255); 2687#endif 2688OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); 2689#ifndef COMPILE_PCRE8 2690JUMPHERE(jump); 2691jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255); 2692#endif 2693OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); 2694#ifndef COMPILE_PCRE8 2695JUMPHERE(jump); 2696#endif 2697jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); 2698OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); 2699JUMPTO(SLJIT_C_NOT_ZERO, label); 2700 2701JUMPHERE(jump); 2702OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 2703OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0); 2704OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 2705OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); 2706sljit_emit_fast_return(compiler, RETURN_ADDR, 0); 2707} 2708 2709#undef LCC_TABLE 2710#undef CHAR1 2711#undef CHAR2 2712 2713#if defined SUPPORT_UTF && defined SUPPORT_UCP 2714 2715static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1) 2716{ 2717/* This function would be ineffective to do in JIT level. */ 2718int c1, c2; 2719const pcre_uchar *src2 = args->uchar_ptr; 2720const pcre_uchar *end2 = args->end; 2721 2722while (src1 < end1) 2723 { 2724 if (src2 >= end2) 2725 return (pcre_uchar*)1; 2726 GETCHARINC(c1, src1); 2727 GETCHARINC(c2, src2); 2728 if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL; 2729 } 2730return src2; 2731} 2732 2733#endif /* SUPPORT_UTF && SUPPORT_UCP */ 2734 2735static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc, 2736 compare_context* context, jump_list **backtracks) 2737{ 2738DEFINE_COMPILER; 2739unsigned int othercasebit = 0; 2740pcre_uchar *othercasechar = NULL; 2741#ifdef SUPPORT_UTF 2742int utflength; 2743#endif 2744 2745if (caseless && char_has_othercase(common, cc)) 2746 { 2747 othercasebit = char_get_othercase_bit(common, cc); 2748 SLJIT_ASSERT(othercasebit); 2749 /* Extracting bit difference info. */ 2750#ifdef COMPILE_PCRE8 2751 othercasechar = cc + (othercasebit >> 8); 2752 othercasebit &= 0xff; 2753#else 2754#ifdef COMPILE_PCRE16 2755 othercasechar = cc + (othercasebit >> 9); 2756 if ((othercasebit & 0x100) != 0) 2757 othercasebit = (othercasebit & 0xff) << 8; 2758 else 2759 othercasebit &= 0xff; 2760#endif 2761#endif 2762 } 2763 2764if (context->sourcereg == -1) 2765 { 2766#ifdef COMPILE_PCRE8 2767#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 2768 if (context->length >= 4) 2769 OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 2770 else if (context->length >= 2) 2771 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 2772 else 2773#endif 2774 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 2775#else 2776#ifdef COMPILE_PCRE16 2777#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 2778 if (context->length >= 4) 2779 OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 2780 else 2781#endif 2782 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 2783#endif 2784#endif /* COMPILE_PCRE8 */ 2785 context->sourcereg = TMP2; 2786 } 2787 2788#ifdef SUPPORT_UTF 2789utflength = 1; 2790if (common->utf && HAS_EXTRALEN(*cc)) 2791 utflength += GET_EXTRALEN(*cc); 2792 2793do 2794 { 2795#endif 2796 2797 context->length -= IN_UCHARS(1); 2798#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 2799 2800 /* Unaligned read is supported. */ 2801 if (othercasebit != 0 && othercasechar == cc) 2802 { 2803 context->c.asuchars[context->ucharptr] = *cc | othercasebit; 2804 context->oc.asuchars[context->ucharptr] = othercasebit; 2805 } 2806 else 2807 { 2808 context->c.asuchars[context->ucharptr] = *cc; 2809 context->oc.asuchars[context->ucharptr] = 0; 2810 } 2811 context->ucharptr++; 2812 2813#ifdef COMPILE_PCRE8 2814 if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) 2815#else 2816 if (context->ucharptr >= 2 || context->length == 0) 2817#endif 2818 { 2819 if (context->length >= 4) 2820 OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 2821#ifdef COMPILE_PCRE8 2822 else if (context->length >= 2) 2823 OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 2824 else if (context->length >= 1) 2825 OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 2826#else 2827 else if (context->length >= 2) 2828 OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 2829#endif 2830 context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; 2831 2832 switch(context->ucharptr) 2833 { 2834 case 4 / sizeof(pcre_uchar): 2835 if (context->oc.asint != 0) 2836 OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); 2837 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); 2838 break; 2839 2840 case 2 / sizeof(pcre_uchar): 2841 if (context->oc.asushort != 0) 2842 OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); 2843 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); 2844 break; 2845 2846#ifdef COMPILE_PCRE8 2847 case 1: 2848 if (context->oc.asbyte != 0) 2849 OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); 2850 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); 2851 break; 2852#endif 2853 2854 default: 2855 SLJIT_ASSERT_STOP(); 2856 break; 2857 } 2858 context->ucharptr = 0; 2859 } 2860 2861#else 2862 2863 /* Unaligned read is unsupported. */ 2864#ifdef COMPILE_PCRE8 2865 if (context->length > 0) 2866 OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 2867#else 2868 if (context->length > 0) 2869 OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 2870#endif 2871 context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; 2872 2873 if (othercasebit != 0 && othercasechar == cc) 2874 { 2875 OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); 2876 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); 2877 } 2878 else 2879 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); 2880 2881#endif 2882 2883 cc++; 2884#ifdef SUPPORT_UTF 2885 utflength--; 2886 } 2887while (utflength > 0); 2888#endif 2889 2890return cc; 2891} 2892 2893#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 2894 2895#define SET_TYPE_OFFSET(value) \ 2896 if ((value) != typeoffset) \ 2897 { \ 2898 if ((value) > typeoffset) \ 2899 OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ 2900 else \ 2901 OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ 2902 } \ 2903 typeoffset = (value); 2904 2905#define SET_CHAR_OFFSET(value) \ 2906 if ((value) != charoffset) \ 2907 { \ 2908 if ((value) > charoffset) \ 2909 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \ 2910 else \ 2911 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \ 2912 } \ 2913 charoffset = (value); 2914 2915static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) 2916{ 2917DEFINE_COMPILER; 2918jump_list *found = NULL; 2919jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks; 2920unsigned int c; 2921int compares; 2922struct sljit_jump *jump = NULL; 2923pcre_uchar *ccbegin; 2924#ifdef SUPPORT_UCP 2925BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; 2926BOOL charsaved = FALSE; 2927int typereg = TMP1, scriptreg = TMP1; 2928unsigned int typeoffset; 2929#endif 2930int invertcmp, numberofcmps; 2931unsigned int charoffset; 2932 2933/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ 2934detect_partial_match(common, backtracks); 2935read_char(common); 2936 2937if ((*cc++ & XCL_MAP) != 0) 2938 { 2939 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); 2940#ifndef COMPILE_PCRE8 2941 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 2942#elif defined SUPPORT_UTF 2943 if (common->utf) 2944 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 2945#endif 2946 2947 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); 2948 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); 2949 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); 2950 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); 2951 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); 2952 add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO)); 2953 2954#ifndef COMPILE_PCRE8 2955 JUMPHERE(jump); 2956#elif defined SUPPORT_UTF 2957 if (common->utf) 2958 JUMPHERE(jump); 2959#endif 2960 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 2961#ifdef SUPPORT_UCP 2962 charsaved = TRUE; 2963#endif 2964 cc += 32 / sizeof(pcre_uchar); 2965 } 2966 2967/* Scanning the necessary info. */ 2968ccbegin = cc; 2969compares = 0; 2970while (*cc != XCL_END) 2971 { 2972 compares++; 2973 if (*cc == XCL_SINGLE) 2974 { 2975 cc += 2; 2976#ifdef SUPPORT_UTF 2977 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 2978#endif 2979#ifdef SUPPORT_UCP 2980 needschar = TRUE; 2981#endif 2982 } 2983 else if (*cc == XCL_RANGE) 2984 { 2985 cc += 2; 2986#ifdef SUPPORT_UTF 2987 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 2988#endif 2989 cc++; 2990#ifdef SUPPORT_UTF 2991 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 2992#endif 2993#ifdef SUPPORT_UCP 2994 needschar = TRUE; 2995#endif 2996 } 2997#ifdef SUPPORT_UCP 2998 else 2999 { 3000 SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); 3001 cc++; 3002 switch(*cc) 3003 { 3004 case PT_ANY: 3005 break; 3006 3007 case PT_LAMP: 3008 case PT_GC: 3009 case PT_PC: 3010 case PT_ALNUM: 3011 needstype = TRUE; 3012 break; 3013 3014 case PT_SC: 3015 needsscript = TRUE; 3016 break; 3017 3018 case PT_SPACE: 3019 case PT_PXSPACE: 3020 case PT_WORD: 3021 needstype = TRUE; 3022 needschar = TRUE; 3023 break; 3024 3025 default: 3026 SLJIT_ASSERT_STOP(); 3027 break; 3028 } 3029 cc += 2; 3030 } 3031#endif 3032 } 3033 3034#ifdef SUPPORT_UCP 3035/* Simple register allocation. TMP1 is preferred if possible. */ 3036if (needstype || needsscript) 3037 { 3038 if (needschar && !charsaved) 3039 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); 3040 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 3041 if (needschar) 3042 { 3043 if (needstype) 3044 { 3045 OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); 3046 typereg = RETURN_ADDR; 3047 } 3048 3049 if (needsscript) 3050 scriptreg = TMP3; 3051 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 3052 } 3053 else if (needstype && needsscript) 3054 scriptreg = TMP3; 3055 /* In all other cases only one of them was specified, and that can goes to TMP1. */ 3056 3057 if (needsscript) 3058 { 3059 if (scriptreg == TMP1) 3060 { 3061 OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); 3062 OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3); 3063 } 3064 else 3065 { 3066 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); 3067 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); 3068 OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0); 3069 } 3070 } 3071 } 3072#endif 3073 3074/* Generating code. */ 3075cc = ccbegin; 3076charoffset = 0; 3077numberofcmps = 0; 3078#ifdef SUPPORT_UCP 3079typeoffset = 0; 3080#endif 3081 3082while (*cc != XCL_END) 3083 { 3084 compares--; 3085 invertcmp = (compares == 0 && list != backtracks); 3086 jump = NULL; 3087 3088 if (*cc == XCL_SINGLE) 3089 { 3090 cc ++; 3091#ifdef SUPPORT_UTF 3092 if (common->utf) 3093 { 3094 GETCHARINC(c, cc); 3095 } 3096 else 3097#endif 3098 c = *cc++; 3099 3100 if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) 3101 { 3102 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); 3103 COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 3104 numberofcmps++; 3105 } 3106 else if (numberofcmps > 0) 3107 { 3108 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); 3109 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 3110 jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 3111 numberofcmps = 0; 3112 } 3113 else 3114 { 3115 jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset); 3116 numberofcmps = 0; 3117 } 3118 } 3119 else if (*cc == XCL_RANGE) 3120 { 3121 cc ++; 3122#ifdef SUPPORT_UTF 3123 if (common->utf) 3124 { 3125 GETCHARINC(c, cc); 3126 } 3127 else 3128#endif 3129 c = *cc++; 3130 SET_CHAR_OFFSET(c); 3131#ifdef SUPPORT_UTF 3132 if (common->utf) 3133 { 3134 GETCHARINC(c, cc); 3135 } 3136 else 3137#endif 3138 c = *cc++; 3139 if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) 3140 { 3141 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); 3142 COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); 3143 numberofcmps++; 3144 } 3145 else if (numberofcmps > 0) 3146 { 3147 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); 3148 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); 3149 jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 3150 numberofcmps = 0; 3151 } 3152 else 3153 { 3154 jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset); 3155 numberofcmps = 0; 3156 } 3157 } 3158#ifdef SUPPORT_UCP 3159 else 3160 { 3161 if (*cc == XCL_NOTPROP) 3162 invertcmp ^= 0x1; 3163 cc++; 3164 switch(*cc) 3165 { 3166 case PT_ANY: 3167 if (list != backtracks) 3168 { 3169 if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0)) 3170 continue; 3171 } 3172 else if (cc[-1] == XCL_NOTPROP) 3173 continue; 3174 jump = JUMP(SLJIT_JUMP); 3175 break; 3176 3177 case PT_LAMP: 3178 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); 3179 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); 3180 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); 3181 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); 3182 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); 3183 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 3184 jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 3185 break; 3186 3187 case PT_GC: 3188 c = PRIV(ucp_typerange)[(int)cc[1] * 2]; 3189 SET_TYPE_OFFSET(c); 3190 jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); 3191 break; 3192 3193 case PT_PC: 3194 jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); 3195 break; 3196 3197 case PT_SC: 3198 jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]); 3199 break; 3200 3201 case PT_SPACE: 3202 case PT_PXSPACE: 3203 if (*cc == PT_SPACE) 3204 { 3205 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); 3206 jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset); 3207 } 3208 SET_CHAR_OFFSET(9); 3209 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9); 3210 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); 3211 if (*cc == PT_SPACE) 3212 JUMPHERE(jump); 3213 3214 SET_TYPE_OFFSET(ucp_Zl); 3215 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); 3216 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); 3217 jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 3218 break; 3219 3220 case PT_WORD: 3221 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset); 3222 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); 3223 /* ... fall through */ 3224 3225 case PT_ALNUM: 3226 SET_TYPE_OFFSET(ucp_Ll); 3227 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); 3228 COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); 3229 SET_TYPE_OFFSET(ucp_Nd); 3230 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); 3231 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); 3232 jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 3233 break; 3234 } 3235 cc += 2; 3236 } 3237#endif 3238 3239 if (jump != NULL) 3240 add_jump(compiler, compares > 0 ? list : backtracks, jump); 3241 } 3242 3243if (found != NULL) 3244 set_jumps(found, LABEL()); 3245} 3246 3247#undef SET_TYPE_OFFSET 3248#undef SET_CHAR_OFFSET 3249 3250#endif 3251 3252static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) 3253{ 3254DEFINE_COMPILER; 3255int length; 3256unsigned int c, oc, bit; 3257compare_context context; 3258struct sljit_jump *jump[4]; 3259#ifdef SUPPORT_UTF 3260struct sljit_label *label; 3261#ifdef SUPPORT_UCP 3262pcre_uchar propdata[5]; 3263#endif 3264#endif 3265 3266switch(type) 3267 { 3268 case OP_SOD: 3269 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 3270 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 3271 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); 3272 return cc; 3273 3274 case OP_SOM: 3275 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 3276 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 3277 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); 3278 return cc; 3279 3280 case OP_NOT_WORD_BOUNDARY: 3281 case OP_WORD_BOUNDARY: 3282 add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); 3283 add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 3284 return cc; 3285 3286 case OP_NOT_DIGIT: 3287 case OP_DIGIT: 3288 detect_partial_match(common, backtracks); 3289 read_char8_type(common); 3290 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); 3291 add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); 3292 return cc; 3293 3294 case OP_NOT_WHITESPACE: 3295 case OP_WHITESPACE: 3296 detect_partial_match(common, backtracks); 3297 read_char8_type(common); 3298 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); 3299 add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); 3300 return cc; 3301 3302 case OP_NOT_WORDCHAR: 3303 case OP_WORDCHAR: 3304 detect_partial_match(common, backtracks); 3305 read_char8_type(common); 3306 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); 3307 add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); 3308 return cc; 3309 3310 case OP_ANY: 3311 detect_partial_match(common, backtracks); 3312 read_char(common); 3313 if (common->nltype == NLTYPE_FIXED && common->newline > 255) 3314 { 3315 jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); 3316 if (common->mode != JIT_PARTIAL_HARD_COMPILE) 3317 jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 3318 else 3319 jump[1] = check_str_end(common); 3320 3321 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 3322 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); 3323 if (jump[1] != NULL) 3324 JUMPHERE(jump[1]); 3325 JUMPHERE(jump[0]); 3326 } 3327 else 3328 check_newlinechar(common, common->nltype, backtracks, TRUE); 3329 return cc; 3330 3331 case OP_ALLANY: 3332 detect_partial_match(common, backtracks); 3333#ifdef SUPPORT_UTF 3334 if (common->utf) 3335 { 3336 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 3337 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 3338#ifdef COMPILE_PCRE8 3339 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 3340 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); 3341 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 3342#else /* COMPILE_PCRE8 */ 3343#ifdef COMPILE_PCRE16 3344 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); 3345 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 3346 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); 3347 COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); 3348 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 3349 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 3350#endif /* COMPILE_PCRE16 */ 3351#endif /* COMPILE_PCRE8 */ 3352 JUMPHERE(jump[0]); 3353 return cc; 3354 } 3355#endif 3356 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 3357 return cc; 3358 3359 case OP_ANYBYTE: 3360 detect_partial_match(common, backtracks); 3361 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 3362 return cc; 3363 3364#ifdef SUPPORT_UTF 3365#ifdef SUPPORT_UCP 3366 case OP_NOTPROP: 3367 case OP_PROP: 3368 propdata[0] = 0; 3369 propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; 3370 propdata[2] = cc[0]; 3371 propdata[3] = cc[1]; 3372 propdata[4] = XCL_END; 3373 compile_xclass_trypath(common, propdata, backtracks); 3374 return cc + 2; 3375#endif 3376#endif 3377 3378 case OP_ANYNL: 3379 detect_partial_match(common, backtracks); 3380 read_char(common); 3381 jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); 3382 /* We don't need to handle soft partial matching case. */ 3383 if (common->mode != JIT_PARTIAL_HARD_COMPILE) 3384 jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 3385 else 3386 jump[1] = check_str_end(common); 3387 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 3388 jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); 3389 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 3390 jump[3] = JUMP(SLJIT_JUMP); 3391 JUMPHERE(jump[0]); 3392 check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); 3393 JUMPHERE(jump[1]); 3394 JUMPHERE(jump[2]); 3395 JUMPHERE(jump[3]); 3396 return cc; 3397 3398 case OP_NOT_HSPACE: 3399 case OP_HSPACE: 3400 detect_partial_match(common, backtracks); 3401 read_char(common); 3402 add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); 3403 add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 3404 return cc; 3405 3406 case OP_NOT_VSPACE: 3407 case OP_VSPACE: 3408 detect_partial_match(common, backtracks); 3409 read_char(common); 3410 add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); 3411 add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 3412 return cc; 3413 3414#ifdef SUPPORT_UCP 3415 case OP_EXTUNI: 3416 detect_partial_match(common, backtracks); 3417 read_char(common); 3418 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 3419 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); 3420 add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc)); 3421 3422 label = LABEL(); 3423 jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 3424 OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); 3425 read_char(common); 3426 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 3427 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); 3428 CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label); 3429 3430 OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); 3431 JUMPHERE(jump[0]); 3432 if (common->mode == JIT_PARTIAL_HARD_COMPILE) 3433 { 3434 jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); 3435 /* Since we successfully read a char above, partial matching must occure. */ 3436 check_partial(common, TRUE); 3437 JUMPHERE(jump[0]); 3438 } 3439 return cc; 3440#endif 3441 3442 case OP_EODN: 3443 /* Requires rather complex checks. */ 3444 jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 3445 if (common->nltype == NLTYPE_FIXED && common->newline > 255) 3446 { 3447 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 3448 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 3449 if (common->mode == JIT_COMPILE) 3450 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); 3451 else 3452 { 3453 jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); 3454 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); 3455 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); 3456 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); 3457 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); 3458 add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL)); 3459 check_partial(common, TRUE); 3460 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 3461 JUMPHERE(jump[1]); 3462 } 3463 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 3464 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); 3465 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); 3466 } 3467 else if (common->nltype == NLTYPE_FIXED) 3468 { 3469 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 3470 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 3471 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); 3472 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); 3473 } 3474 else 3475 { 3476 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 3477 jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); 3478 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 3479 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); 3480 jump[2] = JUMP(SLJIT_C_GREATER); 3481 add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS)); 3482 /* Equal. */ 3483 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 3484 jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); 3485 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 3486 3487 JUMPHERE(jump[1]); 3488 if (common->nltype == NLTYPE_ANYCRLF) 3489 { 3490 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 3491 add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0)); 3492 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); 3493 } 3494 else 3495 { 3496 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0); 3497 read_char(common); 3498 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); 3499 add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); 3500 add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); 3501 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); 3502 } 3503 JUMPHERE(jump[2]); 3504 JUMPHERE(jump[3]); 3505 } 3506 JUMPHERE(jump[0]); 3507 check_partial(common, FALSE); 3508 return cc; 3509 3510 case OP_EOD: 3511 add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); 3512 check_partial(common, FALSE); 3513 return cc; 3514 3515 case OP_CIRC: 3516 OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); 3517 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); 3518 add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0)); 3519 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); 3520 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 3521 return cc; 3522 3523 case OP_CIRCM: 3524 OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); 3525 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); 3526 jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0); 3527 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); 3528 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 3529 jump[0] = JUMP(SLJIT_JUMP); 3530 JUMPHERE(jump[1]); 3531 3532 add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); 3533 if (common->nltype == NLTYPE_FIXED && common->newline > 255) 3534 { 3535 OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 3536 add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0)); 3537 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); 3538 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); 3539 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); 3540 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); 3541 } 3542 else 3543 { 3544 skip_char_back(common); 3545 read_char(common); 3546 check_newlinechar(common, common->nltype, backtracks, FALSE); 3547 } 3548 JUMPHERE(jump[0]); 3549 return cc; 3550 3551 case OP_DOLL: 3552 OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); 3553 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); 3554 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 3555 3556 if (!common->endonly) 3557 compile_char1_trypath(common, OP_EODN, cc, backtracks); 3558 else 3559 { 3560 add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); 3561 check_partial(common, FALSE); 3562 } 3563 return cc; 3564 3565 case OP_DOLLM: 3566 jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); 3567 OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); 3568 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); 3569 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 3570 check_partial(common, FALSE); 3571 jump[0] = JUMP(SLJIT_JUMP); 3572 JUMPHERE(jump[1]); 3573 3574 if (common->nltype == NLTYPE_FIXED && common->newline > 255) 3575 { 3576 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 3577 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 3578 if (common->mode == JIT_COMPILE) 3579 add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); 3580 else 3581 { 3582 jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); 3583 /* STR_PTR = STR_END - IN_UCHARS(1) */ 3584 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); 3585 check_partial(common, TRUE); 3586 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 3587 JUMPHERE(jump[1]); 3588 } 3589 3590 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 3591 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); 3592 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); 3593 } 3594 else 3595 { 3596 peek_char(common); 3597 check_newlinechar(common, common->nltype, backtracks, FALSE); 3598 } 3599 JUMPHERE(jump[0]); 3600 return cc; 3601 3602 case OP_CHAR: 3603 case OP_CHARI: 3604 length = 1; 3605#ifdef SUPPORT_UTF 3606 if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); 3607#endif 3608 if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) 3609 { 3610 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); 3611 add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); 3612 3613 context.length = IN_UCHARS(length); 3614 context.sourcereg = -1; 3615#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 3616 context.ucharptr = 0; 3617#endif 3618 return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); 3619 } 3620 detect_partial_match(common, backtracks); 3621 read_char(common); 3622#ifdef SUPPORT_UTF 3623 if (common->utf) 3624 { 3625 GETCHAR(c, cc); 3626 } 3627 else 3628#endif 3629 c = *cc; 3630 if (type == OP_CHAR || !char_has_othercase(common, cc)) 3631 { 3632 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); 3633 return cc + length; 3634 } 3635 oc = char_othercase(common, c); 3636 bit = c ^ oc; 3637 if (ispowerof2(bit)) 3638 { 3639 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); 3640 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); 3641 return cc + length; 3642 } 3643 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); 3644 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); 3645 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); 3646 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 3647 add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); 3648 return cc + length; 3649 3650 case OP_NOT: 3651 case OP_NOTI: 3652 detect_partial_match(common, backtracks); 3653 length = 1; 3654#ifdef SUPPORT_UTF 3655 if (common->utf) 3656 { 3657#ifdef COMPILE_PCRE8 3658 c = *cc; 3659 if (c < 128) 3660 { 3661 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 3662 if (type == OP_NOT || !char_has_othercase(common, cc)) 3663 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); 3664 else 3665 { 3666 /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ 3667 OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); 3668 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); 3669 } 3670 /* Skip the variable-length character. */ 3671 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 3672 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 3673 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); 3674 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 3675 JUMPHERE(jump[0]); 3676 return cc + 1; 3677 } 3678 else 3679#endif /* COMPILE_PCRE8 */ 3680 { 3681 GETCHARLEN(c, cc, length); 3682 read_char(common); 3683 } 3684 } 3685 else 3686#endif /* SUPPORT_UTF */ 3687 { 3688 read_char(common); 3689 c = *cc; 3690 } 3691 3692 if (type == OP_NOT || !char_has_othercase(common, cc)) 3693 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); 3694 else 3695 { 3696 oc = char_othercase(common, c); 3697 bit = c ^ oc; 3698 if (ispowerof2(bit)) 3699 { 3700 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); 3701 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); 3702 } 3703 else 3704 { 3705 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); 3706 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); 3707 } 3708 } 3709 return cc + length; 3710 3711 case OP_CLASS: 3712 case OP_NCLASS: 3713 detect_partial_match(common, backtracks); 3714 read_char(common); 3715#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 3716 jump[0] = NULL; 3717#ifdef COMPILE_PCRE8 3718 /* This check only affects 8 bit mode. In other modes, we 3719 always need to compare the value with 255. */ 3720 if (common->utf) 3721#endif /* COMPILE_PCRE8 */ 3722 { 3723 jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 3724 if (type == OP_CLASS) 3725 { 3726 add_jump(compiler, backtracks, jump[0]); 3727 jump[0] = NULL; 3728 } 3729 } 3730#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ 3731 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); 3732 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); 3733 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); 3734 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); 3735 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); 3736 add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); 3737#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 3738 if (jump[0] != NULL) 3739 JUMPHERE(jump[0]); 3740#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ 3741 return cc + 32 / sizeof(pcre_uchar); 3742 3743#if defined SUPPORT_UTF || defined COMPILE_PCRE16 3744 case OP_XCLASS: 3745 compile_xclass_trypath(common, cc + LINK_SIZE, backtracks); 3746 return cc + GET(cc, 0) - 1; 3747#endif 3748 3749 case OP_REVERSE: 3750 length = GET(cc, 0); 3751 if (length == 0) 3752 return cc + LINK_SIZE; 3753 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 3754#ifdef SUPPORT_UTF 3755 if (common->utf) 3756 { 3757 OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 3758 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); 3759 label = LABEL(); 3760 add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); 3761 skip_char_back(common); 3762 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); 3763 JUMPTO(SLJIT_C_NOT_ZERO, label); 3764 } 3765 else 3766#endif 3767 { 3768 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 3769 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); 3770 add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); 3771 } 3772 check_start_used_ptr(common); 3773 return cc + LINK_SIZE; 3774 } 3775SLJIT_ASSERT_STOP(); 3776return cc; 3777} 3778 3779static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks) 3780{ 3781/* This function consumes at least one input character. */ 3782/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ 3783DEFINE_COMPILER; 3784pcre_uchar *ccbegin = cc; 3785compare_context context; 3786int size; 3787 3788context.length = 0; 3789do 3790 { 3791 if (cc >= ccend) 3792 break; 3793 3794 if (*cc == OP_CHAR) 3795 { 3796 size = 1; 3797#ifdef SUPPORT_UTF 3798 if (common->utf && HAS_EXTRALEN(cc[1])) 3799 size += GET_EXTRALEN(cc[1]); 3800#endif 3801 } 3802 else if (*cc == OP_CHARI) 3803 { 3804 size = 1; 3805#ifdef SUPPORT_UTF 3806 if (common->utf) 3807 { 3808 if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) 3809 size = 0; 3810 else if (HAS_EXTRALEN(cc[1])) 3811 size += GET_EXTRALEN(cc[1]); 3812 } 3813 else 3814#endif 3815 if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) 3816 size = 0; 3817 } 3818 else 3819 size = 0; 3820 3821 cc += 1 + size; 3822 context.length += IN_UCHARS(size); 3823 } 3824while (size > 0 && context.length <= 128); 3825 3826cc = ccbegin; 3827if (context.length > 0) 3828 { 3829 /* We have a fixed-length byte sequence. */ 3830 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); 3831 add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); 3832 3833 context.sourcereg = -1; 3834#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 3835 context.ucharptr = 0; 3836#endif 3837 do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); 3838 return cc; 3839 } 3840 3841/* A non-fixed length character will be checked if length == 0. */ 3842return compile_char1_trypath(common, *cc, cc + 1, backtracks); 3843} 3844 3845static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) 3846{ 3847DEFINE_COMPILER; 3848int offset = GET2(cc, 1) << 1; 3849 3850OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); 3851if (!common->jscript_compat) 3852 { 3853 if (backtracks == NULL) 3854 { 3855 /* OVECTOR(1) contains the "string begin - 1" constant. */ 3856 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); 3857 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); 3858 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); 3859 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); 3860 return JUMP(SLJIT_C_NOT_ZERO); 3861 } 3862 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); 3863 } 3864return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); 3865} 3866 3867/* Forward definitions. */ 3868static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); 3869static void compile_backtrackpath(compiler_common *, struct backtrack_common *); 3870 3871#define PUSH_BACKTRACK(size, ccstart, error) \ 3872 do \ 3873 { \ 3874 backtrack = sljit_alloc_memory(compiler, (size)); \ 3875 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ 3876 return error; \ 3877 memset(backtrack, 0, size); \ 3878 backtrack->prev = parent->top; \ 3879 backtrack->cc = (ccstart); \ 3880 parent->top = backtrack; \ 3881 } \ 3882 while (0) 3883 3884#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \ 3885 do \ 3886 { \ 3887 backtrack = sljit_alloc_memory(compiler, (size)); \ 3888 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ 3889 return; \ 3890 memset(backtrack, 0, size); \ 3891 backtrack->prev = parent->top; \ 3892 backtrack->cc = (ccstart); \ 3893 parent->top = backtrack; \ 3894 } \ 3895 while (0) 3896 3897#define BACKTRACK_AS(type) ((type *)backtrack) 3898 3899static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) 3900{ 3901DEFINE_COMPILER; 3902int offset = GET2(cc, 1) << 1; 3903struct sljit_jump *jump = NULL; 3904struct sljit_jump *partial; 3905struct sljit_jump *nopartial; 3906 3907OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); 3908/* OVECTOR(1) contains the "string begin - 1" constant. */ 3909if (withchecks && !common->jscript_compat) 3910 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); 3911 3912#if defined SUPPORT_UTF && defined SUPPORT_UCP 3913if (common->utf && *cc == OP_REFI) 3914 { 3915 SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3); 3916 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); 3917 if (withchecks) 3918 jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); 3919 3920 /* Needed to save important temporary registers. */ 3921 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); 3922 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); 3923 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0); 3924 sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); 3925 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 3926 if (common->mode == JIT_COMPILE) 3927 add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); 3928 else 3929 { 3930 add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); 3931 nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); 3932 check_partial(common, FALSE); 3933 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 3934 JUMPHERE(nopartial); 3935 } 3936 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); 3937 } 3938else 3939#endif /* SUPPORT_UTF && SUPPORT_UCP */ 3940 { 3941 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); 3942 if (withchecks) 3943 jump = JUMP(SLJIT_C_ZERO); 3944 3945 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 3946 partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); 3947 if (common->mode == JIT_COMPILE) 3948 add_jump(compiler, backtracks, partial); 3949 3950 add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); 3951 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 3952 3953 if (common->mode != JIT_COMPILE) 3954 { 3955 nopartial = JUMP(SLJIT_JUMP); 3956 JUMPHERE(partial); 3957 /* TMP2 -= STR_END - STR_PTR */ 3958 OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); 3959 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); 3960 partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); 3961 OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); 3962 add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); 3963 add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 3964 JUMPHERE(partial); 3965 check_partial(common, FALSE); 3966 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 3967 JUMPHERE(nopartial); 3968 } 3969 } 3970 3971if (jump != NULL) 3972 { 3973 if (emptyfail) 3974 add_jump(compiler, backtracks, jump); 3975 else 3976 JUMPHERE(jump); 3977 } 3978return cc + 1 + IMM2_SIZE; 3979} 3980 3981static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 3982{ 3983DEFINE_COMPILER; 3984backtrack_common *backtrack; 3985pcre_uchar type; 3986struct sljit_label *label; 3987struct sljit_jump *zerolength; 3988struct sljit_jump *jump = NULL; 3989pcre_uchar *ccbegin = cc; 3990int min = 0, max = 0; 3991BOOL minimize; 3992 3993PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); 3994 3995type = cc[1 + IMM2_SIZE]; 3996minimize = (type & 0x1) != 0; 3997switch(type) 3998 { 3999 case OP_CRSTAR: 4000 case OP_CRMINSTAR: 4001 min = 0; 4002 max = 0; 4003 cc += 1 + IMM2_SIZE + 1; 4004 break; 4005 case OP_CRPLUS: 4006 case OP_CRMINPLUS: 4007 min = 1; 4008 max = 0; 4009 cc += 1 + IMM2_SIZE + 1; 4010 break; 4011 case OP_CRQUERY: 4012 case OP_CRMINQUERY: 4013 min = 0; 4014 max = 1; 4015 cc += 1 + IMM2_SIZE + 1; 4016 break; 4017 case OP_CRRANGE: 4018 case OP_CRMINRANGE: 4019 min = GET2(cc, 1 + IMM2_SIZE + 1); 4020 max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE); 4021 cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE; 4022 break; 4023 default: 4024 SLJIT_ASSERT_STOP(); 4025 break; 4026 } 4027 4028if (!minimize) 4029 { 4030 if (min == 0) 4031 { 4032 allocate_stack(common, 2); 4033 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4034 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); 4035 /* Temporary release of STR_PTR. */ 4036 OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); 4037 zerolength = compile_ref_checks(common, ccbegin, NULL); 4038 /* Restore if not zero length. */ 4039 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); 4040 } 4041 else 4042 { 4043 allocate_stack(common, 1); 4044 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 4045 zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); 4046 } 4047 4048 if (min > 1 || max > 1) 4049 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); 4050 4051 label = LABEL(); 4052 compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); 4053 4054 if (min > 1 || max > 1) 4055 { 4056 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); 4057 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 4058 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); 4059 if (min > 1) 4060 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); 4061 if (max > 1) 4062 { 4063 jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); 4064 allocate_stack(common, 1); 4065 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4066 JUMPTO(SLJIT_JUMP, label); 4067 JUMPHERE(jump); 4068 } 4069 } 4070 4071 if (max == 0) 4072 { 4073 /* Includes min > 1 case as well. */ 4074 allocate_stack(common, 1); 4075 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4076 JUMPTO(SLJIT_JUMP, label); 4077 } 4078 4079 JUMPHERE(zerolength); 4080 BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); 4081 4082 decrease_call_count(common); 4083 return cc; 4084 } 4085 4086allocate_stack(common, 2); 4087OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 4088if (type != OP_CRMINSTAR) 4089 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); 4090 4091if (min == 0) 4092 { 4093 zerolength = compile_ref_checks(common, ccbegin, NULL); 4094 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4095 jump = JUMP(SLJIT_JUMP); 4096 } 4097else 4098 zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); 4099 4100BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); 4101if (max > 0) 4102 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); 4103 4104compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); 4105OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4106 4107if (min > 1) 4108 { 4109 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 4110 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 4111 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 4112 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath); 4113 } 4114else if (max > 0) 4115 OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); 4116 4117if (jump != NULL) 4118 JUMPHERE(jump); 4119JUMPHERE(zerolength); 4120 4121decrease_call_count(common); 4122return cc; 4123} 4124 4125static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 4126{ 4127DEFINE_COMPILER; 4128backtrack_common *backtrack; 4129recurse_entry *entry = common->entries; 4130recurse_entry *prev = NULL; 4131int start = GET(cc, 1); 4132 4133PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); 4134while (entry != NULL) 4135 { 4136 if (entry->start == start) 4137 break; 4138 prev = entry; 4139 entry = entry->next; 4140 } 4141 4142if (entry == NULL) 4143 { 4144 entry = sljit_alloc_memory(compiler, sizeof(recurse_entry)); 4145 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 4146 return NULL; 4147 entry->next = NULL; 4148 entry->entry = NULL; 4149 entry->calls = NULL; 4150 entry->start = start; 4151 4152 if (prev != NULL) 4153 prev->next = entry; 4154 else 4155 common->entries = entry; 4156 } 4157 4158if (common->has_set_som && common->mark_ptr != 0) 4159 { 4160 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); 4161 allocate_stack(common, 2); 4162 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); 4163 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 4164 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 4165 } 4166else if (common->has_set_som || common->mark_ptr != 0) 4167 { 4168 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); 4169 allocate_stack(common, 1); 4170 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 4171 } 4172 4173if (entry->entry == NULL) 4174 add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); 4175else 4176 JUMPTO(SLJIT_FAST_CALL, entry->entry); 4177/* Leave if the match is failed. */ 4178add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); 4179return cc + 1 + LINK_SIZE; 4180} 4181 4182static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) 4183{ 4184DEFINE_COMPILER; 4185int framesize; 4186int localptr; 4187backtrack_common altbacktrack; 4188pcre_uchar *ccbegin; 4189pcre_uchar opcode; 4190pcre_uchar bra = OP_BRA; 4191jump_list *tmp = NULL; 4192jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; 4193jump_list **found; 4194/* Saving previous accept variables. */ 4195struct sljit_label *save_leavelabel = common->leavelabel; 4196struct sljit_label *save_acceptlabel = common->acceptlabel; 4197jump_list *save_leave = common->leave; 4198jump_list *save_accept = common->accept; 4199struct sljit_jump *jump; 4200struct sljit_jump *brajump = NULL; 4201 4202if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) 4203 { 4204 SLJIT_ASSERT(!conditional); 4205 bra = *cc; 4206 cc++; 4207 } 4208localptr = PRIV_DATA(cc); 4209SLJIT_ASSERT(localptr != 0); 4210framesize = get_framesize(common, cc, FALSE); 4211backtrack->framesize = framesize; 4212backtrack->localptr = localptr; 4213opcode = *cc; 4214SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); 4215found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; 4216ccbegin = cc; 4217cc += GET(cc, 1); 4218 4219if (bra == OP_BRAMINZERO) 4220 { 4221 /* This is a braminzero backtrack path. */ 4222 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 4223 free_stack(common, 1); 4224 brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 4225 } 4226 4227if (framesize < 0) 4228 { 4229 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); 4230 allocate_stack(common, 1); 4231 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4232 } 4233else 4234 { 4235 allocate_stack(common, framesize + 2); 4236 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4237 OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1)); 4238 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); 4239 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4240 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 4241 init_frame(common, ccbegin, framesize + 1, 2, FALSE); 4242 } 4243 4244memset(&altbacktrack, 0, sizeof(backtrack_common)); 4245common->leavelabel = NULL; 4246common->leave = NULL; 4247while (1) 4248 { 4249 common->acceptlabel = NULL; 4250 common->accept = NULL; 4251 altbacktrack.top = NULL; 4252 altbacktrack.topbacktracks = NULL; 4253 4254 if (*ccbegin == OP_ALT) 4255 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 4256 4257 altbacktrack.cc = ccbegin; 4258 compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); 4259 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 4260 { 4261 common->leavelabel = save_leavelabel; 4262 common->acceptlabel = save_acceptlabel; 4263 common->leave = save_leave; 4264 common->accept = save_accept; 4265 return NULL; 4266 } 4267 common->acceptlabel = LABEL(); 4268 if (common->accept != NULL) 4269 set_jumps(common->accept, common->acceptlabel); 4270 4271 /* Reset stack. */ 4272 if (framesize < 0) 4273 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4274 else { 4275 if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) 4276 { 4277 /* We don't need to keep the STR_PTR, only the previous localptr. */ 4278 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); 4279 } 4280 else 4281 { 4282 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4283 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 4284 } 4285 } 4286 4287 if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) 4288 { 4289 /* We know that STR_PTR was stored on the top of the stack. */ 4290 if (conditional) 4291 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); 4292 else if (bra == OP_BRAZERO) 4293 { 4294 if (framesize < 0) 4295 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); 4296 else 4297 { 4298 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); 4299 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w)); 4300 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); 4301 } 4302 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); 4303 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 4304 } 4305 else if (framesize >= 0) 4306 { 4307 /* For OP_BRA and OP_BRAMINZERO. */ 4308 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); 4309 } 4310 } 4311 add_jump(compiler, found, JUMP(SLJIT_JUMP)); 4312 4313 compile_backtrackpath(common, altbacktrack.top); 4314 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 4315 { 4316 common->leavelabel = save_leavelabel; 4317 common->acceptlabel = save_acceptlabel; 4318 common->leave = save_leave; 4319 common->accept = save_accept; 4320 return NULL; 4321 } 4322 set_jumps(altbacktrack.topbacktracks, LABEL()); 4323 4324 if (*cc != OP_ALT) 4325 break; 4326 4327 ccbegin = cc; 4328 cc += GET(cc, 1); 4329 } 4330/* None of them matched. */ 4331if (common->leave != NULL) 4332 set_jumps(common->leave, LABEL()); 4333 4334if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) 4335 { 4336 /* Assert is failed. */ 4337 if (conditional || bra == OP_BRAZERO) 4338 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 4339 4340 if (framesize < 0) 4341 { 4342 /* The topmost item should be 0. */ 4343 if (bra == OP_BRAZERO) 4344 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 4345 else 4346 free_stack(common, 1); 4347 } 4348 else 4349 { 4350 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 4351 /* The topmost item should be 0. */ 4352 if (bra == OP_BRAZERO) 4353 { 4354 free_stack(common, framesize + 1); 4355 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 4356 } 4357 else 4358 free_stack(common, framesize + 2); 4359 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); 4360 } 4361 jump = JUMP(SLJIT_JUMP); 4362 if (bra != OP_BRAZERO) 4363 add_jump(compiler, target, jump); 4364 4365 /* Assert is successful. */ 4366 set_jumps(tmp, LABEL()); 4367 if (framesize < 0) 4368 { 4369 /* We know that STR_PTR was stored on the top of the stack. */ 4370 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); 4371 /* Keep the STR_PTR on the top of the stack. */ 4372 if (bra == OP_BRAZERO) 4373 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); 4374 else if (bra == OP_BRAMINZERO) 4375 { 4376 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); 4377 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 4378 } 4379 } 4380 else 4381 { 4382 if (bra == OP_BRA) 4383 { 4384 /* We don't need to keep the STR_PTR, only the previous localptr. */ 4385 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); 4386 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); 4387 } 4388 else 4389 { 4390 /* We don't need to keep the STR_PTR, only the previous localptr. */ 4391 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w)); 4392 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 4393 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); 4394 } 4395 } 4396 4397 if (bra == OP_BRAZERO) 4398 { 4399 backtrack->trypath = LABEL(); 4400 sljit_set_label(jump, backtrack->trypath); 4401 } 4402 else if (bra == OP_BRAMINZERO) 4403 { 4404 JUMPTO(SLJIT_JUMP, backtrack->trypath); 4405 JUMPHERE(brajump); 4406 if (framesize >= 0) 4407 { 4408 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4409 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 4410 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); 4411 } 4412 set_jumps(backtrack->common.topbacktracks, LABEL()); 4413 } 4414 } 4415else 4416 { 4417 /* AssertNot is successful. */ 4418 if (framesize < 0) 4419 { 4420 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 4421 if (bra != OP_BRA) 4422 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 4423 else 4424 free_stack(common, 1); 4425 } 4426 else 4427 { 4428 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 4429 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 4430 /* The topmost item should be 0. */ 4431 if (bra != OP_BRA) 4432 { 4433 free_stack(common, framesize + 1); 4434 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 4435 } 4436 else 4437 free_stack(common, framesize + 2); 4438 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); 4439 } 4440 4441 if (bra == OP_BRAZERO) 4442 backtrack->trypath = LABEL(); 4443 else if (bra == OP_BRAMINZERO) 4444 { 4445 JUMPTO(SLJIT_JUMP, backtrack->trypath); 4446 JUMPHERE(brajump); 4447 } 4448 4449 if (bra != OP_BRA) 4450 { 4451 SLJIT_ASSERT(found == &backtrack->common.topbacktracks); 4452 set_jumps(backtrack->common.topbacktracks, LABEL()); 4453 backtrack->common.topbacktracks = NULL; 4454 } 4455 } 4456 4457common->leavelabel = save_leavelabel; 4458common->acceptlabel = save_acceptlabel; 4459common->leave = save_leave; 4460common->accept = save_accept; 4461return cc + 1 + LINK_SIZE; 4462} 4463 4464static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table) 4465{ 4466int condition = FALSE; 4467pcre_uchar *slotA = name_table; 4468pcre_uchar *slotB; 4469sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; 4470sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; 4471sljit_w no_capture; 4472int i; 4473 4474locals += refno & 0xff; 4475refno >>= 8; 4476no_capture = locals[1]; 4477 4478for (i = 0; i < name_count; i++) 4479 { 4480 if (GET2(slotA, 0) == refno) break; 4481 slotA += name_entry_size; 4482 } 4483 4484if (i < name_count) 4485 { 4486 /* Found a name for the number - there can be only one; duplicate names 4487 for different numbers are allowed, but not vice versa. First scan down 4488 for duplicates. */ 4489 4490 slotB = slotA; 4491 while (slotB > name_table) 4492 { 4493 slotB -= name_entry_size; 4494 if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) 4495 { 4496 condition = locals[GET2(slotB, 0) << 1] != no_capture; 4497 if (condition) break; 4498 } 4499 else break; 4500 } 4501 4502 /* Scan up for duplicates */ 4503 if (!condition) 4504 { 4505 slotB = slotA; 4506 for (i++; i < name_count; i++) 4507 { 4508 slotB += name_entry_size; 4509 if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) 4510 { 4511 condition = locals[GET2(slotB, 0) << 1] != no_capture; 4512 if (condition) break; 4513 } 4514 else break; 4515 } 4516 } 4517 } 4518return condition; 4519} 4520 4521static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table) 4522{ 4523int condition = FALSE; 4524pcre_uchar *slotA = name_table; 4525pcre_uchar *slotB; 4526sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; 4527sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; 4528sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)]; 4529int i; 4530 4531for (i = 0; i < name_count; i++) 4532 { 4533 if (GET2(slotA, 0) == recno) break; 4534 slotA += name_entry_size; 4535 } 4536 4537if (i < name_count) 4538 { 4539 /* Found a name for the number - there can be only one; duplicate 4540 names for different numbers are allowed, but not vice versa. First 4541 scan down for duplicates. */ 4542 4543 slotB = slotA; 4544 while (slotB > name_table) 4545 { 4546 slotB -= name_entry_size; 4547 if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) 4548 { 4549 condition = GET2(slotB, 0) == group_num; 4550 if (condition) break; 4551 } 4552 else break; 4553 } 4554 4555 /* Scan up for duplicates */ 4556 if (!condition) 4557 { 4558 slotB = slotA; 4559 for (i++; i < name_count; i++) 4560 { 4561 slotB += name_entry_size; 4562 if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) 4563 { 4564 condition = GET2(slotB, 0) == group_num; 4565 if (condition) break; 4566 } 4567 else break; 4568 } 4569 } 4570 } 4571return condition; 4572} 4573 4574/* 4575 Handling bracketed expressions is probably the most complex part. 4576 4577 Stack layout naming characters: 4578 S - Push the current STR_PTR 4579 0 - Push a 0 (NULL) 4580 A - Push the current STR_PTR. Needed for restoring the STR_PTR 4581 before the next alternative. Not pushed if there are no alternatives. 4582 M - Any values pushed by the current alternative. Can be empty, or anything. 4583 C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack. 4584 L - Push the previous local (pointed by localptr) to the stack 4585 () - opional values stored on the stack 4586 ()* - optonal, can be stored multiple times 4587 4588 The following list shows the regular expression templates, their PCRE byte codes 4589 and stack layout supported by pcre-sljit. 4590 4591 (?:) OP_BRA | OP_KET A M 4592 () OP_CBRA | OP_KET C M 4593 (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )* 4594 OP_SBRA | OP_KETRMAX 0 L M S ( L M S )* 4595 (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )* 4596 OP_SBRA | OP_KETRMIN 0 L M S ( L M S )* 4597 ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )* 4598 OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )* 4599 ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )* 4600 OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )* 4601 (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 ) 4602 (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 ) 4603 ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 ) 4604 ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 ) 4605 (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )* 4606 OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )* 4607 (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )* 4608 OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )* 4609 ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )* 4610 OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )* 4611 ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )* 4612 OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )* 4613 4614 4615 Stack layout naming characters: 4616 A - Push the alternative index (starting from 0) on the stack. 4617 Not pushed if there is no alternatives. 4618 M - Any values pushed by the current alternative. Can be empty, or anything. 4619 4620 The next list shows the possible content of a bracket: 4621 (|) OP_*BRA | OP_ALT ... M A 4622 (?()|) OP_*COND | OP_ALT M A 4623 (?>|) OP_ONCE | OP_ALT ... [stack trace] M A 4624 (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A 4625 Or nothing, if trace is unnecessary 4626*/ 4627 4628static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 4629{ 4630DEFINE_COMPILER; 4631backtrack_common *backtrack; 4632pcre_uchar opcode; 4633int localptr = 0; 4634int offset = 0; 4635int stacksize; 4636pcre_uchar *ccbegin; 4637pcre_uchar *trypath; 4638pcre_uchar bra = OP_BRA; 4639pcre_uchar ket; 4640assert_backtrack *assert; 4641BOOL has_alternatives; 4642struct sljit_jump *jump; 4643struct sljit_jump *skip; 4644struct sljit_label *rmaxlabel = NULL; 4645struct sljit_jump *braminzerojump = NULL; 4646 4647PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); 4648 4649if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) 4650 { 4651 bra = *cc; 4652 cc++; 4653 opcode = *cc; 4654 } 4655 4656opcode = *cc; 4657ccbegin = cc; 4658trypath = ccbegin + 1 + LINK_SIZE; 4659 4660if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) 4661 { 4662 /* Drop this bracket_backtrack. */ 4663 parent->top = backtrack->prev; 4664 return bracketend(cc); 4665 } 4666 4667ket = *(bracketend(cc) - 1 - LINK_SIZE); 4668SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); 4669SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); 4670cc += GET(cc, 1); 4671 4672has_alternatives = *cc == OP_ALT; 4673if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) 4674 { 4675 has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE; 4676 if (*trypath == OP_NRREF) 4677 { 4678 stacksize = GET2(trypath, 1); 4679 if (common->currententry == NULL || stacksize == RREF_ANY) 4680 has_alternatives = FALSE; 4681 else if (common->currententry->start == 0) 4682 has_alternatives = stacksize != 0; 4683 else 4684 has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE); 4685 } 4686 } 4687 4688if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) 4689 opcode = OP_SCOND; 4690if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) 4691 opcode = OP_ONCE; 4692 4693if (opcode == OP_CBRA || opcode == OP_SCBRA) 4694 { 4695 /* Capturing brackets has a pre-allocated space. */ 4696 offset = GET2(ccbegin, 1 + LINK_SIZE); 4697 localptr = OVECTOR_PRIV(offset); 4698 offset <<= 1; 4699 BACKTRACK_AS(bracket_backtrack)->localptr = localptr; 4700 trypath += IMM2_SIZE; 4701 } 4702else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) 4703 { 4704 /* Other brackets simply allocate the next entry. */ 4705 localptr = PRIV_DATA(ccbegin); 4706 SLJIT_ASSERT(localptr != 0); 4707 BACKTRACK_AS(bracket_backtrack)->localptr = localptr; 4708 if (opcode == OP_ONCE) 4709 BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE); 4710 } 4711 4712/* Instructions before the first alternative. */ 4713stacksize = 0; 4714if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) 4715 stacksize++; 4716if (bra == OP_BRAZERO) 4717 stacksize++; 4718 4719if (stacksize > 0) 4720 allocate_stack(common, stacksize); 4721 4722stacksize = 0; 4723if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) 4724 { 4725 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); 4726 stacksize++; 4727 } 4728 4729if (bra == OP_BRAZERO) 4730 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 4731 4732if (bra == OP_BRAMINZERO) 4733 { 4734 /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */ 4735 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 4736 if (ket != OP_KETRMIN) 4737 { 4738 free_stack(common, 1); 4739 braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 4740 } 4741 else 4742 { 4743 if (opcode == OP_ONCE || opcode >= OP_SBRA) 4744 { 4745 jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 4746 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 4747 /* Nothing stored during the first run. */ 4748 skip = JUMP(SLJIT_JUMP); 4749 JUMPHERE(jump); 4750 /* Checking zero-length iteration. */ 4751 if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) 4752 { 4753 /* When we come from outside, localptr contains the previous STR_PTR. */ 4754 braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4755 } 4756 else 4757 { 4758 /* Except when the whole stack frame must be saved. */ 4759 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4760 braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w)); 4761 } 4762 JUMPHERE(skip); 4763 } 4764 else 4765 { 4766 jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 4767 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 4768 JUMPHERE(jump); 4769 } 4770 } 4771 } 4772 4773if (ket == OP_KETRMIN) 4774 BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); 4775 4776if (ket == OP_KETRMAX) 4777 { 4778 rmaxlabel = LABEL(); 4779 if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) 4780 BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel; 4781 } 4782 4783/* Handling capturing brackets and alternatives. */ 4784if (opcode == OP_ONCE) 4785 { 4786 if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) 4787 { 4788 /* Neither capturing brackets nor recursions are not found in the block. */ 4789 if (ket == OP_KETRMIN) 4790 { 4791 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4792 allocate_stack(common, 2); 4793 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4794 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); 4795 OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); 4796 } 4797 else if (ket == OP_KETRMAX || has_alternatives) 4798 { 4799 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); 4800 allocate_stack(common, 1); 4801 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4802 } 4803 else 4804 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); 4805 } 4806 else 4807 { 4808 if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) 4809 { 4810 allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2); 4811 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4812 OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1)); 4813 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4814 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); 4815 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 4816 init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE); 4817 } 4818 else 4819 { 4820 allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1); 4821 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4822 OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize)); 4823 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); 4824 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); 4825 init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE); 4826 } 4827 } 4828 } 4829else if (opcode == OP_CBRA || opcode == OP_SCBRA) 4830 { 4831 /* Saving the previous values. */ 4832 allocate_stack(common, 3); 4833 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); 4834 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); 4835 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); 4836 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); 4837 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4838 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); 4839 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); 4840 } 4841else if (opcode == OP_SBRA || opcode == OP_SCOND) 4842 { 4843 /* Saving the previous value. */ 4844 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4845 allocate_stack(common, 1); 4846 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); 4847 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 4848 } 4849else if (has_alternatives) 4850 { 4851 /* Pushing the starting string pointer. */ 4852 allocate_stack(common, 1); 4853 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 4854 } 4855 4856/* Generating code for the first alternative. */ 4857if (opcode == OP_COND || opcode == OP_SCOND) 4858 { 4859 if (*trypath == OP_CREF) 4860 { 4861 SLJIT_ASSERT(has_alternatives); 4862 add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), 4863 CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); 4864 trypath += 1 + IMM2_SIZE; 4865 } 4866 else if (*trypath == OP_NCREF) 4867 { 4868 SLJIT_ASSERT(has_alternatives); 4869 stacksize = GET2(trypath, 1); 4870 jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); 4871 4872 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); 4873 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); 4874 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); 4875 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w))); 4876 GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); 4877 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); 4878 sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); 4879 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); 4880 add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); 4881 4882 JUMPHERE(jump); 4883 trypath += 1 + IMM2_SIZE; 4884 } 4885 else if (*trypath == OP_RREF || *trypath == OP_NRREF) 4886 { 4887 /* Never has other case. */ 4888 BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; 4889 4890 stacksize = GET2(trypath, 1); 4891 if (common->currententry == NULL) 4892 stacksize = 0; 4893 else if (stacksize == RREF_ANY) 4894 stacksize = 1; 4895 else if (common->currententry->start == 0) 4896 stacksize = stacksize == 0; 4897 else 4898 stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE); 4899 4900 if (*trypath == OP_RREF || stacksize || common->currententry == NULL) 4901 { 4902 SLJIT_ASSERT(!has_alternatives); 4903 if (stacksize != 0) 4904 trypath += 1 + IMM2_SIZE; 4905 else 4906 { 4907 if (*cc == OP_ALT) 4908 { 4909 trypath = cc + 1 + LINK_SIZE; 4910 cc += GET(cc, 1); 4911 } 4912 else 4913 trypath = cc; 4914 } 4915 } 4916 else 4917 { 4918 SLJIT_ASSERT(has_alternatives); 4919 4920 stacksize = GET2(trypath, 1); 4921 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); 4922 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); 4923 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); 4924 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); 4925 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); 4926 GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); 4927 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); 4928 sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); 4929 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); 4930 add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); 4931 trypath += 1 + IMM2_SIZE; 4932 } 4933 } 4934 else 4935 { 4936 SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT); 4937 /* Similar code as PUSH_BACKTRACK macro. */ 4938 assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack)); 4939 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 4940 return NULL; 4941 memset(assert, 0, sizeof(assert_backtrack)); 4942 assert->common.cc = trypath; 4943 BACKTRACK_AS(bracket_backtrack)->u.assert = assert; 4944 trypath = compile_assert_trypath(common, trypath, assert, TRUE); 4945 } 4946 } 4947 4948compile_trypath(common, trypath, cc, backtrack); 4949if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 4950 return NULL; 4951 4952if (opcode == OP_ONCE) 4953 { 4954 if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) 4955 { 4956 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 4957 /* TMP2 which is set here used by OP_KETRMAX below. */ 4958 if (ket == OP_KETRMAX) 4959 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); 4960 else if (ket == OP_KETRMIN) 4961 { 4962 /* Move the STR_PTR to the localptr. */ 4963 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); 4964 } 4965 } 4966 else 4967 { 4968 stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1; 4969 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w)); 4970 if (ket == OP_KETRMAX) 4971 { 4972 /* TMP2 which is set here used by OP_KETRMAX below. */ 4973 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 4974 } 4975 } 4976 } 4977 4978stacksize = 0; 4979if (ket != OP_KET || bra != OP_BRA) 4980 stacksize++; 4981if (has_alternatives && opcode != OP_ONCE) 4982 stacksize++; 4983 4984if (stacksize > 0) 4985 allocate_stack(common, stacksize); 4986 4987stacksize = 0; 4988if (ket != OP_KET) 4989 { 4990 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 4991 stacksize++; 4992 } 4993else if (bra != OP_BRA) 4994 { 4995 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); 4996 stacksize++; 4997 } 4998 4999if (has_alternatives) 5000 { 5001 if (opcode != OP_ONCE) 5002 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); 5003 if (ket != OP_KETRMAX) 5004 BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); 5005 } 5006 5007/* Must be after the trypath label. */ 5008if (offset != 0) 5009 { 5010 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 5011 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); 5012 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); 5013 } 5014 5015if (ket == OP_KETRMAX) 5016 { 5017 if (opcode == OP_ONCE || opcode >= OP_SBRA) 5018 { 5019 if (has_alternatives) 5020 BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); 5021 /* Checking zero-length iteration. */ 5022 if (opcode != OP_ONCE) 5023 { 5024 CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel); 5025 /* Drop STR_PTR for greedy plus quantifier. */ 5026 if (bra != OP_BRAZERO) 5027 free_stack(common, 1); 5028 } 5029 else 5030 /* TMP2 must contain the starting STR_PTR. */ 5031 CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel); 5032 } 5033 else 5034 JUMPTO(SLJIT_JUMP, rmaxlabel); 5035 BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); 5036 } 5037 5038if (bra == OP_BRAZERO) 5039 BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL(); 5040 5041if (bra == OP_BRAMINZERO) 5042 { 5043 /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ 5044 JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath); 5045 if (braminzerojump != NULL) 5046 { 5047 JUMPHERE(braminzerojump); 5048 /* We need to release the end pointer to perform the 5049 backtrack for the zero-length iteration. When 5050 framesize is < 0, OP_ONCE will do the release itself. */ 5051 if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) 5052 { 5053 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 5054 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 5055 } 5056 else if (ket == OP_KETRMIN && opcode != OP_ONCE) 5057 free_stack(common, 1); 5058 } 5059 /* Continue to the normal backtrack. */ 5060 } 5061 5062if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) 5063 decrease_call_count(common); 5064 5065/* Skip the other alternatives. */ 5066while (*cc == OP_ALT) 5067 cc += GET(cc, 1); 5068cc += 1 + LINK_SIZE; 5069return cc; 5070} 5071 5072static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 5073{ 5074DEFINE_COMPILER; 5075backtrack_common *backtrack; 5076pcre_uchar opcode; 5077int localptr; 5078int cbraprivptr = 0; 5079int framesize; 5080int stacksize; 5081int offset = 0; 5082BOOL zero = FALSE; 5083pcre_uchar *ccbegin = NULL; 5084int stack; 5085struct sljit_label *loop = NULL; 5086struct jump_list *emptymatch = NULL; 5087 5088PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL); 5089if (*cc == OP_BRAPOSZERO) 5090 { 5091 zero = TRUE; 5092 cc++; 5093 } 5094 5095opcode = *cc; 5096localptr = PRIV_DATA(cc); 5097SLJIT_ASSERT(localptr != 0); 5098BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr; 5099switch(opcode) 5100 { 5101 case OP_BRAPOS: 5102 case OP_SBRAPOS: 5103 ccbegin = cc + 1 + LINK_SIZE; 5104 break; 5105 5106 case OP_CBRAPOS: 5107 case OP_SCBRAPOS: 5108 offset = GET2(cc, 1 + LINK_SIZE); 5109 cbraprivptr = OVECTOR_PRIV(offset); 5110 offset <<= 1; 5111 ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE; 5112 break; 5113 5114 default: 5115 SLJIT_ASSERT_STOP(); 5116 break; 5117 } 5118 5119framesize = get_framesize(common, cc, FALSE); 5120BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; 5121if (framesize < 0) 5122 { 5123 stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1; 5124 if (!zero) 5125 stacksize++; 5126 BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; 5127 allocate_stack(common, stacksize); 5128 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); 5129 5130 if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) 5131 { 5132 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); 5133 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); 5134 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); 5135 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); 5136 } 5137 else 5138 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5139 5140 if (!zero) 5141 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1); 5142 } 5143else 5144 { 5145 stacksize = framesize + 1; 5146 if (!zero) 5147 stacksize++; 5148 if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) 5149 stacksize++; 5150 BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; 5151 allocate_stack(common, stacksize); 5152 5153 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 5154 OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); 5155 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); 5156 stack = 0; 5157 if (!zero) 5158 { 5159 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); 5160 stack++; 5161 } 5162 if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) 5163 { 5164 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); 5165 stack++; 5166 } 5167 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); 5168 init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE); 5169 } 5170 5171if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) 5172 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); 5173 5174loop = LABEL(); 5175while (*cc != OP_KETRPOS) 5176 { 5177 backtrack->top = NULL; 5178 backtrack->topbacktracks = NULL; 5179 cc += GET(cc, 1); 5180 5181 compile_trypath(common, ccbegin, cc, backtrack); 5182 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 5183 return NULL; 5184 5185 if (framesize < 0) 5186 { 5187 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 5188 5189 if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) 5190 { 5191 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); 5192 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); 5193 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); 5194 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); 5195 } 5196 else 5197 { 5198 if (opcode == OP_SBRAPOS) 5199 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5200 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5201 } 5202 5203 if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) 5204 add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); 5205 5206 if (!zero) 5207 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); 5208 } 5209 else 5210 { 5211 if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) 5212 { 5213 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w)); 5214 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); 5215 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); 5216 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); 5217 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); 5218 } 5219 else 5220 { 5221 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 5222 OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w)); 5223 if (opcode == OP_SBRAPOS) 5224 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); 5225 OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0); 5226 } 5227 5228 if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) 5229 add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); 5230 5231 if (!zero) 5232 { 5233 if (framesize < 0) 5234 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); 5235 else 5236 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 5237 } 5238 } 5239 JUMPTO(SLJIT_JUMP, loop); 5240 flush_stubs(common); 5241 5242 compile_backtrackpath(common, backtrack->top); 5243 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 5244 return NULL; 5245 set_jumps(backtrack->topbacktracks, LABEL()); 5246 5247 if (framesize < 0) 5248 { 5249 if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) 5250 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); 5251 else 5252 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5253 } 5254 else 5255 { 5256 if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) 5257 { 5258 /* Last alternative. */ 5259 if (*cc == OP_KETRPOS) 5260 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 5261 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); 5262 } 5263 else 5264 { 5265 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 5266 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); 5267 } 5268 } 5269 5270 if (*cc == OP_KETRPOS) 5271 break; 5272 ccbegin = cc + 1 + LINK_SIZE; 5273 } 5274 5275backtrack->topbacktracks = NULL; 5276if (!zero) 5277 { 5278 if (framesize < 0) 5279 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); 5280 else /* TMP2 is set to [localptr] above. */ 5281 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0)); 5282 } 5283 5284/* None of them matched. */ 5285set_jumps(emptymatch, LABEL()); 5286decrease_call_count(common); 5287return cc + 1 + LINK_SIZE; 5288} 5289 5290static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end) 5291{ 5292int class_len; 5293 5294*opcode = *cc; 5295if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO) 5296 { 5297 cc++; 5298 *type = OP_CHAR; 5299 } 5300else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI) 5301 { 5302 cc++; 5303 *type = OP_CHARI; 5304 *opcode -= OP_STARI - OP_STAR; 5305 } 5306else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO) 5307 { 5308 cc++; 5309 *type = OP_NOT; 5310 *opcode -= OP_NOTSTAR - OP_STAR; 5311 } 5312else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI) 5313 { 5314 cc++; 5315 *type = OP_NOTI; 5316 *opcode -= OP_NOTSTARI - OP_STAR; 5317 } 5318else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) 5319 { 5320 cc++; 5321 *opcode -= OP_TYPESTAR - OP_STAR; 5322 *type = 0; 5323 } 5324else 5325 { 5326 SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS); 5327 *type = *opcode; 5328 cc++; 5329 class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0); 5330 *opcode = cc[class_len - 1]; 5331 if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) 5332 { 5333 *opcode -= OP_CRSTAR - OP_STAR; 5334 if (end != NULL) 5335 *end = cc + class_len; 5336 } 5337 else 5338 { 5339 SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE); 5340 *arg1 = GET2(cc, (class_len + IMM2_SIZE)); 5341 *arg2 = GET2(cc, class_len); 5342 5343 if (*arg2 == 0) 5344 { 5345 SLJIT_ASSERT(*arg1 != 0); 5346 *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO; 5347 } 5348 if (*arg1 == *arg2) 5349 *opcode = OP_EXACT; 5350 5351 if (end != NULL) 5352 *end = cc + class_len + 2 * IMM2_SIZE; 5353 } 5354 return cc; 5355 } 5356 5357if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO) 5358 { 5359 *arg1 = GET2(cc, 0); 5360 cc += IMM2_SIZE; 5361 } 5362 5363if (*type == 0) 5364 { 5365 *type = *cc; 5366 if (end != NULL) 5367 *end = next_opcode(common, cc); 5368 cc++; 5369 return cc; 5370 } 5371 5372if (end != NULL) 5373 { 5374 *end = cc + 1; 5375#ifdef SUPPORT_UTF 5376 if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); 5377#endif 5378 } 5379return cc; 5380} 5381 5382static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 5383{ 5384DEFINE_COMPILER; 5385backtrack_common *backtrack; 5386pcre_uchar opcode; 5387pcre_uchar type; 5388int arg1 = -1, arg2 = -1; 5389pcre_uchar* end; 5390jump_list *nomatch = NULL; 5391struct sljit_jump *jump = NULL; 5392struct sljit_label *label; 5393 5394PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); 5395 5396cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); 5397 5398switch(opcode) 5399 { 5400 case OP_STAR: 5401 case OP_PLUS: 5402 case OP_UPTO: 5403 case OP_CRRANGE: 5404 if (type == OP_ANYNL || type == OP_EXTUNI) 5405 { 5406 if (opcode == OP_STAR || opcode == OP_UPTO) 5407 { 5408 allocate_stack(common, 2); 5409 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5410 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); 5411 } 5412 else 5413 { 5414 allocate_stack(common, 1); 5415 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 5416 } 5417 if (opcode == OP_UPTO || opcode == OP_CRRANGE) 5418 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); 5419 5420 label = LABEL(); 5421 compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); 5422 if (opcode == OP_UPTO || opcode == OP_CRRANGE) 5423 { 5424 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); 5425 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 5426 if (opcode == OP_CRRANGE && arg2 > 0) 5427 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label); 5428 if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0)) 5429 jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1); 5430 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); 5431 } 5432 5433 allocate_stack(common, 1); 5434 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5435 JUMPTO(SLJIT_JUMP, label); 5436 if (jump != NULL) 5437 JUMPHERE(jump); 5438 } 5439 else 5440 { 5441 if (opcode == OP_PLUS) 5442 compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); 5443 allocate_stack(common, 2); 5444 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5445 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); 5446 label = LABEL(); 5447 compile_char1_trypath(common, type, cc, &nomatch); 5448 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5449 if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0)) 5450 { 5451 OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); 5452 JUMPTO(SLJIT_JUMP, label); 5453 } 5454 else 5455 { 5456 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 5457 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 5458 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 5459 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); 5460 } 5461 set_jumps(nomatch, LABEL()); 5462 if (opcode == OP_CRRANGE) 5463 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1)); 5464 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5465 } 5466 BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); 5467 break; 5468 5469 case OP_MINSTAR: 5470 case OP_MINPLUS: 5471 if (opcode == OP_MINPLUS) 5472 compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); 5473 allocate_stack(common, 1); 5474 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5475 BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); 5476 break; 5477 5478 case OP_MINUPTO: 5479 case OP_CRMINRANGE: 5480 allocate_stack(common, 2); 5481 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5482 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); 5483 if (opcode == OP_CRMINRANGE) 5484 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); 5485 BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); 5486 break; 5487 5488 case OP_QUERY: 5489 case OP_MINQUERY: 5490 allocate_stack(common, 1); 5491 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5492 if (opcode == OP_QUERY) 5493 compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); 5494 BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); 5495 break; 5496 5497 case OP_EXACT: 5498 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); 5499 label = LABEL(); 5500 compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); 5501 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); 5502 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 5503 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); 5504 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); 5505 break; 5506 5507 case OP_POSSTAR: 5508 case OP_POSPLUS: 5509 case OP_POSUPTO: 5510 if (opcode != OP_POSSTAR) 5511 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); 5512 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); 5513 label = LABEL(); 5514 compile_char1_trypath(common, type, cc, &nomatch); 5515 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); 5516 if (opcode != OP_POSUPTO) 5517 { 5518 if (opcode == OP_POSPLUS) 5519 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2); 5520 JUMPTO(SLJIT_JUMP, label); 5521 } 5522 else 5523 { 5524 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); 5525 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 5526 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); 5527 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); 5528 } 5529 set_jumps(nomatch, LABEL()); 5530 if (opcode == OP_POSPLUS) 5531 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2)); 5532 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); 5533 break; 5534 5535 case OP_POSQUERY: 5536 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); 5537 compile_char1_trypath(common, type, cc, &nomatch); 5538 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); 5539 set_jumps(nomatch, LABEL()); 5540 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); 5541 break; 5542 5543 default: 5544 SLJIT_ASSERT_STOP(); 5545 break; 5546 } 5547 5548decrease_call_count(common); 5549return end; 5550} 5551 5552static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 5553{ 5554DEFINE_COMPILER; 5555backtrack_common *backtrack; 5556 5557PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); 5558 5559if (*cc == OP_FAIL) 5560 { 5561 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); 5562 return cc + 1; 5563 } 5564 5565if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL) 5566 { 5567 /* No need to check notempty conditions. */ 5568 if (common->acceptlabel == NULL) 5569 add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); 5570 else 5571 JUMPTO(SLJIT_JUMP, common->acceptlabel); 5572 return cc + 1; 5573 } 5574 5575if (common->acceptlabel == NULL) 5576 add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0))); 5577else 5578 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel); 5579OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 5580OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); 5581add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 5582OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); 5583if (common->acceptlabel == NULL) 5584 add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 5585else 5586 CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel); 5587OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 5588if (common->acceptlabel == NULL) 5589 add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); 5590else 5591 CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel); 5592add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); 5593return cc + 1; 5594} 5595 5596static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc) 5597{ 5598DEFINE_COMPILER; 5599int offset = GET2(cc, 1); 5600 5601/* Data will be discarded anyway... */ 5602if (common->currententry != NULL) 5603 return cc + 1 + IMM2_SIZE; 5604 5605OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset)); 5606offset <<= 1; 5607OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); 5608OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); 5609return cc + 1 + IMM2_SIZE; 5610} 5611 5612static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) 5613{ 5614DEFINE_COMPILER; 5615backtrack_common *backtrack; 5616 5617while (cc < ccend) 5618 { 5619 switch(*cc) 5620 { 5621 case OP_SOD: 5622 case OP_SOM: 5623 case OP_NOT_WORD_BOUNDARY: 5624 case OP_WORD_BOUNDARY: 5625 case OP_NOT_DIGIT: 5626 case OP_DIGIT: 5627 case OP_NOT_WHITESPACE: 5628 case OP_WHITESPACE: 5629 case OP_NOT_WORDCHAR: 5630 case OP_WORDCHAR: 5631 case OP_ANY: 5632 case OP_ALLANY: 5633 case OP_ANYBYTE: 5634 case OP_NOTPROP: 5635 case OP_PROP: 5636 case OP_ANYNL: 5637 case OP_NOT_HSPACE: 5638 case OP_HSPACE: 5639 case OP_NOT_VSPACE: 5640 case OP_VSPACE: 5641 case OP_EXTUNI: 5642 case OP_EODN: 5643 case OP_EOD: 5644 case OP_CIRC: 5645 case OP_CIRCM: 5646 case OP_DOLL: 5647 case OP_DOLLM: 5648 case OP_NOT: 5649 case OP_NOTI: 5650 case OP_REVERSE: 5651 cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 5652 break; 5653 5654 case OP_SET_SOM: 5655 PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); 5656 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); 5657 allocate_stack(common, 1); 5658 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); 5659 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 5660 cc++; 5661 break; 5662 5663 case OP_CHAR: 5664 case OP_CHARI: 5665 if (common->mode == JIT_COMPILE) 5666 cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 5667 else 5668 cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 5669 break; 5670 5671 case OP_STAR: 5672 case OP_MINSTAR: 5673 case OP_PLUS: 5674 case OP_MINPLUS: 5675 case OP_QUERY: 5676 case OP_MINQUERY: 5677 case OP_UPTO: 5678 case OP_MINUPTO: 5679 case OP_EXACT: 5680 case OP_POSSTAR: 5681 case OP_POSPLUS: 5682 case OP_POSQUERY: 5683 case OP_POSUPTO: 5684 case OP_STARI: 5685 case OP_MINSTARI: 5686 case OP_PLUSI: 5687 case OP_MINPLUSI: 5688 case OP_QUERYI: 5689 case OP_MINQUERYI: 5690 case OP_UPTOI: 5691 case OP_MINUPTOI: 5692 case OP_EXACTI: 5693 case OP_POSSTARI: 5694 case OP_POSPLUSI: 5695 case OP_POSQUERYI: 5696 case OP_POSUPTOI: 5697 case OP_NOTSTAR: 5698 case OP_NOTMINSTAR: 5699 case OP_NOTPLUS: 5700 case OP_NOTMINPLUS: 5701 case OP_NOTQUERY: 5702 case OP_NOTMINQUERY: 5703 case OP_NOTUPTO: 5704 case OP_NOTMINUPTO: 5705 case OP_NOTEXACT: 5706 case OP_NOTPOSSTAR: 5707 case OP_NOTPOSPLUS: 5708 case OP_NOTPOSQUERY: 5709 case OP_NOTPOSUPTO: 5710 case OP_NOTSTARI: 5711 case OP_NOTMINSTARI: 5712 case OP_NOTPLUSI: 5713 case OP_NOTMINPLUSI: 5714 case OP_NOTQUERYI: 5715 case OP_NOTMINQUERYI: 5716 case OP_NOTUPTOI: 5717 case OP_NOTMINUPTOI: 5718 case OP_NOTEXACTI: 5719 case OP_NOTPOSSTARI: 5720 case OP_NOTPOSPLUSI: 5721 case OP_NOTPOSQUERYI: 5722 case OP_NOTPOSUPTOI: 5723 case OP_TYPESTAR: 5724 case OP_TYPEMINSTAR: 5725 case OP_TYPEPLUS: 5726 case OP_TYPEMINPLUS: 5727 case OP_TYPEQUERY: 5728 case OP_TYPEMINQUERY: 5729 case OP_TYPEUPTO: 5730 case OP_TYPEMINUPTO: 5731 case OP_TYPEEXACT: 5732 case OP_TYPEPOSSTAR: 5733 case OP_TYPEPOSPLUS: 5734 case OP_TYPEPOSQUERY: 5735 case OP_TYPEPOSUPTO: 5736 cc = compile_iterator_trypath(common, cc, parent); 5737 break; 5738 5739 case OP_CLASS: 5740 case OP_NCLASS: 5741 if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE) 5742 cc = compile_iterator_trypath(common, cc, parent); 5743 else 5744 cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 5745 break; 5746 5747#if defined SUPPORT_UTF || defined COMPILE_PCRE16 5748 case OP_XCLASS: 5749 if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) 5750 cc = compile_iterator_trypath(common, cc, parent); 5751 else 5752 cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 5753 break; 5754#endif 5755 5756 case OP_REF: 5757 case OP_REFI: 5758 if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE) 5759 cc = compile_ref_iterator_trypath(common, cc, parent); 5760 else 5761 cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); 5762 break; 5763 5764 case OP_RECURSE: 5765 cc = compile_recurse_trypath(common, cc, parent); 5766 break; 5767 5768 case OP_ASSERT: 5769 case OP_ASSERT_NOT: 5770 case OP_ASSERTBACK: 5771 case OP_ASSERTBACK_NOT: 5772 PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); 5773 cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); 5774 break; 5775 5776 case OP_BRAMINZERO: 5777 PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc); 5778 cc = bracketend(cc + 1); 5779 if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) 5780 { 5781 allocate_stack(common, 1); 5782 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5783 } 5784 else 5785 { 5786 allocate_stack(common, 2); 5787 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 5788 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); 5789 } 5790 BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL(); 5791 if (cc[1] > OP_ASSERTBACK_NOT) 5792 decrease_call_count(common); 5793 break; 5794 5795 case OP_ONCE: 5796 case OP_ONCE_NC: 5797 case OP_BRA: 5798 case OP_CBRA: 5799 case OP_COND: 5800 case OP_SBRA: 5801 case OP_SCBRA: 5802 case OP_SCOND: 5803 cc = compile_bracket_trypath(common, cc, parent); 5804 break; 5805 5806 case OP_BRAZERO: 5807 if (cc[1] > OP_ASSERTBACK_NOT) 5808 cc = compile_bracket_trypath(common, cc, parent); 5809 else 5810 { 5811 PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); 5812 cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); 5813 } 5814 break; 5815 5816 case OP_BRAPOS: 5817 case OP_CBRAPOS: 5818 case OP_SBRAPOS: 5819 case OP_SCBRAPOS: 5820 case OP_BRAPOSZERO: 5821 cc = compile_bracketpos_trypath(common, cc, parent); 5822 break; 5823 5824 case OP_MARK: 5825 PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); 5826 SLJIT_ASSERT(common->mark_ptr != 0); 5827 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); 5828 allocate_stack(common, 1); 5829 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 5830 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 5831 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2)); 5832 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); 5833 OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); 5834 cc += 1 + 2 + cc[1]; 5835 break; 5836 5837 case OP_COMMIT: 5838 PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); 5839 cc += 1; 5840 break; 5841 5842 case OP_FAIL: 5843 case OP_ACCEPT: 5844 case OP_ASSERT_ACCEPT: 5845 cc = compile_fail_accept_trypath(common, cc, parent); 5846 break; 5847 5848 case OP_CLOSE: 5849 cc = compile_close_trypath(common, cc); 5850 break; 5851 5852 case OP_SKIPZERO: 5853 cc = bracketend(cc + 1); 5854 break; 5855 5856 default: 5857 SLJIT_ASSERT_STOP(); 5858 return; 5859 } 5860 if (cc == NULL) 5861 return; 5862 } 5863SLJIT_ASSERT(cc == ccend); 5864} 5865 5866#undef PUSH_BACKTRACK 5867#undef PUSH_BACKTRACK_NOVALUE 5868#undef BACKTRACK_AS 5869 5870#define COMPILE_BACKTRACKPATH(current) \ 5871 do \ 5872 { \ 5873 compile_backtrackpath(common, (current)); \ 5874 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ 5875 return; \ 5876 } \ 5877 while (0) 5878 5879#define CURRENT_AS(type) ((type *)current) 5880 5881static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) 5882{ 5883DEFINE_COMPILER; 5884pcre_uchar *cc = current->cc; 5885pcre_uchar opcode; 5886pcre_uchar type; 5887int arg1 = -1, arg2 = -1; 5888struct sljit_label *label = NULL; 5889struct sljit_jump *jump = NULL; 5890jump_list *jumplist = NULL; 5891 5892cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL); 5893 5894switch(opcode) 5895 { 5896 case OP_STAR: 5897 case OP_PLUS: 5898 case OP_UPTO: 5899 case OP_CRRANGE: 5900 if (type == OP_ANYNL || type == OP_EXTUNI) 5901 { 5902 set_jumps(current->topbacktracks, LABEL()); 5903 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5904 free_stack(common, 1); 5905 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); 5906 } 5907 else 5908 { 5909 if (opcode <= OP_PLUS || opcode == OP_UPTO) 5910 arg2 = 0; 5911 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 5912 jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1); 5913 OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1); 5914 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5915 skip_char_back(common); 5916 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5917 JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); 5918 if (opcode == OP_CRRANGE) 5919 set_jumps(current->topbacktracks, LABEL()); 5920 JUMPHERE(jump); 5921 free_stack(common, 2); 5922 if (opcode == OP_PLUS) 5923 set_jumps(current->topbacktracks, LABEL()); 5924 } 5925 break; 5926 5927 case OP_MINSTAR: 5928 case OP_MINPLUS: 5929 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5930 compile_char1_trypath(common, type, cc, &jumplist); 5931 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5932 JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); 5933 set_jumps(jumplist, LABEL()); 5934 free_stack(common, 1); 5935 if (opcode == OP_MINPLUS) 5936 set_jumps(current->topbacktracks, LABEL()); 5937 break; 5938 5939 case OP_MINUPTO: 5940 case OP_CRMINRANGE: 5941 if (opcode == OP_CRMINRANGE) 5942 { 5943 label = LABEL(); 5944 set_jumps(current->topbacktracks, label); 5945 } 5946 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5947 compile_char1_trypath(common, type, cc, &jumplist); 5948 5949 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 5950 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 5951 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 5952 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 5953 5954 if (opcode == OP_CRMINRANGE) 5955 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label); 5956 5957 if (opcode == OP_CRMINRANGE && arg1 == 0) 5958 JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); 5959 else 5960 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath); 5961 5962 set_jumps(jumplist, LABEL()); 5963 free_stack(common, 2); 5964 break; 5965 5966 case OP_QUERY: 5967 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5968 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 5969 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); 5970 jump = JUMP(SLJIT_JUMP); 5971 set_jumps(current->topbacktracks, LABEL()); 5972 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5973 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 5974 JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); 5975 JUMPHERE(jump); 5976 free_stack(common, 1); 5977 break; 5978 5979 case OP_MINQUERY: 5980 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 5981 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 5982 jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 5983 compile_char1_trypath(common, type, cc, &jumplist); 5984 JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); 5985 set_jumps(jumplist, LABEL()); 5986 JUMPHERE(jump); 5987 free_stack(common, 1); 5988 break; 5989 5990 case OP_EXACT: 5991 case OP_POSPLUS: 5992 set_jumps(current->topbacktracks, LABEL()); 5993 break; 5994 5995 case OP_POSSTAR: 5996 case OP_POSQUERY: 5997 case OP_POSUPTO: 5998 break; 5999 6000 default: 6001 SLJIT_ASSERT_STOP(); 6002 break; 6003 } 6004} 6005 6006static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) 6007{ 6008DEFINE_COMPILER; 6009pcre_uchar *cc = current->cc; 6010pcre_uchar type; 6011 6012type = cc[1 + IMM2_SIZE]; 6013if ((type & 0x1) == 0) 6014 { 6015 set_jumps(current->topbacktracks, LABEL()); 6016 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6017 free_stack(common, 1); 6018 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); 6019 return; 6020 } 6021 6022OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6023CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); 6024set_jumps(current->topbacktracks, LABEL()); 6025free_stack(common, 2); 6026} 6027 6028static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current) 6029{ 6030DEFINE_COMPILER; 6031 6032set_jumps(current->topbacktracks, LABEL()); 6033 6034if (common->has_set_som && common->mark_ptr != 0) 6035 { 6036 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6037 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 6038 free_stack(common, 2); 6039 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); 6040 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); 6041 } 6042else if (common->has_set_som || common->mark_ptr != 0) 6043 { 6044 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6045 free_stack(common, 1); 6046 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); 6047 } 6048} 6049 6050static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current) 6051{ 6052DEFINE_COMPILER; 6053pcre_uchar *cc = current->cc; 6054pcre_uchar bra = OP_BRA; 6055struct sljit_jump *brajump = NULL; 6056 6057SLJIT_ASSERT(*cc != OP_BRAMINZERO); 6058if (*cc == OP_BRAZERO) 6059 { 6060 bra = *cc; 6061 cc++; 6062 } 6063 6064if (bra == OP_BRAZERO) 6065 { 6066 SLJIT_ASSERT(current->topbacktracks == NULL); 6067 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6068 } 6069 6070if (CURRENT_AS(assert_backtrack)->framesize < 0) 6071 { 6072 set_jumps(current->topbacktracks, LABEL()); 6073 6074 if (bra == OP_BRAZERO) 6075 { 6076 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 6077 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); 6078 free_stack(common, 1); 6079 } 6080 return; 6081 } 6082 6083if (bra == OP_BRAZERO) 6084 { 6085 if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) 6086 { 6087 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 6088 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); 6089 free_stack(common, 1); 6090 return; 6091 } 6092 free_stack(common, 1); 6093 brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 6094 } 6095 6096if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) 6097 { 6098 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr); 6099 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 6100 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w)); 6101 6102 set_jumps(current->topbacktracks, LABEL()); 6103 } 6104else 6105 set_jumps(current->topbacktracks, LABEL()); 6106 6107if (bra == OP_BRAZERO) 6108 { 6109 /* We know there is enough place on the stack. */ 6110 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); 6111 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 6112 JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath); 6113 JUMPHERE(brajump); 6114 } 6115} 6116 6117static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current) 6118{ 6119DEFINE_COMPILER; 6120int opcode; 6121int offset = 0; 6122int localptr = CURRENT_AS(bracket_backtrack)->localptr; 6123int stacksize; 6124int count; 6125pcre_uchar *cc = current->cc; 6126pcre_uchar *ccbegin; 6127pcre_uchar *ccprev; 6128jump_list *jumplist = NULL; 6129jump_list *jumplistitem = NULL; 6130pcre_uchar bra = OP_BRA; 6131pcre_uchar ket; 6132assert_backtrack *assert; 6133BOOL has_alternatives; 6134struct sljit_jump *brazero = NULL; 6135struct sljit_jump *once = NULL; 6136struct sljit_jump *cond = NULL; 6137struct sljit_label *rminlabel = NULL; 6138 6139if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) 6140 { 6141 bra = *cc; 6142 cc++; 6143 } 6144 6145opcode = *cc; 6146ccbegin = cc; 6147ket = *(bracketend(ccbegin) - 1 - LINK_SIZE); 6148cc += GET(cc, 1); 6149has_alternatives = *cc == OP_ALT; 6150if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) 6151 has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; 6152if (opcode == OP_CBRA || opcode == OP_SCBRA) 6153 offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; 6154if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) 6155 opcode = OP_SCOND; 6156if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) 6157 opcode = OP_ONCE; 6158 6159if (ket == OP_KETRMAX) 6160 { 6161 if (bra == OP_BRAZERO) 6162 { 6163 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6164 free_stack(common, 1); 6165 brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0); 6166 } 6167 } 6168else if (ket == OP_KETRMIN) 6169 { 6170 if (bra != OP_BRAMINZERO) 6171 { 6172 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6173 if (opcode >= OP_SBRA || opcode == OP_ONCE) 6174 { 6175 /* Checking zero-length iteration. */ 6176 if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) 6177 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath); 6178 else 6179 { 6180 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 6181 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath); 6182 } 6183 if (opcode != OP_ONCE) 6184 free_stack(common, 1); 6185 } 6186 else 6187 JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath); 6188 } 6189 rminlabel = LABEL(); 6190 } 6191else if (bra == OP_BRAZERO) 6192 { 6193 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6194 free_stack(common, 1); 6195 brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); 6196 } 6197 6198if (SLJIT_UNLIKELY(opcode == OP_ONCE)) 6199 { 6200 if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) 6201 { 6202 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 6203 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 6204 } 6205 once = JUMP(SLJIT_JUMP); 6206 } 6207else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) 6208 { 6209 if (has_alternatives) 6210 { 6211 /* Always exactly one alternative. */ 6212 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6213 free_stack(common, 1); 6214 6215 jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list)); 6216 if (SLJIT_UNLIKELY(!jumplistitem)) 6217 return; 6218 jumplist = jumplistitem; 6219 jumplistitem->next = NULL; 6220 jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1); 6221 } 6222 } 6223else if (*cc == OP_ALT) 6224 { 6225 /* Build a jump list. Get the last successfully matched branch index. */ 6226 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6227 free_stack(common, 1); 6228 count = 1; 6229 do 6230 { 6231 /* Append as the last item. */ 6232 if (jumplist != NULL) 6233 { 6234 jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list)); 6235 jumplistitem = jumplistitem->next; 6236 } 6237 else 6238 { 6239 jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list)); 6240 jumplist = jumplistitem; 6241 } 6242 6243 if (SLJIT_UNLIKELY(!jumplistitem)) 6244 return; 6245 6246 jumplistitem->next = NULL; 6247 jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++); 6248 cc += GET(cc, 1); 6249 } 6250 while (*cc == OP_ALT); 6251 6252 cc = ccbegin + GET(ccbegin, 1); 6253 } 6254 6255COMPILE_BACKTRACKPATH(current->top); 6256if (current->topbacktracks) 6257 set_jumps(current->topbacktracks, LABEL()); 6258 6259if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) 6260 { 6261 /* Conditional block always has at most one alternative. */ 6262 if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) 6263 { 6264 SLJIT_ASSERT(has_alternatives); 6265 assert = CURRENT_AS(bracket_backtrack)->u.assert; 6266 if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) 6267 { 6268 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); 6269 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 6270 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); 6271 } 6272 cond = JUMP(SLJIT_JUMP); 6273 set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); 6274 } 6275 else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) 6276 { 6277 SLJIT_ASSERT(has_alternatives); 6278 cond = JUMP(SLJIT_JUMP); 6279 set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); 6280 } 6281 else 6282 SLJIT_ASSERT(!has_alternatives); 6283 } 6284 6285if (has_alternatives) 6286 { 6287 count = 1; 6288 do 6289 { 6290 current->top = NULL; 6291 current->topbacktracks = NULL; 6292 current->nextbacktracks = NULL; 6293 if (*cc == OP_ALT) 6294 { 6295 ccprev = cc + 1 + LINK_SIZE; 6296 cc += GET(cc, 1); 6297 if (opcode != OP_COND && opcode != OP_SCOND) 6298 { 6299 if (localptr != 0 && opcode != OP_ONCE) 6300 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 6301 else 6302 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6303 } 6304 compile_trypath(common, ccprev, cc, current); 6305 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 6306 return; 6307 } 6308 6309 /* Instructions after the current alternative is succesfully matched. */ 6310 /* There is a similar code in compile_bracket_trypath. */ 6311 if (opcode == OP_ONCE) 6312 { 6313 if (CURRENT_AS(bracket_backtrack)->u.framesize < 0) 6314 { 6315 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 6316 /* TMP2 which is set here used by OP_KETRMAX below. */ 6317 if (ket == OP_KETRMAX) 6318 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); 6319 else if (ket == OP_KETRMIN) 6320 { 6321 /* Move the STR_PTR to the localptr. */ 6322 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); 6323 } 6324 } 6325 else 6326 { 6327 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w)); 6328 if (ket == OP_KETRMAX) 6329 { 6330 /* TMP2 which is set here used by OP_KETRMAX below. */ 6331 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6332 } 6333 } 6334 } 6335 6336 stacksize = 0; 6337 if (opcode != OP_ONCE) 6338 stacksize++; 6339 if (ket != OP_KET || bra != OP_BRA) 6340 stacksize++; 6341 6342 if (stacksize > 0) { 6343 if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0) 6344 allocate_stack(common, stacksize); 6345 else 6346 { 6347 /* We know we have place at least for one item on the top of the stack. */ 6348 SLJIT_ASSERT(stacksize == 1); 6349 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); 6350 } 6351 } 6352 6353 stacksize = 0; 6354 if (ket != OP_KET || bra != OP_BRA) 6355 { 6356 if (ket != OP_KET) 6357 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 6358 else 6359 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); 6360 stacksize++; 6361 } 6362 6363 if (opcode != OP_ONCE) 6364 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++); 6365 6366 if (offset != 0) 6367 { 6368 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); 6369 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); 6370 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); 6371 } 6372 6373 JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath); 6374 6375 if (opcode != OP_ONCE) 6376 { 6377 SLJIT_ASSERT(jumplist); 6378 JUMPHERE(jumplist->jump); 6379 jumplist = jumplist->next; 6380 } 6381 6382 COMPILE_BACKTRACKPATH(current->top); 6383 if (current->topbacktracks) 6384 set_jumps(current->topbacktracks, LABEL()); 6385 SLJIT_ASSERT(!current->nextbacktracks); 6386 } 6387 while (*cc == OP_ALT); 6388 SLJIT_ASSERT(!jumplist); 6389 6390 if (cond != NULL) 6391 { 6392 SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); 6393 assert = CURRENT_AS(bracket_backtrack)->u.assert; 6394 if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) 6395 6396 { 6397 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); 6398 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 6399 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); 6400 } 6401 JUMPHERE(cond); 6402 } 6403 6404 /* Free the STR_PTR. */ 6405 if (localptr == 0) 6406 free_stack(common, 1); 6407 } 6408 6409if (offset != 0) 6410 { 6411 /* Using both tmp register is better for instruction scheduling. */ 6412 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6413 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 6414 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); 6415 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); 6416 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2)); 6417 free_stack(common, 3); 6418 } 6419else if (opcode == OP_SBRA || opcode == OP_SCOND) 6420 { 6421 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0)); 6422 free_stack(common, 1); 6423 } 6424else if (opcode == OP_ONCE) 6425 { 6426 cc = ccbegin + GET(ccbegin, 1); 6427 if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) 6428 { 6429 /* Reset head and drop saved frame. */ 6430 stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1; 6431 free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize); 6432 } 6433 else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) 6434 { 6435 /* The STR_PTR must be released. */ 6436 free_stack(common, 1); 6437 } 6438 6439 JUMPHERE(once); 6440 /* Restore previous localptr */ 6441 if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) 6442 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w)); 6443 else if (ket == OP_KETRMIN) 6444 { 6445 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 6446 /* See the comment below. */ 6447 free_stack(common, 2); 6448 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); 6449 } 6450 } 6451 6452if (ket == OP_KETRMAX) 6453 { 6454 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6455 if (bra != OP_BRAZERO) 6456 free_stack(common, 1); 6457 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath); 6458 if (bra == OP_BRAZERO) 6459 { 6460 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 6461 JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); 6462 JUMPHERE(brazero); 6463 free_stack(common, 1); 6464 } 6465 } 6466else if (ket == OP_KETRMIN) 6467 { 6468 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6469 6470 /* OP_ONCE removes everything in case of a backtrack, so we don't 6471 need to explicitly release the STR_PTR. The extra release would 6472 affect badly the free_stack(2) above. */ 6473 if (opcode != OP_ONCE) 6474 free_stack(common, 1); 6475 CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel); 6476 if (opcode == OP_ONCE) 6477 free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); 6478 else if (bra == OP_BRAMINZERO) 6479 free_stack(common, 1); 6480 } 6481else if (bra == OP_BRAZERO) 6482 { 6483 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6484 JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); 6485 JUMPHERE(brazero); 6486 } 6487} 6488 6489static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current) 6490{ 6491DEFINE_COMPILER; 6492int offset; 6493struct sljit_jump *jump; 6494 6495if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) 6496 { 6497 if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) 6498 { 6499 offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; 6500 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6501 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 6502 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); 6503 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); 6504 } 6505 set_jumps(current->topbacktracks, LABEL()); 6506 free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); 6507 return; 6508 } 6509 6510OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr); 6511add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 6512 6513if (current->topbacktracks) 6514 { 6515 jump = JUMP(SLJIT_JUMP); 6516 set_jumps(current->topbacktracks, LABEL()); 6517 /* Drop the stack frame. */ 6518 free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); 6519 JUMPHERE(jump); 6520 } 6521OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w)); 6522} 6523 6524static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current) 6525{ 6526assert_backtrack backtrack; 6527 6528current->top = NULL; 6529current->topbacktracks = NULL; 6530current->nextbacktracks = NULL; 6531if (current->cc[1] > OP_ASSERTBACK_NOT) 6532 { 6533 /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */ 6534 compile_bracket_trypath(common, current->cc, current); 6535 compile_bracket_backtrackpath(common, current->top); 6536 } 6537else 6538 { 6539 memset(&backtrack, 0, sizeof(backtrack)); 6540 backtrack.common.cc = current->cc; 6541 backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath; 6542 /* Manual call of compile_assert_trypath. */ 6543 compile_assert_trypath(common, current->cc, &backtrack, FALSE); 6544 } 6545SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); 6546} 6547 6548static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current) 6549{ 6550DEFINE_COMPILER; 6551 6552while (current) 6553 { 6554 if (current->nextbacktracks != NULL) 6555 set_jumps(current->nextbacktracks, LABEL()); 6556 switch(*current->cc) 6557 { 6558 case OP_SET_SOM: 6559 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6560 free_stack(common, 1); 6561 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0); 6562 break; 6563 6564 case OP_STAR: 6565 case OP_MINSTAR: 6566 case OP_PLUS: 6567 case OP_MINPLUS: 6568 case OP_QUERY: 6569 case OP_MINQUERY: 6570 case OP_UPTO: 6571 case OP_MINUPTO: 6572 case OP_EXACT: 6573 case OP_POSSTAR: 6574 case OP_POSPLUS: 6575 case OP_POSQUERY: 6576 case OP_POSUPTO: 6577 case OP_STARI: 6578 case OP_MINSTARI: 6579 case OP_PLUSI: 6580 case OP_MINPLUSI: 6581 case OP_QUERYI: 6582 case OP_MINQUERYI: 6583 case OP_UPTOI: 6584 case OP_MINUPTOI: 6585 case OP_EXACTI: 6586 case OP_POSSTARI: 6587 case OP_POSPLUSI: 6588 case OP_POSQUERYI: 6589 case OP_POSUPTOI: 6590 case OP_NOTSTAR: 6591 case OP_NOTMINSTAR: 6592 case OP_NOTPLUS: 6593 case OP_NOTMINPLUS: 6594 case OP_NOTQUERY: 6595 case OP_NOTMINQUERY: 6596 case OP_NOTUPTO: 6597 case OP_NOTMINUPTO: 6598 case OP_NOTEXACT: 6599 case OP_NOTPOSSTAR: 6600 case OP_NOTPOSPLUS: 6601 case OP_NOTPOSQUERY: 6602 case OP_NOTPOSUPTO: 6603 case OP_NOTSTARI: 6604 case OP_NOTMINSTARI: 6605 case OP_NOTPLUSI: 6606 case OP_NOTMINPLUSI: 6607 case OP_NOTQUERYI: 6608 case OP_NOTMINQUERYI: 6609 case OP_NOTUPTOI: 6610 case OP_NOTMINUPTOI: 6611 case OP_NOTEXACTI: 6612 case OP_NOTPOSSTARI: 6613 case OP_NOTPOSPLUSI: 6614 case OP_NOTPOSQUERYI: 6615 case OP_NOTPOSUPTOI: 6616 case OP_TYPESTAR: 6617 case OP_TYPEMINSTAR: 6618 case OP_TYPEPLUS: 6619 case OP_TYPEMINPLUS: 6620 case OP_TYPEQUERY: 6621 case OP_TYPEMINQUERY: 6622 case OP_TYPEUPTO: 6623 case OP_TYPEMINUPTO: 6624 case OP_TYPEEXACT: 6625 case OP_TYPEPOSSTAR: 6626 case OP_TYPEPOSPLUS: 6627 case OP_TYPEPOSQUERY: 6628 case OP_TYPEPOSUPTO: 6629 case OP_CLASS: 6630 case OP_NCLASS: 6631#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 6632 case OP_XCLASS: 6633#endif 6634 compile_iterator_backtrackpath(common, current); 6635 break; 6636 6637 case OP_REF: 6638 case OP_REFI: 6639 compile_ref_iterator_backtrackpath(common, current); 6640 break; 6641 6642 case OP_RECURSE: 6643 compile_recurse_backtrackpath(common, current); 6644 break; 6645 6646 case OP_ASSERT: 6647 case OP_ASSERT_NOT: 6648 case OP_ASSERTBACK: 6649 case OP_ASSERTBACK_NOT: 6650 compile_assert_backtrackpath(common, current); 6651 break; 6652 6653 case OP_ONCE: 6654 case OP_ONCE_NC: 6655 case OP_BRA: 6656 case OP_CBRA: 6657 case OP_COND: 6658 case OP_SBRA: 6659 case OP_SCBRA: 6660 case OP_SCOND: 6661 compile_bracket_backtrackpath(common, current); 6662 break; 6663 6664 case OP_BRAZERO: 6665 if (current->cc[1] > OP_ASSERTBACK_NOT) 6666 compile_bracket_backtrackpath(common, current); 6667 else 6668 compile_assert_backtrackpath(common, current); 6669 break; 6670 6671 case OP_BRAPOS: 6672 case OP_CBRAPOS: 6673 case OP_SBRAPOS: 6674 case OP_SCBRAPOS: 6675 case OP_BRAPOSZERO: 6676 compile_bracketpos_backtrackpath(common, current); 6677 break; 6678 6679 case OP_BRAMINZERO: 6680 compile_braminzero_backtrackpath(common, current); 6681 break; 6682 6683 case OP_MARK: 6684 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6685 free_stack(common, 1); 6686 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); 6687 break; 6688 6689 case OP_COMMIT: 6690 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); 6691 if (common->leavelabel == NULL) 6692 add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP)); 6693 else 6694 JUMPTO(SLJIT_JUMP, common->leavelabel); 6695 break; 6696 6697 case OP_FAIL: 6698 case OP_ACCEPT: 6699 case OP_ASSERT_ACCEPT: 6700 set_jumps(current->topbacktracks, LABEL()); 6701 break; 6702 6703 default: 6704 SLJIT_ASSERT_STOP(); 6705 break; 6706 } 6707 current = current->prev; 6708 } 6709} 6710 6711static SLJIT_INLINE void compile_recurse(compiler_common *common) 6712{ 6713DEFINE_COMPILER; 6714pcre_uchar *cc = common->start + common->currententry->start; 6715pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); 6716pcre_uchar *ccend = bracketend(cc); 6717int localsize = get_localsize(common, ccbegin, ccend); 6718int framesize = get_framesize(common, cc, TRUE); 6719int alternativesize; 6720BOOL needsframe; 6721backtrack_common altbacktrack; 6722struct sljit_label *save_leavelabel = common->leavelabel; 6723jump_list *save_leave = common->leave; 6724struct sljit_jump *jump; 6725 6726SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); 6727needsframe = framesize >= 0; 6728if (!needsframe) 6729 framesize = 0; 6730alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; 6731 6732SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0); 6733common->currententry->entry = LABEL(); 6734set_jumps(common->currententry->calls, common->currententry->entry); 6735 6736sljit_emit_fast_enter(compiler, TMP2, 0); 6737allocate_stack(common, localsize + framesize + alternativesize); 6738OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0); 6739copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); 6740OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0); 6741if (needsframe) 6742 init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE); 6743 6744if (alternativesize > 0) 6745 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 6746 6747memset(&altbacktrack, 0, sizeof(backtrack_common)); 6748common->leavelabel = NULL; 6749common->acceptlabel = NULL; 6750common->leave = NULL; 6751common->accept = NULL; 6752altbacktrack.cc = ccbegin; 6753cc += GET(cc, 1); 6754while (1) 6755 { 6756 altbacktrack.top = NULL; 6757 altbacktrack.topbacktracks = NULL; 6758 6759 if (altbacktrack.cc != ccbegin) 6760 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 6761 6762 compile_trypath(common, altbacktrack.cc, cc, &altbacktrack); 6763 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 6764 { 6765 common->leavelabel = save_leavelabel; 6766 common->leave = save_leave; 6767 return; 6768 } 6769 6770 add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); 6771 6772 compile_backtrackpath(common, altbacktrack.top); 6773 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 6774 { 6775 common->leavelabel = save_leavelabel; 6776 common->leave = save_leave; 6777 return; 6778 } 6779 set_jumps(altbacktrack.topbacktracks, LABEL()); 6780 6781 if (*cc != OP_ALT) 6782 break; 6783 6784 altbacktrack.cc = cc + 1 + LINK_SIZE; 6785 cc += GET(cc, 1); 6786 } 6787/* None of them matched. */ 6788if (common->leave != NULL) 6789 set_jumps(common->leave, LABEL()); 6790 6791OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); 6792jump = JUMP(SLJIT_JUMP); 6793 6794set_jumps(common->accept, LABEL()); 6795OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head); 6796if (needsframe) 6797 { 6798 OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); 6799 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 6800 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); 6801 } 6802OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); 6803 6804JUMPHERE(jump); 6805copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize); 6806free_stack(common, localsize + framesize + alternativesize); 6807OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); 6808OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 6809OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0); 6810sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); 6811 6812common->leavelabel = save_leavelabel; 6813common->leave = save_leave; 6814} 6815 6816#undef COMPILE_BACKTRACKPATH 6817#undef CURRENT_AS 6818 6819void 6820PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode) 6821{ 6822struct sljit_compiler *compiler; 6823backtrack_common rootbacktrack; 6824compiler_common common_data; 6825compiler_common *common = &common_data; 6826const pcre_uint8 *tables = re->tables; 6827pcre_study_data *study; 6828int localsize; 6829pcre_uchar *ccend; 6830executable_functions *functions; 6831void *executable_func; 6832sljit_uw executable_size; 6833struct sljit_label *mainloop = NULL; 6834struct sljit_label *empty_match_found; 6835struct sljit_label *empty_match_backtrack; 6836struct sljit_jump *jump; 6837struct sljit_jump *reqbyte_notfound = NULL; 6838struct sljit_jump *empty_match; 6839 6840SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0); 6841study = extra->study_data; 6842 6843if (!tables) 6844 tables = PRIV(default_tables); 6845 6846memset(&rootbacktrack, 0, sizeof(backtrack_common)); 6847memset(common, 0, sizeof(compiler_common)); 6848rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; 6849 6850common->start = rootbacktrack.cc; 6851common->fcc = tables + fcc_offset; 6852common->lcc = (sljit_w)(tables + lcc_offset); 6853common->mode = mode; 6854common->nltype = NLTYPE_FIXED; 6855switch(re->options & PCRE_NEWLINE_BITS) 6856 { 6857 case 0: 6858 /* Compile-time default */ 6859 switch (NEWLINE) 6860 { 6861 case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; 6862 case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; 6863 default: common->newline = NEWLINE; break; 6864 } 6865 break; 6866 case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; 6867 case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; 6868 case PCRE_NEWLINE_CR+ 6869 PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break; 6870 case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; 6871 case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; 6872 default: return; 6873 } 6874if ((re->options & PCRE_BSR_ANYCRLF) != 0) 6875 common->bsr_nltype = NLTYPE_ANYCRLF; 6876else if ((re->options & PCRE_BSR_UNICODE) != 0) 6877 common->bsr_nltype = NLTYPE_ANY; 6878else 6879 { 6880#ifdef BSR_ANYCRLF 6881 common->bsr_nltype = NLTYPE_ANYCRLF; 6882#else 6883 common->bsr_nltype = NLTYPE_ANY; 6884#endif 6885 } 6886common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; 6887common->ctypes = (sljit_w)(tables + ctypes_offset); 6888common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); 6889common->name_count = re->name_count; 6890common->name_entry_size = re->name_entry_size; 6891common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; 6892#ifdef SUPPORT_UTF 6893/* PCRE_UTF16 has the same value as PCRE_UTF8. */ 6894common->utf = (re->options & PCRE_UTF8) != 0; 6895#ifdef SUPPORT_UCP 6896common->use_ucp = (re->options & PCRE_UCP) != 0; 6897#endif 6898#endif /* SUPPORT_UTF */ 6899ccend = bracketend(rootbacktrack.cc); 6900 6901/* Calculate the local space size on the stack. */ 6902common->ovector_start = CALL_LIMIT + sizeof(sljit_w); 6903 6904SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); 6905localsize = get_localspace(common, rootbacktrack.cc, ccend); 6906if (localsize < 0) 6907 return; 6908 6909/* Checking flags and updating ovector_start. */ 6910if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) 6911 { 6912 common->req_char_ptr = common->ovector_start; 6913 common->ovector_start += sizeof(sljit_w); 6914 } 6915if (mode != JIT_COMPILE) 6916 { 6917 common->start_used_ptr = common->ovector_start; 6918 common->ovector_start += sizeof(sljit_w); 6919 if (mode == JIT_PARTIAL_SOFT_COMPILE) 6920 { 6921 common->hit_start = common->ovector_start; 6922 common->ovector_start += sizeof(sljit_w); 6923 } 6924 } 6925if ((re->options & PCRE_FIRSTLINE) != 0) 6926 { 6927 common->first_line_end = common->ovector_start; 6928 common->ovector_start += sizeof(sljit_w); 6929 } 6930 6931/* Aligning ovector to even number of sljit words. */ 6932if ((common->ovector_start & sizeof(sljit_w)) != 0) 6933 common->ovector_start += sizeof(sljit_w); 6934 6935SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); 6936common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); 6937localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); 6938if (localsize > SLJIT_MAX_LOCAL_SIZE) 6939 return; 6940common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); 6941if (!common->localptrs) 6942 return; 6943memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); 6944set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend); 6945 6946compiler = sljit_create_compiler(); 6947if (!compiler) 6948 { 6949 SLJIT_FREE(common->localptrs); 6950 return; 6951 } 6952common->compiler = compiler; 6953 6954/* Main pcre_jit_exec entry. */ 6955sljit_emit_enter(compiler, 1, 5, 5, localsize); 6956 6957/* Register init. */ 6958reset_ovector(common, (re->top_bracket + 1) * 2); 6959if (common->req_char_ptr != 0) 6960 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0); 6961 6962OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); 6963OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); 6964OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 6965OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); 6966OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); 6967OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit)); 6968OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); 6969OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); 6970OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); 6971 6972if (mode == JIT_PARTIAL_SOFT_COMPILE) 6973 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); 6974 6975/* Main part of the matching */ 6976if ((re->options & PCRE_ANCHORED) == 0) 6977 { 6978 mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); 6979 /* Forward search if possible. */ 6980 if ((re->options & PCRE_NO_START_OPTIMIZE) == 0) 6981 { 6982 if ((re->flags & PCRE_FIRSTSET) != 0) 6983 fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); 6984 else if ((re->flags & PCRE_STARTLINE) != 0) 6985 fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); 6986 else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) 6987 fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); 6988 } 6989 } 6990if (common->req_char_ptr != 0) 6991 reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0); 6992 6993/* Store the current STR_PTR in OVECTOR(0). */ 6994OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); 6995/* Copy the limit of allowed recursions. */ 6996OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); 6997if (common->mark_ptr != 0) 6998 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); 6999/* Copy the beginning of the string. */ 7000if (mode == JIT_PARTIAL_SOFT_COMPILE) 7001 { 7002 jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); 7003 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); 7004 JUMPHERE(jump); 7005 } 7006else if (mode == JIT_PARTIAL_HARD_COMPILE) 7007 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); 7008 7009compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack); 7010if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 7011 { 7012 sljit_free_compiler(compiler); 7013 SLJIT_FREE(common->localptrs); 7014 return; 7015 } 7016 7017empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); 7018empty_match_found = LABEL(); 7019 7020common->acceptlabel = LABEL(); 7021if (common->accept != NULL) 7022 set_jumps(common->accept, common->acceptlabel); 7023 7024/* This means we have a match. Update the ovector. */ 7025copy_ovector(common, re->top_bracket + 1); 7026common->leavelabel = LABEL(); 7027if (common->leave != NULL) 7028 set_jumps(common->leave, common->leavelabel); 7029sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); 7030 7031if (mode != JIT_COMPILE) 7032 { 7033 common->partialmatchlabel = LABEL(); 7034 set_jumps(common->partialmatch, common->partialmatchlabel); 7035 return_with_partial_match(common, common->leavelabel); 7036 } 7037 7038empty_match_backtrack = LABEL(); 7039compile_backtrackpath(common, rootbacktrack.top); 7040if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 7041 { 7042 sljit_free_compiler(compiler); 7043 SLJIT_FREE(common->localptrs); 7044 return; 7045 } 7046 7047SLJIT_ASSERT(rootbacktrack.prev == NULL); 7048 7049if (mode == JIT_PARTIAL_SOFT_COMPILE) 7050 { 7051 /* Update hit_start only in the first time. */ 7052 jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); 7053 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr); 7054 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); 7055 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0); 7056 JUMPHERE(jump); 7057 } 7058 7059/* Check we have remaining characters. */ 7060OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); 7061 7062if ((re->options & PCRE_ANCHORED) == 0) 7063 { 7064 if ((re->options & PCRE_FIRSTLINE) == 0) 7065 { 7066 if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) 7067 { 7068 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); 7069 CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); 7070 } 7071 else 7072 CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); 7073 } 7074 else 7075 { 7076 SLJIT_ASSERT(common->first_line_end != 0); 7077 if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) 7078 { 7079 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); 7080 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); 7081 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); 7082 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); 7083 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL); 7084 JUMPTO(SLJIT_C_ZERO, mainloop); 7085 } 7086 else 7087 CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop); 7088 } 7089 } 7090 7091/* No more remaining characters. */ 7092if (reqbyte_notfound != NULL) 7093 JUMPHERE(reqbyte_notfound); 7094 7095if (mode == JIT_PARTIAL_SOFT_COMPILE) 7096 CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); 7097 7098OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); 7099JUMPTO(SLJIT_JUMP, common->leavelabel); 7100 7101flush_stubs(common); 7102 7103JUMPHERE(empty_match); 7104OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 7105OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); 7106CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack); 7107OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); 7108CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found); 7109OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 7110CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found); 7111JUMPTO(SLJIT_JUMP, empty_match_backtrack); 7112 7113common->currententry = common->entries; 7114while (common->currententry != NULL) 7115 { 7116 /* Might add new entries. */ 7117 compile_recurse(common); 7118 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 7119 { 7120 sljit_free_compiler(compiler); 7121 SLJIT_FREE(common->localptrs); 7122 return; 7123 } 7124 flush_stubs(common); 7125 common->currententry = common->currententry->next; 7126 } 7127 7128/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ 7129/* This is a (really) rare case. */ 7130set_jumps(common->stackalloc, LABEL()); 7131/* RETURN_ADDR is not a saved register. */ 7132sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 7133OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); 7134OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 7135OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); 7136OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0); 7137OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); 7138 7139sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); 7140jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); 7141OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 7142OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); 7143OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); 7144OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit)); 7145OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); 7146sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); 7147 7148/* Allocation failed. */ 7149JUMPHERE(jump); 7150/* We break the return address cache here, but this is a really rare case. */ 7151OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); 7152JUMPTO(SLJIT_JUMP, common->leavelabel); 7153 7154/* Call limit reached. */ 7155set_jumps(common->calllimit, LABEL()); 7156OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); 7157JUMPTO(SLJIT_JUMP, common->leavelabel); 7158 7159if (common->revertframes != NULL) 7160 { 7161 set_jumps(common->revertframes, LABEL()); 7162 do_revertframes(common); 7163 } 7164if (common->wordboundary != NULL) 7165 { 7166 set_jumps(common->wordboundary, LABEL()); 7167 check_wordboundary(common); 7168 } 7169if (common->anynewline != NULL) 7170 { 7171 set_jumps(common->anynewline, LABEL()); 7172 check_anynewline(common); 7173 } 7174if (common->hspace != NULL) 7175 { 7176 set_jumps(common->hspace, LABEL()); 7177 check_hspace(common); 7178 } 7179if (common->vspace != NULL) 7180 { 7181 set_jumps(common->vspace, LABEL()); 7182 check_vspace(common); 7183 } 7184if (common->casefulcmp != NULL) 7185 { 7186 set_jumps(common->casefulcmp, LABEL()); 7187 do_casefulcmp(common); 7188 } 7189if (common->caselesscmp != NULL) 7190 { 7191 set_jumps(common->caselesscmp, LABEL()); 7192 do_caselesscmp(common); 7193 } 7194#ifdef SUPPORT_UTF 7195if (common->utfreadchar != NULL) 7196 { 7197 set_jumps(common->utfreadchar, LABEL()); 7198 do_utfreadchar(common); 7199 } 7200#ifdef COMPILE_PCRE8 7201if (common->utfreadtype8 != NULL) 7202 { 7203 set_jumps(common->utfreadtype8, LABEL()); 7204 do_utfreadtype8(common); 7205 } 7206#endif 7207#endif /* COMPILE_PCRE8 */ 7208#ifdef SUPPORT_UCP 7209if (common->getucd != NULL) 7210 { 7211 set_jumps(common->getucd, LABEL()); 7212 do_getucd(common); 7213 } 7214#endif 7215 7216SLJIT_FREE(common->localptrs); 7217executable_func = sljit_generate_code(compiler); 7218executable_size = sljit_get_generated_code_size(compiler); 7219sljit_free_compiler(compiler); 7220if (executable_func == NULL) 7221 return; 7222 7223/* Reuse the function descriptor if possible. */ 7224if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) 7225 functions = (executable_functions *)extra->executable_jit; 7226else 7227 { 7228 functions = SLJIT_MALLOC(sizeof(executable_functions)); 7229 if (functions == NULL) 7230 { 7231 /* This case is highly unlikely since we just recently 7232 freed a lot of memory. Although not impossible. */ 7233 sljit_free_code(executable_func); 7234 return; 7235 } 7236 memset(functions, 0, sizeof(executable_functions)); 7237 extra->executable_jit = functions; 7238 extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; 7239 } 7240 7241functions->executable_funcs[mode] = executable_func; 7242functions->executable_sizes[mode] = executable_size; 7243} 7244 7245static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func) 7246{ 7247union { 7248 void* executable_func; 7249 jit_function call_executable_func; 7250} convert_executable_func; 7251pcre_uint8 local_area[LOCAL_SPACE_SIZE]; 7252struct sljit_stack local_stack; 7253 7254local_stack.top = (sljit_w)&local_area; 7255local_stack.base = local_stack.top; 7256local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; 7257local_stack.max_limit = local_stack.limit; 7258arguments->stack = &local_stack; 7259convert_executable_func.executable_func = executable_func; 7260return convert_executable_func.call_executable_func(arguments); 7261} 7262 7263int 7264PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject, 7265 int length, int start_offset, int options, int *offsets, int offsetcount) 7266{ 7267executable_functions *functions = (executable_functions *)extra_data->executable_jit; 7268union { 7269 void* executable_func; 7270 jit_function call_executable_func; 7271} convert_executable_func; 7272jit_arguments arguments; 7273int maxoffsetcount; 7274int retval; 7275int mode = JIT_COMPILE; 7276 7277if ((options & PCRE_PARTIAL_HARD) != 0) 7278 mode = JIT_PARTIAL_HARD_COMPILE; 7279else if ((options & PCRE_PARTIAL_SOFT) != 0) 7280 mode = JIT_PARTIAL_SOFT_COMPILE; 7281 7282if (functions->executable_funcs[mode] == NULL) 7283 return PCRE_ERROR_NULL; 7284 7285/* Sanity checks should be handled by pcre_exec. */ 7286arguments.stack = NULL; 7287arguments.str = subject + start_offset; 7288arguments.begin = subject; 7289arguments.end = subject + length; 7290arguments.mark_ptr = NULL; 7291/* JIT decreases this value less frequently than the interpreter. */ 7292arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; 7293arguments.notbol = (options & PCRE_NOTBOL) != 0; 7294arguments.noteol = (options & PCRE_NOTEOL) != 0; 7295arguments.notempty = (options & PCRE_NOTEMPTY) != 0; 7296arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; 7297arguments.offsets = offsets; 7298 7299/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of 7300the output vector for storing captured strings, with the remainder used as 7301workspace. We don't need the workspace here. For compatibility, we limit the 7302number of captured strings in the same way as pcre_exec(), so that the user 7303gets the same result with and without JIT. */ 7304 7305if (offsetcount != 2) 7306 offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3; 7307maxoffsetcount = (re->top_bracket + 1) * 2; 7308if (offsetcount > maxoffsetcount) 7309 offsetcount = maxoffsetcount; 7310arguments.offsetcount = offsetcount; 7311 7312if (functions->callback) 7313 arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata); 7314else 7315 arguments.stack = (struct sljit_stack *)functions->userdata; 7316 7317if (arguments.stack == NULL) 7318 retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]); 7319else 7320 { 7321 convert_executable_func.executable_func = functions->executable_funcs[mode]; 7322 retval = convert_executable_func.call_executable_func(&arguments); 7323 } 7324 7325if (retval * 2 > offsetcount) 7326 retval = 0; 7327if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) 7328 *(extra_data->mark) = arguments.mark_ptr; 7329 7330return retval; 7331} 7332 7333void 7334PRIV(jit_free)(void *executable_funcs) 7335{ 7336int i; 7337executable_functions *functions = (executable_functions *)executable_funcs; 7338for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) 7339 { 7340 if (functions->executable_funcs[i] != NULL) 7341 sljit_free_code(functions->executable_funcs[i]); 7342 } 7343SLJIT_FREE(functions); 7344} 7345 7346int 7347PRIV(jit_get_size)(void *executable_funcs) 7348{ 7349int i; 7350sljit_uw size = 0; 7351sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes; 7352for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) 7353 size += executable_sizes[i]; 7354return (int)size; 7355} 7356 7357const char* 7358PRIV(jit_get_target)(void) 7359{ 7360return sljit_get_platform_name(); 7361} 7362 7363#ifdef COMPILE_PCRE8 7364PCRE_EXP_DECL pcre_jit_stack * 7365pcre_jit_stack_alloc(int startsize, int maxsize) 7366#else 7367PCRE_EXP_DECL pcre16_jit_stack * 7368pcre16_jit_stack_alloc(int startsize, int maxsize) 7369#endif 7370{ 7371if (startsize < 1 || maxsize < 1) 7372 return NULL; 7373if (startsize > maxsize) 7374 startsize = maxsize; 7375startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); 7376maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); 7377return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize); 7378} 7379 7380#ifdef COMPILE_PCRE8 7381PCRE_EXP_DECL void 7382pcre_jit_stack_free(pcre_jit_stack *stack) 7383#else 7384PCRE_EXP_DECL void 7385pcre16_jit_stack_free(pcre16_jit_stack *stack) 7386#endif 7387{ 7388sljit_free_stack((struct sljit_stack *)stack); 7389} 7390 7391#ifdef COMPILE_PCRE8 7392PCRE_EXP_DECL void 7393pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) 7394#else 7395PCRE_EXP_DECL void 7396pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) 7397#endif 7398{ 7399executable_functions *functions; 7400if (extra != NULL && 7401 (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && 7402 extra->executable_jit != NULL) 7403 { 7404 functions = (executable_functions *)extra->executable_jit; 7405 functions->callback = callback; 7406 functions->userdata = userdata; 7407 } 7408} 7409 7410#else /* SUPPORT_JIT */ 7411 7412/* These are dummy functions to avoid linking errors when JIT support is not 7413being compiled. */ 7414 7415#ifdef COMPILE_PCRE8 7416PCRE_EXP_DECL pcre_jit_stack * 7417pcre_jit_stack_alloc(int startsize, int maxsize) 7418#else 7419PCRE_EXP_DECL pcre16_jit_stack * 7420pcre16_jit_stack_alloc(int startsize, int maxsize) 7421#endif 7422{ 7423(void)startsize; 7424(void)maxsize; 7425return NULL; 7426} 7427 7428#ifdef COMPILE_PCRE8 7429PCRE_EXP_DECL void 7430pcre_jit_stack_free(pcre_jit_stack *stack) 7431#else 7432PCRE_EXP_DECL void 7433pcre16_jit_stack_free(pcre16_jit_stack *stack) 7434#endif 7435{ 7436(void)stack; 7437} 7438 7439#ifdef COMPILE_PCRE8 7440PCRE_EXP_DECL void 7441pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) 7442#else 7443PCRE_EXP_DECL void 7444pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) 7445#endif 7446{ 7447(void)extra; 7448(void)callback; 7449(void)userdata; 7450} 7451 7452#endif 7453 7454/* End of pcre_jit_compile.c */ 7455