165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/************************************************* 265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich* Perl-Compatible Regular Expressions * 365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*************************************************/ 465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* PCRE is a library of functions to support regular expressions whose syntax 665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichand semantics are as close as possible to those of the Perl 5 language. 765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Written by Philip Hazel 965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Copyright (c) 1997-2013 University of Cambridge 1065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich The machine code generator part (this module) was written by Zoltan Herczeg 1265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Copyright (c) 2010-2013 1365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich----------------------------------------------------------------------------- 1565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichRedistribution and use in source and binary forms, with or without 1665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmodification, are permitted provided that the following conditions are met: 1765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * Redistributions of source code must retain the above copyright notice, 1965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich this list of conditions and the following disclaimer. 2065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 2165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * Redistributions in binary form must reproduce the above copyright 2265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich notice, this list of conditions and the following disclaimer in the 2365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich documentation and/or other materials provided with the distribution. 2465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 2565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * Neither the name of the University of Cambridge nor the names of its 2665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich contributors may be used to endorse or promote products derived from 2765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich this software without specific prior written permission. 2865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 2965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 3065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 3365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPOSSIBILITY OF SUCH DAMAGE. 4065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich----------------------------------------------------------------------------- 4165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*/ 4265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 4365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_CONFIG_H 4465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "config.h" 4565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 4665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 4765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "pcre_internal.h" 4865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 4965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_JIT 5065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 5165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* All-in-one: Since we use the JIT compiler only from here, 5265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwe just include it. This way we don't need to touch the build 5365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsystem files. */ 5465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 5565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_MALLOC(size) (PUBL(malloc))(size) 5665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_FREE(ptr) (PUBL(free))(ptr) 5765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_CONFIG_AUTO 1 5865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_CONFIG_STATIC 1 5965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_VERBOSE 0 6065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SLJIT_DEBUG 0 6165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 6265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "sljit/sljitLir.c" 6365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 6465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED 6565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#error Unsupported architecture 6665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 6765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 6865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Defines for debugging purposes. */ 6965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 7065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* 1 - Use unoptimized capturing brackets. 7165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 2 - Enable capture_last_ptr (includes option 1). */ 7265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */ 7365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 7465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* 1 - Always have a control head. */ 7565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* #define DEBUG_FORCE_CONTROL_HEAD 1 */ 7665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 7765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Allocate memory for the regex stack on the real machine stack. 7865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichFast, but limited size. */ 7965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MACHINE_STACK_SIZE 32768 8065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 8165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Growth rate for stack allocated by the OS. Should be the multiply 8265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichof page size. */ 8365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define STACK_GROWTH_RATE 8192 8465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 8565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Enable to check that the allocation could destroy temporaries. */ 8665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SLJIT_DEBUG && SLJIT_DEBUG 8765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define DESTROY_REGISTERS 1 8865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 8965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 9065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* 9165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichShort summary about the backtracking mechanism empolyed by the jit code generator: 9265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 9365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichThe code generator follows the recursive nature of the PERL compatible regular 9465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichexpressions. The basic blocks of regular expressions are condition checkers 9565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhose execute different commands depending on the result of the condition check. 9665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichThe relationship between the operators can be horizontal (concatenation) and 9765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichvertical (sub-expression) (See struct backtrack_common for more details). 9865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 9965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 'ab' - 'a' and 'b' regexps are concatenated 10065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 'a+' - 'a' is the sub-expression of the '+' operator 10165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 10265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichThe condition checkers are boolean (true/false) checkers. Machine code is generated 10365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor the checker itself and for the actions depending on the result of the checker. 10465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichThe 'true' case is called as the matching path (expected path), and the other is called as 10565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichthe 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken 10665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbranches on the matching path. 10765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 10865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Greedy star operator (*) : 10965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Matching path: match happens. 11065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Backtrack path: match failed. 11165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Non-greedy star operator (*?) : 11265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Matching path: no need to perform a match. 11365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Backtrack path: match is required. 11465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 11565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichThe following example shows how the code generated for a capturing bracket 11665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwith two alternatives. Let A, B, C, D are arbirary regular expressions, and 11765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwe have the following regular expression: 11865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 11965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich A(B|C)D 12065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 12165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichThe generated code will be the following: 12265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 12365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich A matching path 12465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich '(' matching path (pushing arguments to the stack) 12565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich B matching path 12665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ')' matching path (pushing arguments to the stack) 12765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich D matching path 12865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return with successful match 12965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 13065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich D backtrack path 13165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ')' backtrack path (If we arrived from "C" jump to the backtrack of "C") 13265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich B backtrack path 13365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich C expected path 13465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump to D matching path 13565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich C backtrack path 13665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich A backtrack path 13765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 13865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Notice, that the order of backtrack code paths are the opposite of the fast 13965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich code paths. In this way the topmost value on the stack is always belong 14065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich to the current backtrack code path. The backtrack path must check 14165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich whether there is a next alternative. If so, it needs to jump back to 14265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich the matching path eventually. Otherwise it needs to clear out its own stack 14365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich frame and continue the execution on the backtrack code paths. 14465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*/ 14565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 14665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* 14765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSaved stack frames: 14865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 14965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichAtomic blocks and asserts require reloading the values of private data 15065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhen the backtrack mechanism performed. Because of OP_RECURSE, the data 15165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichare not necessarly known in compile time, thus we need a dynamic restore 15265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmechanism. 15365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 15465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichThe stack frames are stored in a chain list, and have the following format: 15565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ] 15665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 15765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichThus we can restore the private data to a particular point in the stack. 15865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*/ 15965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 16065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct jit_arguments { 16165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Pointers first. */ 16265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_stack *stack; 16365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich const pcre_uchar *str; 16465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich const pcre_uchar *begin; 16565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich const pcre_uchar *end; 16665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int *offsets; 16765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uchar *uchar_ptr; 16865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uchar *mark_ptr; 16965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich void *callout_data; 17065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Everything else after. */ 17165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint32 limit_match; 17265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int real_offset_count; 17365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int offset_count; 17465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint8 notbol; 17565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint8 noteol; 17665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint8 notempty; 17765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint8 notempty_atstart; 17865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} jit_arguments; 17965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 18065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct executable_functions { 18165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; 18265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uw *read_only_data[JIT_NUMBER_OF_COMPILE_MODES]; 18365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; 18465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PUBL(jit_callback) callback; 18565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich void *userdata; 18665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint32 top_bracket; 18765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint32 limit_match; 18865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} executable_functions; 18965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 19065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct jump_list { 19165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_jump *jump; 19265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct jump_list *next; 19365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} jump_list; 19465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 19565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct stub_list { 19665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_jump *start; 19765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *quit; 19865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct stub_list *next; 19965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} stub_list; 20065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 20165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct label_addr_list { 20265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *label; 20365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uw *update_addr; 20465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct label_addr_list *next; 20565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} label_addr_list; 20665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 20765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichenum frame_types { 20865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich no_frame = -1, 20965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich no_stack = -2 21065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}; 21165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 21265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichenum control_types { 21365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich type_mark = 0, 21465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich type_then_trap = 1 21565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}; 21665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 21765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef int (SLJIT_CALL *jit_function)(jit_arguments *args); 21865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 21965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* The following structure is the key data type for the recursive 22065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcode generator. It is allocated by compile_matchingpath, and contains 22165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichthe arguments for compile_backtrackingpath. Must be the first member 22265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichof its descendants. */ 22365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct backtrack_common { 22465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Concatenation stack. */ 22565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct backtrack_common *prev; 22665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *nextbacktracks; 22765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Internal stack (for component operators). */ 22865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct backtrack_common *top; 22965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *topbacktracks; 23065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Opcode pointer. */ 23165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uchar *cc; 23265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} backtrack_common; 23365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 23465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct assert_backtrack { 23565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack_common common; 23665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *condfailed; 23765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Less than 0 if a frame is not needed. */ 23865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int framesize; 23965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Points to our private memory word on the stack. */ 24065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int private_data_ptr; 24165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* For iterators. */ 24265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *matchingpath; 24365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} assert_backtrack; 24465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 24565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct bracket_backtrack { 24665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack_common common; 24765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Where to coninue if an alternative is successfully matched. */ 24865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *alternative_matchingpath; 24965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* For rmin and rmax iterators. */ 25065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *recursive_matchingpath; 25165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* For greedy ? operator. */ 25265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *zero_matchingpath; 25365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Contains the branches of a failed condition. */ 25465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich union { 25565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Both for OP_COND, OP_SCOND. */ 25665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *condfailed; 25765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich assert_backtrack *assert; 25865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* For OP_ONCE. Less than 0 if not needed. */ 25965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int framesize; 26065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } u; 26165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Points to our private memory word on the stack. */ 26265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int private_data_ptr; 26365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} bracket_backtrack; 26465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 26565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct bracketpos_backtrack { 26665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack_common common; 26765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Points to our private memory word on the stack. */ 26865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int private_data_ptr; 26965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Reverting stack is needed. */ 27065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int framesize; 27165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Allocated stack size. */ 27265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int stacksize; 27365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} bracketpos_backtrack; 27465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 27565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct braminzero_backtrack { 27665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack_common common; 27765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *matchingpath; 27865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} braminzero_backtrack; 27965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 28065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct iterator_backtrack { 28165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack_common common; 28265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Next iteration. */ 28365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *matchingpath; 28465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} iterator_backtrack; 28565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 28665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct recurse_entry { 28765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct recurse_entry *next; 28865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Contains the function entry. */ 28965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *entry; 29065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Collects the calls until the function is not created. */ 29165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *calls; 29265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Points to the starting opcode. */ 29365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_sw start; 29465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} recurse_entry; 29565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 29665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct recurse_backtrack { 29765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack_common common; 29865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL inlined_pattern; 29965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} recurse_backtrack; 30065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 30165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OP_THEN_TRAP OP_TABLE_LENGTH 30265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 30365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct then_trap_backtrack { 30465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack_common common; 30565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* If then_trap is not NULL, this structure contains the real 30665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich then_trap for the backtracking path. */ 30765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct then_trap_backtrack *then_trap; 30865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Points to the starting opcode. */ 30965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_sw start; 31065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Exit point for the then opcodes of this alternative. */ 31165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *quit; 31265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Frame size of the current alternative. */ 31365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int framesize; 31465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} then_trap_backtrack; 31565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 31665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MAX_RANGE_SIZE 4 31765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 31865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct compiler_common { 31965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The sljit ceneric compiler. */ 32065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_compiler *compiler; 32165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* First byte code. */ 32265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uchar *start; 32365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Maps private data offset to each opcode. */ 32465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_si *private_data_ptrs; 32565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This read-only data is available during runtime. */ 32665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uw *read_only_data; 32765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The total size of the read-only data. */ 32865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uw read_only_data_size; 32965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The next free entry of the read_only_data. */ 33065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uw *read_only_data_ptr; 33165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Tells whether the capturing bracket is optimized. */ 33265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint8 *optimized_cbracket; 33365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Tells whether the starting offset is a target of then. */ 33465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint8 *then_offsets; 33565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Current position where a THEN must jump. */ 33665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich then_trap_backtrack *then_trap; 33765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Starting offset of private data for capturing brackets. */ 33865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int cbra_ptr; 33965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Output vector starting point. Must be divisible by 2. */ 34065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int ovector_start; 34165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Last known position of the requested byte. */ 34265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int req_char_ptr; 34365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Head of the last recursion. */ 34465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int recursive_head_ptr; 34565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* First inspected character for partial matching. */ 34665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int start_used_ptr; 34765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Starting pointer for partial soft matches. */ 34865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int hit_start; 34965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* End pointer of the first line. */ 35065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int first_line_end; 35165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Points to the marked string. */ 35265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int mark_ptr; 35365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Recursive control verb management chain. */ 35465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int control_head_ptr; 35565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Points to the last matched capture block index. */ 35665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int capture_last_ptr; 35765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Points to the starting position of the current match. */ 35865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int start_ptr; 35965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 36065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Flipped and lower case tables. */ 36165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich const pcre_uint8 *fcc; 36265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_sw lcc; 36365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */ 36465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int mode; 36565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TRUE, when minlength is greater than 0. */ 36665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL might_be_empty; 36765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* \K is found in the pattern. */ 36865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL has_set_som; 36965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* (*SKIP:arg) is found in the pattern. */ 37065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL has_skip_arg; 37165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* (*THEN) is found in the pattern. */ 37265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL has_then; 37365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Needs to know the start position anytime. */ 37465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL needs_start_ptr; 37565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Currently in recurse or negative assert. */ 37665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL local_exit; 37765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Currently in a positive assert. */ 37865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL positive_assert; 37965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Newline control. */ 38065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int nltype; 38165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint32 nlmax; 38265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint32 nlmin; 38365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int newline; 38465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int bsr_nltype; 38565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint32 bsr_nlmax; 38665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uint32 bsr_nlmin; 38765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Dollar endonly. */ 38865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int endonly; 38965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Tables. */ 39065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_sw ctypes; 39165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Named capturing brackets. */ 39265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pcre_uchar *name_table; 39365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_sw name_count; 39465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_sw name_entry_size; 39565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 39665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Labels and jump lists. */ 39765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *partialmatchlabel; 39865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *quit_label; 39965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *forced_quit_label; 40065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *accept_label; 40165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_label *ff_newline_shortcut; 40265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stub_list *stubs; 40365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label_addr_list *label_addrs; 40465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich recurse_entry *entries; 40565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich recurse_entry *currententry; 40665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *partialmatch; 40765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *quit; 40865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *positive_assert_quit; 40965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *forced_quit; 41065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *accept; 41165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *calllimit; 41265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *stackalloc; 41365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *revertframes; 41465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *wordboundary; 41565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *anynewline; 41665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *hspace; 41765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *vspace; 41865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *casefulcmp; 41965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *caselesscmp; 42065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *reset_match; 42165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL jscript_compat; 42265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 42365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL utf; 42465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 42565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL use_ucp; 42665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 42765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 42865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *utfreadchar; 42965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *utfreadchar16; 43065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *utfreadtype8; 43165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 43265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 43365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 43465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump_list *getucd; 43565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 43665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} compiler_common; 43765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 43865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* For byte_sequence_compare. */ 43965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 44065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypedef struct compare_context { 44165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int length; 44265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int sourcereg; 44365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 44465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int ucharptr; 44565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich union { 44665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_si asint; 44765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uh asushort; 44865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 44965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_ub asbyte; 45065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_ub asuchars[4]; 45165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 45265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uh asuchars[2]; 45365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 45465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_ui asuchars[1]; 45565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 45665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } c; 45765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich union { 45865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_si asint; 45965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uh asushort; 46065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 46165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_ub asbyte; 46265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_ub asuchars[4]; 46365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 46465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_uh asuchars[2]; 46565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 46665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_ui asuchars[1]; 46765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 46865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } oc; 46965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 47065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} compare_context; 47165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 47265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Undefine sljit macros. */ 47365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CMP 47465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 47565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Used for accessing the elements of the stack. */ 47665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_sw)) 47765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 47865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP1 SLJIT_R0 47965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP2 SLJIT_R2 48065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define TMP3 SLJIT_R3 48165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define STR_PTR SLJIT_S0 48265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define STR_END SLJIT_S1 48365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define STACK_TOP SLJIT_R1 48465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define STACK_LIMIT SLJIT_S2 48565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define COUNT_MATCH SLJIT_S3 48665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define ARGUMENTS SLJIT_S4 48765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define RETURN_ADDR SLJIT_R4 48865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 48965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Local space layout. */ 49065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* These two locals can be used by the current opcode. */ 49165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LOCALS0 (0 * sizeof(sljit_sw)) 49265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LOCALS1 (1 * sizeof(sljit_sw)) 49365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Two local variables for possessive quantifiers (char1 cannot use them). */ 49465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define POSSESSIVE0 (2 * sizeof(sljit_sw)) 49565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define POSSESSIVE1 (3 * sizeof(sljit_sw)) 49665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Max limit of recursions. */ 49765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LIMIT_MATCH (4 * sizeof(sljit_sw)) 49865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* The output vector is stored on the stack, and contains pointers 49965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichto characters. The vector data is divided into two groups: the first 50065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichgroup contains the start / end character pointers, and the second is 50165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichthe start pointers when the end of the capturing group has not yet reached. */ 50265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OVECTOR_START (common->ovector_start) 50365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OVECTOR(i) (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw)) 50465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw)) 50565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) 50665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 50765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 50865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MOV_UCHAR SLJIT_MOV_UB 50965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MOVU_UCHAR SLJIT_MOVU_UB 51065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 51165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MOV_UCHAR SLJIT_MOV_UH 51265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MOVU_UCHAR SLJIT_MOVU_UH 51365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 51465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MOV_UCHAR SLJIT_MOV_UI 51565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MOVU_UCHAR SLJIT_MOVU_UI 51665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 51765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#error Unsupported compiling mode 51865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 51965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 52065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Shortcuts. */ 52165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define DEFINE_COMPILER \ 52265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich struct sljit_compiler *compiler = common->compiler 52365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OP1(op, dst, dstw, src, srcw) \ 52465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw)) 52565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \ 52665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w)) 52765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LABEL() \ 52865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_label(compiler) 52965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JUMP(type) \ 53065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_jump(compiler, (type)) 53165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JUMPTO(type, label) \ 53265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_set_label(sljit_emit_jump(compiler, (type)), (label)) 53365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define JUMPHERE(jump) \ 53465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_set_label((jump), sljit_emit_label(compiler)) 53565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SET_LABEL(jump, label) \ 53665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_set_label((jump), (label)) 53765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMP(type, src1, src1w, src2, src2w) \ 53865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) 53965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CMPTO(type, src1, src1w, src2, src2w, label) \ 54065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) 54165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define OP_FLAGS(op, dst, dstw, src, srcw, type) \ 54265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type)) 54365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define GET_LOCAL_BASE(dst, dstw, offset) \ 54465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_get_local_base(compiler, (dst), (dstw), (offset)) 54565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 54665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define READ_CHAR_MAX 0x7fffffff 54765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 54865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar* bracketend(pcre_uchar* cc) 54965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 55065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); 55165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichdo cc += GET(cc, 1); while (*cc == OP_ALT); 55265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); 55365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc += 1 + LINK_SIZE; 55465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc; 55565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 55665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 55765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic int no_alternatives(pcre_uchar* cc) 55865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 55965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint count = 0; 56065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); 56165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichdo 56265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 56365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 56465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count++; 56565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 56665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (*cc == OP_ALT); 56765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); 56865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn count; 56965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 57065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 57165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic int ones_in_half_byte[16] = { 57265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3, 57365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4 57465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}; 57565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 57665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Functions whose might need modification for all new supported opcodes: 57765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich next_opcode 57865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_opcode_types 57965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_private_data_ptrs 58065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich get_framesize 58165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich init_frame 58265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich get_private_data_copy_length 58365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich copy_private_data 58465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_matchingpath 58565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_backtrackingpath 58665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*/ 58765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 58865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc) 58965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 59065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_UNUSED_ARG(common); 59165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(*cc) 59265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 59365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SOD: 59465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SOM: 59565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SET_SOM: 59665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORD_BOUNDARY: 59765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORD_BOUNDARY: 59865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_DIGIT: 59965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DIGIT: 60065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WHITESPACE: 60165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WHITESPACE: 60265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORDCHAR: 60365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORDCHAR: 60465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANY: 60565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ALLANY: 60665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPROP: 60765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PROP: 60865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYNL: 60965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_HSPACE: 61065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_HSPACE: 61165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_VSPACE: 61265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_VSPACE: 61365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXTUNI: 61465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EODN: 61565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EOD: 61665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRC: 61765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRCM: 61865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLL: 61965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLLM: 62065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRSTAR: 62165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINSTAR: 62265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPLUS: 62365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINPLUS: 62465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRQUERY: 62565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINQUERY: 62665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRRANGE: 62765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINRANGE: 62865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPOSSTAR: 62965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPOSPLUS: 63065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPOSQUERY: 63165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPOSRANGE: 63265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 63365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 63465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REF: 63565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REFI: 63665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNREF: 63765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNREFI: 63865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_RECURSE: 63965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CALLOUT: 64065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ALT: 64165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_KET: 64265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_KETRMAX: 64365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_KETRMIN: 64465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_KETRPOS: 64565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REVERSE: 64665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT: 64765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_NOT: 64865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK: 64965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK_NOT: 65065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE: 65165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE_NC: 65265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRA: 65365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOS: 65465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 65565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 65665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COND: 65765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRA: 65865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRAPOS: 65965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 66065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 66165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCOND: 66265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CREF: 66365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNCREF: 66465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_RREF: 66565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNRREF: 66665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DEF: 66765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAZERO: 66865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAMINZERO: 66965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOSZERO: 67065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE: 67165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIP: 67265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN: 67365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COMMIT: 67465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_FAIL: 67565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ACCEPT: 67665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_ACCEPT: 67765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLOSE: 67865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIPZERO: 67965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + PRIV(OP_lengths)[*cc]; 68065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 68165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHAR: 68265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHARI: 68365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT: 68465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTI: 68565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STAR: 68665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTAR: 68765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUS: 68865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUS: 68965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERY: 69065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERY: 69165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTO: 69265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTO: 69365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACT: 69465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTAR: 69565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUS: 69665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERY: 69765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTO: 69865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STARI: 69965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTARI: 70065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUSI: 70165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUSI: 70265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERYI: 70365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERYI: 70465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTOI: 70565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTOI: 70665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACTI: 70765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTARI: 70865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUSI: 70965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERYI: 71065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTOI: 71165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTSTAR: 71265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINSTAR: 71365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPLUS: 71465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINPLUS: 71565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTQUERY: 71665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINQUERY: 71765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTUPTO: 71865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINUPTO: 71965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACT: 72065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSSTAR: 72165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSPLUS: 72265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSQUERY: 72365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSUPTO: 72465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTSTARI: 72565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINSTARI: 72665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPLUSI: 72765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINPLUSI: 72865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTQUERYI: 72965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINQUERYI: 73065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTUPTOI: 73165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINUPTOI: 73265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACTI: 73365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSSTARI: 73465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSPLUSI: 73565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSQUERYI: 73665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSUPTOI: 73765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += PRIV(OP_lengths)[*cc]; 73865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 73965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 74065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 74165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 74265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 74365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Special cases. */ 74465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPESTAR: 74565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINSTAR: 74665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPLUS: 74765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINPLUS: 74865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEQUERY: 74965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINQUERY: 75065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEUPTO: 75165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINUPTO: 75265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEEXACT: 75365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSSTAR: 75465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSPLUS: 75565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSQUERY: 75665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSUPTO: 75765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + PRIV(OP_lengths)[*cc] - 1; 75865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 75965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYBYTE: 76065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 76165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) return NULL; 76265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 76365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 1; 76465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 76565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 76665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 76765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + GET(cc, 1); 76865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 76965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 77065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MARK: 77165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE_ARG: 77265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIP_ARG: 77365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN_ARG: 77465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 1 + 2 + cc[1]; 77565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 77665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 77765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* All opcodes are supported now! */ 77865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 77965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 78065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 78165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 78265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 78365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) 78465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 78565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint count; 78665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *slot; 78765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 78865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ 78965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (cc < ccend) 79065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 79165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 79265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 79365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SET_SOM: 79465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->has_set_som = TRUE; 79565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->might_be_empty = TRUE; 79665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1; 79765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 79865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 79965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REF: 80065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REFI: 80165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->optimized_cbracket[GET2(cc, 1)] = 0; 80265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE; 80365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 80465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 80565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRA: 80665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 80765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRA: 80865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 80965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = no_alternatives(cc); 81065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (count > 4) 81165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->read_only_data_size += count * sizeof(sljit_uw); 81265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE + (*cc == OP_CBRA || *cc == OP_SCBRA ? IMM2_SIZE : 0); 81365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 81465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 81565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 81665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 81765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; 81865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE + IMM2_SIZE; 81965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 82065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 82165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COND: 82265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCOND: 82365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Only AUTO_CALLOUT can insert this opcode. We do 82465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich not intend to support this case. */ 82565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc[1 + LINK_SIZE] == OP_CALLOUT) 82665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 82765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 82865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 82965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 83065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CREF: 83165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->optimized_cbracket[GET2(cc, 1)] = 0; 83265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE; 83365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 83465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 83565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNREF: 83665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNREFI: 83765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNCREF: 83865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = GET2(cc, 1 + IMM2_SIZE); 83965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich slot = common->name_table + GET2(cc, 1) * common->name_entry_size; 84065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (count-- > 0) 84165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 84265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->optimized_cbracket[GET2(slot, 0)] = 0; 84365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich slot += common->name_entry_size; 84465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 84565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 2 * IMM2_SIZE; 84665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 84765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 84865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_RECURSE: 84965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Set its value only once. */ 85065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->recursive_head_ptr == 0) 85165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 85265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->recursive_head_ptr = common->ovector_start; 85365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 85465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 85565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 85665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 85765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 85865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CALLOUT: 85965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr == 0) 86065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 86165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->capture_last_ptr = common->ovector_start; 86265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 86365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 86465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2 + 2 * LINK_SIZE; 86565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 86665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 86765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN_ARG: 86865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->has_then = TRUE; 86965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->control_head_ptr = 1; 87065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Fall through. */ 87165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 87265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE_ARG: 87365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->needs_start_ptr = TRUE; 87465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Fall through. */ 87565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 87665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MARK: 87765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mark_ptr == 0) 87865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 87965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->mark_ptr = common->ovector_start; 88065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 88165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 88265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 2 + cc[1]; 88365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 88465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 88565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN: 88665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->has_then = TRUE; 88765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->control_head_ptr = 1; 88865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Fall through. */ 88965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 89065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE: 89165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIP: 89265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->needs_start_ptr = TRUE; 89365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1; 89465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 89565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 89665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIP_ARG: 89765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->control_head_ptr = 1; 89865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->has_skip_arg = TRUE; 89965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 2 + cc[1]; 90065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 90165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 90265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 90365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 90465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc == NULL) 90565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 90665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 90765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 90865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 90965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn TRUE; 91065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 91165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 91265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic int get_class_iterator_size(pcre_uchar *cc) 91365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 91465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(*cc) 91565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 91665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRSTAR: 91765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPLUS: 91865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return 2; 91965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 92065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINSTAR: 92165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINPLUS: 92265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRQUERY: 92365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINQUERY: 92465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return 1; 92565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 92665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRRANGE: 92765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINRANGE: 92865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) 92965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return 0; 93065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return 2; 93165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 93265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 93365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return 0; 93465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 93565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 93665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 93765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic BOOL detect_repeat(compiler_common *common, pcre_uchar *begin) 93865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 93965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *end = bracketend(begin); 94065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *next; 94165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *next_end; 94265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *max_end; 94365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar type; 94465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_sw length = end - begin; 94565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint min, max, i; 94665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 94765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Detect fixed iterations first. */ 94865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (end[-(1 + LINK_SIZE)] != OP_KET) 94965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 95065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 95165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Already detected repeat. */ 95265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0) 95365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 95465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 95565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichnext = end; 95665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmin = 1; 95765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (1) 95865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 95965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*next != *begin) 96065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 96165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich next_end = bracketend(next); 96265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0) 96365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 96465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich next = next_end; 96565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min++; 96665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 96765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 96865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (min == 2) 96965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 97065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 97165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmax = 0; 97265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmax_end = next; 97365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*next == OP_BRAZERO || *next == OP_BRAMINZERO) 97465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 97565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich type = *next; 97665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (1) 97765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 97865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin) 97965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 98065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich next_end = bracketend(next + 2 + LINK_SIZE); 98165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0) 98265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 98365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich next = next_end; 98465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max++; 98565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 98665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 98765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (next[0] == type && next[1] == *begin && max >= 1) 98865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 98965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich next_end = bracketend(next + 1); 99065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0) 99165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 99265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE) 99365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*next_end != OP_KET) 99465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 99565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 99665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (i == max) 99765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 99865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end; 99965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO; 100065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* +2 the original and the last. */ 100165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2; 100265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (min == 1) 100365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 100465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min--; 100565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE); 100665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 100765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 100865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 100965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 101065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 101165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (min >= 3) 101265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 101365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end; 101465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT; 101565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min; 101665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 101765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 101865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 101965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn FALSE; 102065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 102165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 102265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CASE_ITERATOR_PRIVATE_DATA_1 \ 102365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTAR: \ 102465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUS: \ 102565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERY: \ 102665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERY: \ 102765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTARI: \ 102865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUSI: \ 102965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERYI: \ 103065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERYI: \ 103165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINSTAR: \ 103265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINPLUS: \ 103365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTQUERY: \ 103465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINQUERY: \ 103565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINSTARI: \ 103665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINPLUSI: \ 103765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTQUERYI: \ 103865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINQUERYI: 103965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 104065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CASE_ITERATOR_PRIVATE_DATA_2A \ 104165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STAR: \ 104265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUS: \ 104365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STARI: \ 104465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUSI: \ 104565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTSTAR: \ 104665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPLUS: \ 104765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTSTARI: \ 104865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPLUSI: 104965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 105065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CASE_ITERATOR_PRIVATE_DATA_2B \ 105165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTO: \ 105265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTO: \ 105365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTOI: \ 105465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTOI: \ 105565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTUPTO: \ 105665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINUPTO: \ 105765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTUPTOI: \ 105865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINUPTOI: 105965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 106065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \ 106165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINSTAR: \ 106265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINPLUS: \ 106365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEQUERY: \ 106465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINQUERY: 106565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 106665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \ 106765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPESTAR: \ 106865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPLUS: 106965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 107065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \ 107165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEUPTO: \ 107265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINUPTO: 107365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 107465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend) 107565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 107665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *cc = common->start; 107765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *alternative; 107865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *end = NULL; 107965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_ptr = *private_data_start; 108065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint space, size, bracketlen; 108165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 108265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (cc < ccend) 108365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 108465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = 0; 108565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 0; 108665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bracketlen = 0; 108765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE) 108865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 108965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 109065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND) 109165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (detect_repeat(common, cc)) 109265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 109365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* These brackets are converted to repeats, so no global 109465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich based single character repeat is allowed. */ 109565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc >= end) 109665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end = bracketend(cc); 109765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 109865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 109965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 110065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 110165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_KET: 110265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->private_data_ptrs[cc + 1 - common->start] != 0) 110365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 110465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[cc - common->start] = private_data_ptr; 110565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_ptr += sizeof(sljit_sw); 110665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += common->private_data_ptrs[cc + 1 - common->start]; 110765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 110865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 110965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 111065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 111165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT: 111265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_NOT: 111365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK: 111465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK_NOT: 111565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE: 111665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE_NC: 111765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOS: 111865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRA: 111965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRAPOS: 112065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCOND: 112165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[cc - common->start] = private_data_ptr; 112265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_ptr += sizeof(sljit_sw); 112365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bracketlen = 1 + LINK_SIZE; 112465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 112565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 112665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 112765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 112865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[cc - common->start] = private_data_ptr; 112965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_ptr += sizeof(sljit_sw); 113065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bracketlen = 1 + LINK_SIZE + IMM2_SIZE; 113165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 113265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 113365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COND: 113465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Might be a hidden SCOND. */ 113565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alternative = cc + GET(cc, 1); 113665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) 113765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 113865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[cc - common->start] = private_data_ptr; 113965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_ptr += sizeof(sljit_sw); 114065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 114165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bracketlen = 1 + LINK_SIZE; 114265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 114365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 114465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRA: 114565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bracketlen = 1 + LINK_SIZE; 114665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 114765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 114865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 114965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 115065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bracketlen = 1 + LINK_SIZE + IMM2_SIZE; 115165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 115265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 115365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_1 115465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = 1; 115565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = -2; 115665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 115765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 115865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_2A 115965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = 2; 116065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = -2; 116165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 116265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 116365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_2B 116465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = 2; 116565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = -(2 + IMM2_SIZE); 116665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 116765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 116865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_1 116965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = 1; 117065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 1; 117165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 117265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 117365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_2A 117465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) 117565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = 2; 117665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 1; 117765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 117865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 117965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_2B 118065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) 118165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = 2; 118265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 1 + IMM2_SIZE; 118365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 118465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 118565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 118665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 118765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size += 1 + 32 / sizeof(pcre_uchar); 118865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = get_class_iterator_size(cc + size); 118965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 119065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 119165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 119265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 119365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = GET(cc, 1); 119465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich space = get_class_iterator_size(cc + size); 119565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 119665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 119765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 119865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 119965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 120065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(cc != NULL); 120165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 120265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 120365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 120465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Character iterators, which are not inside a repeated bracket, 120565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich gets a private slot instead of allocating it on the stack. */ 120665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (space > 0 && cc >= end) 120765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 120865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->private_data_ptrs[cc - common->start] = private_data_ptr; 120965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_ptr += sizeof(sljit_sw) * space; 121065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 121165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 121265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (size != 0) 121365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 121465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (size < 0) 121565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 121665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += -size; 121765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 121865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 121965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 122065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 122165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 122265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += size; 122365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 122465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 122565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bracketlen > 0) 122665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 122765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc >= end) 122865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 122965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end = bracketend(cc); 123065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (end[-1 - LINK_SIZE] == OP_KET) 123165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end = NULL; 123265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 123365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += bracketlen; 123465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 123565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 123665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*private_data_start = private_data_ptr; 123765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 123865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 123965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Returns with a frame_types (always < 0) if no need for frame. */ 124065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head) 124165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 124265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint length = 0; 124365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint possessive = 0; 124465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL stack_restore = FALSE; 124565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL setsom_found = recursive; 124665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL setmark_found = recursive; 124765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* The last capture is a local variable even for recursions. */ 124865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL capture_last_found = FALSE; 124965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 125065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD 125165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(common->control_head_ptr != 0); 125265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*needs_control_head = TRUE; 125365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 125465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*needs_control_head = FALSE; 125565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 125665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 125765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ccend == NULL) 125865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 125965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ccend = bracketend(cc) - (1 + LINK_SIZE); 126065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) 126165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 126265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich possessive = length = (common->capture_last_ptr != 0) ? 5 : 3; 126365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This is correct regardless of common->capture_last_ptr. */ 126465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich capture_last_found = TRUE; 126565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 126665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 126765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 126865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 126965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(cc != NULL); 127065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (cc < ccend) 127165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 127265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 127365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SET_SOM: 127465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->has_set_som); 127565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack_restore = TRUE; 127665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!setsom_found) 127765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 127865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length += 2; 127965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich setsom_found = TRUE; 128065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 128165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1; 128265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 128365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 128465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MARK: 128565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE_ARG: 128665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN_ARG: 128765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->mark_ptr != 0); 128865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack_restore = TRUE; 128965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!setmark_found) 129065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 129165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length += 2; 129265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich setmark_found = TRUE; 129365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 129465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->control_head_ptr != 0) 129565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *needs_control_head = TRUE; 129665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 2 + cc[1]; 129765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 129865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 129965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_RECURSE: 130065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack_restore = TRUE; 130165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->has_set_som && !setsom_found) 130265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 130365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length += 2; 130465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich setsom_found = TRUE; 130565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 130665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mark_ptr != 0 && !setmark_found) 130765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 130865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length += 2; 130965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich setmark_found = TRUE; 131065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 131165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0 && !capture_last_found) 131265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 131365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length += 2; 131465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich capture_last_found = TRUE; 131565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 131665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 131765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 131865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 131965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 132065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 132165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 132265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 132365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack_restore = TRUE; 132465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0 && !capture_last_found) 132565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 132665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length += 2; 132765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich capture_last_found = TRUE; 132865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 132965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length += 3; 133065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE + IMM2_SIZE; 133165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 133265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 133365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 133465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack_restore = TRUE; 133565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Fall through. */ 133665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 133765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORD_BOUNDARY: 133865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORD_BOUNDARY: 133965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_DIGIT: 134065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DIGIT: 134165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WHITESPACE: 134265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WHITESPACE: 134365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORDCHAR: 134465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORDCHAR: 134565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANY: 134665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ALLANY: 134765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYBYTE: 134865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPROP: 134965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PROP: 135065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYNL: 135165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_HSPACE: 135265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_HSPACE: 135365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_VSPACE: 135465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_VSPACE: 135565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXTUNI: 135665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EODN: 135765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EOD: 135865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRC: 135965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRCM: 136065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLL: 136165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLLM: 136265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHAR: 136365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHARI: 136465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT: 136565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTI: 136665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 136765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACT: 136865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTAR: 136965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUS: 137065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERY: 137165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTO: 137265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 137365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACTI: 137465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTARI: 137565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUSI: 137665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERYI: 137765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTOI: 137865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 137965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACT: 138065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSSTAR: 138165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSPLUS: 138265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSQUERY: 138365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSUPTO: 138465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 138565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACTI: 138665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSSTARI: 138765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSPLUSI: 138865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSQUERYI: 138965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSUPTOI: 139065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 139165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEEXACT: 139265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSSTAR: 139365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSPLUS: 139465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSQUERY: 139565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSUPTO: 139665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 139765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 139865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 139965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 140065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 140165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 140265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(cc != NULL); 140365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 140465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 140565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 140665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Possessive quantifiers can use a special case. */ 140765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(possessive == length)) 140865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return stack_restore ? no_frame : no_stack; 140965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 141065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (length > 0) 141165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return length + 1; 141265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn stack_restore ? no_frame : no_stack; 141365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 141465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 141565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive) 141665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 141765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 141865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL setsom_found = recursive; 141965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL setmark_found = recursive; 142065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* The last capture is a local variable even for recursions. */ 142165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL capture_last_found = FALSE; 142265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset; 142365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 142465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* >= 1 + shortest item size (2) */ 142565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_UNUSED_ARG(stacktop); 142665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(stackpos >= stacktop + 2); 142765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 142865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstackpos = STACK(stackpos); 142965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ccend == NULL) 143065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 143165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ccend = bracketend(cc) - (1 + LINK_SIZE); 143265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) 143365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 143465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 143565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 143665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(cc != NULL); 143765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (cc < ccend) 143865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 143965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 144065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SET_SOM: 144165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->has_set_som); 144265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!setsom_found) 144365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 144465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); 144565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0)); 144665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 144765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 144865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 144965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich setsom_found = TRUE; 145065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 145165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1; 145265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 145365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 145465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MARK: 145565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE_ARG: 145665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN_ARG: 145765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->mark_ptr != 0); 145865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!setmark_found) 145965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 146065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); 146165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr); 146265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 146365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 146465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 146565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich setmark_found = TRUE; 146665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 146765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 2 + cc[1]; 146865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 146965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 147065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_RECURSE: 147165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->has_set_som && !setsom_found) 147265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 147365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); 147465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0)); 147565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 147665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 147765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 147865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich setsom_found = TRUE; 147965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 148065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mark_ptr != 0 && !setmark_found) 148165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 148265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); 148365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr); 148465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 148565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 148665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 148765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich setmark_found = TRUE; 148865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 148965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0 && !capture_last_found) 149065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 149165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); 149265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr); 149365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 149465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 149565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 149665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich capture_last_found = TRUE; 149765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 149865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 149965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 150065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 150165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 150265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 150365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 150465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 150565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0 && !capture_last_found) 150665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 150765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); 150865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr); 150965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 151065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 151165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 151265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich capture_last_found = TRUE; 151365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 151465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset = (GET2(cc, 1 + LINK_SIZE)) << 1; 151565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); 151665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 151765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); 151865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); 151965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); 152065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 152165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); 152265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackpos += (int)sizeof(sljit_sw); 152365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 152465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE + IMM2_SIZE; 152565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 152665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 152765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 152865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 152965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(cc != NULL); 153065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 153165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 153265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 153365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0); 153465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(stackpos == STACK(stacktop)); 153565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 153665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 153765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head) 153865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 153965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_length = needs_control_head ? 3 : 2; 154065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint size; 154165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *alternative; 154265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Calculate the sum of the private machine words. */ 154365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (cc < ccend) 154465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 154565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 0; 154665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 154765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 154865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_KET: 154965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc) != 0) 155065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length++; 155165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 155265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 155365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 155465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT: 155565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_NOT: 155665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK: 155765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK_NOT: 155865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE: 155965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE_NC: 156065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOS: 156165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRA: 156265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRAPOS: 156365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCOND: 156465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length++; 156565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 156665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 156765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 156865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 156965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 157065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) 157165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length++; 157265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE + IMM2_SIZE; 157365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 157465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 157565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 157665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 157765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length += 2; 157865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE + IMM2_SIZE; 157965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 158065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 158165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COND: 158265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Might be a hidden SCOND. */ 158365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alternative = cc + GET(cc, 1); 158465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) 158565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length++; 158665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 158765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 158865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 158965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_1 159065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 159165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length++; 159265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2; 159365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 159465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 159565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 159665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 159765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 159865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_2A 159965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 160065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length += 2; 160165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2; 160265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 160365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 160465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 160565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 160665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 160765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_2B 160865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 160965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length += 2; 161065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2 + IMM2_SIZE; 161165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 161265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 161365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 161465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 161565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 161665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_1 161765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 161865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length++; 161965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1; 162065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 162165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 162265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_2A 162365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 162465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length += 2; 162565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1; 162665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 162765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 162865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_2B 162965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 163065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length += 2; 163165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE; 163265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 163365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 163465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 163565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 163665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 163765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 163865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar); 163965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 164065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 1 + 32 / (int)sizeof(pcre_uchar); 164165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 164265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 164365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_length += get_class_iterator_size(cc + size); 164465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += size; 164565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 164665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 164765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 164865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 164965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(cc != NULL); 165065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 165165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 165265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 165365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(cc == ccend); 165465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn private_data_length; 165565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 165665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 165765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, 165865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BOOL save, int stackptr, int stacktop, BOOL needs_control_head) 165965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 166065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 166165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint srcw[2]; 166265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint count, size; 166365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL tmp1next = TRUE; 166465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL tmp1empty = TRUE; 166565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL tmp2empty = TRUE; 166665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *alternative; 166765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichenum { 166865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich start, 166965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich loop, 167065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end 167165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} status; 167265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 167365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatus = save ? start : loop; 167465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstackptr = STACK(stackptr - 2); 167565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstacktop = STACK(stacktop - 1); 167665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 167765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!save) 167865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 167965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw); 168065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (stackptr < stacktop) 168165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 168265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); 168365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 168465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp1empty = FALSE; 168565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 168665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (stackptr < stacktop) 168765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 168865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); 168965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 169065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp2empty = FALSE; 169165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 169265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The tmp1next must be TRUE in either way. */ 169365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 169465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 169565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichdo 169665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 169765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 0; 169865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(status) 169965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 170065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case start: 170165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(save && common->recursive_head_ptr != 0); 170265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 1; 170365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = common->recursive_head_ptr; 170465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 170565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 170665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->control_head_ptr != 0); 170765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 2; 170865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[1] = common->control_head_ptr; 170965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 171065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich status = loop; 171165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 171265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 171365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case loop: 171465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc >= ccend) 171565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 171665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich status = end; 171765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 171865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 171965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 172065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 172165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 172265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_KET: 172365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc) != 0) 172465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 172565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 1; 172665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 172765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 172865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 172965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 173065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 173165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT: 173265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_NOT: 173365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK: 173465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK_NOT: 173565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE: 173665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE_NC: 173765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOS: 173865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRA: 173965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRAPOS: 174065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCOND: 174165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 1; 174265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 174365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(srcw[0] != 0); 174465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 174565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 174665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 174765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 174865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 174965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) 175065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 175165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 1; 175265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); 175365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 175465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE + IMM2_SIZE; 175565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 175665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 175765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 175865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 175965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 2; 176065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 176165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); 176265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0); 176365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE + IMM2_SIZE; 176465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 176565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 176665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COND: 176765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Might be a hidden SCOND. */ 176865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alternative = cc + GET(cc, 1); 176965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) 177065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 177165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 1; 177265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 177365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(srcw[0] != 0); 177465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 177565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 177665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 177765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 177865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_1 177965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 178065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 178165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 1; 178265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 178365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 178465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2; 178565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 178665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 178765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 178865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 178965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 179065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_2A 179165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 179265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 179365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 2; 179465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 179565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); 179665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 179765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2; 179865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 179965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 180065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 180165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 180265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 180365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_PRIVATE_DATA_2B 180465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 180565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 180665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 2; 180765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 180865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); 180965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 181065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2 + IMM2_SIZE; 181165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 181265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); 181365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 181465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 181565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 181665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_1 181765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 181865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 181965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 1; 182065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 182165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 182265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1; 182365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 182465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 182565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_2A 182665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 182765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 182865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 2; 182965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 183065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[1] = srcw[0] + sizeof(sljit_sw); 183165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 183265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1; 183365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 183465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 183565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CASE_ITERATOR_TYPE_PRIVATE_DATA_2B 183665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 183765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 183865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 2; 183965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 184065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[1] = srcw[0] + sizeof(sljit_sw); 184165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 184265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE; 184365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 184465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 184565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 184665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 184765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 184865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 184965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar); 185065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 185165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 1 + 32 / (int)sizeof(pcre_uchar); 185265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 185365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (PRIVATE_DATA(cc)) 185465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(get_class_iterator_size(cc + size)) 185565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 185665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 1: 185765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 1; 185865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 185965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 186065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 186165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 2: 186265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count = 2; 186365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[0] = PRIVATE_DATA(cc); 186465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich srcw[1] = srcw[0] + sizeof(sljit_sw); 186565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 186665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 186765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 186865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 186965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 187065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 187165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += size; 187265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 187365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 187465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 187565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 187665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(cc != NULL); 187765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 187865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 187965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 188065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 188165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case end: 188265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 188365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 188465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 188565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 188665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (count > 0) 188765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 188865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count--; 188965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (save) 189065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 189165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (tmp1next) 189265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 189365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!tmp1empty) 189465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 189565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); 189665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 189765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 189865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]); 189965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp1empty = FALSE; 190065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp1next = FALSE; 190165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 190265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 190365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 190465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!tmp2empty) 190565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 190665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); 190765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 190865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 190965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]); 191065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp2empty = FALSE; 191165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp1next = TRUE; 191265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 191365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 191465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 191565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 191665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (tmp1next) 191765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 191865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(!tmp1empty); 191965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP1, 0); 192065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp1empty = stackptr >= stacktop; 192165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!tmp1empty) 192265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 192365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); 192465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 192565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 192665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp1next = FALSE; 192765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 192865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 192965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 193065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(!tmp2empty); 193165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP2, 0); 193265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp2empty = stackptr >= stacktop; 193365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!tmp2empty) 193465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 193565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); 193665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 193765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 193865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp1next = TRUE; 193965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 194065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 194165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 194265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 194365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (status != end); 194465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 194565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (save) 194665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 194765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (tmp1next) 194865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 194965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!tmp1empty) 195065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 195165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); 195265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 195365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 195465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!tmp2empty) 195565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 195665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); 195765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 195865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 195965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 196065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 196165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 196265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!tmp2empty) 196365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 196465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); 196565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 196665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 196765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!tmp1empty) 196865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 196965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); 197065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stackptr += sizeof(sljit_sw); 197165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 197265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 197365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 197465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); 197565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 197665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 197765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset) 197865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 197965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *end = bracketend(cc); 198065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; 198165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 198265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Assert captures then. */ 198365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) 198465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich current_offset = NULL; 198565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Conditional block does not. */ 198665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_COND || *cc == OP_SCOND) 198765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich has_alternatives = FALSE; 198865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 198965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc = next_opcode(common, cc); 199065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (has_alternatives) 199165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich current_offset = common->then_offsets + (cc - common->start); 199265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 199365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (cc < end) 199465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 199565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) 199665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = set_then_offsets(common, cc, current_offset); 199765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 199865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 199965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_ALT && has_alternatives) 200065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start); 200165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) 200265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *current_offset = 1; 200365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = next_opcode(common, cc); 200465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 200565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 200665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 200765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn end; 200865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 200965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 201065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CASE_ITERATOR_PRIVATE_DATA_1 201165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CASE_ITERATOR_PRIVATE_DATA_2A 201265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CASE_ITERATOR_PRIVATE_DATA_2B 201365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1 201465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A 201565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B 201665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 201765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE BOOL is_powerof2(unsigned int value) 201865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 201965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn (value & (value - 1)) == 0; 202065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 202165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 202265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) 202365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 202465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (list) 202565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 202665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* sljit_set_label is clever enough to do nothing 202765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if either the jump or the label is NULL. */ 202865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_LABEL(list->jump, label); 202965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich list = list->next; 203065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 203165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 203265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 203365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump) 203465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 203565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); 203665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (list_item) 203765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 203865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich list_item->next = *list; 203965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich list_item->jump = jump; 204065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *list = list_item; 204165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 204265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 204365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 204465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void add_stub(compiler_common *common, struct sljit_jump *start) 204565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 204665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 204765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); 204865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 204965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (list_item) 205065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 205165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich list_item->start = start; 205265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich list_item->quit = LABEL(); 205365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich list_item->next = common->stubs; 205465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->stubs = list_item; 205565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 205665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 205765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 205865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void flush_stubs(compiler_common *common) 205965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 206065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 206165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstub_list* list_item = common->stubs; 206265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 206365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (list_item) 206465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 206565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(list_item->start); 206665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); 206765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, list_item->quit); 206865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich list_item = list_item->next; 206965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 207065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->stubs = NULL; 207165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 207265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 207365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void add_label_addr(compiler_common *common, sljit_uw *update_addr) 207465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 207565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 207665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel_addr_list *label_addr; 207765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 207865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list)); 207965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (label_addr == NULL) 208065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 208165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel_addr->label = LABEL(); 208265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel_addr->update_addr = update_addr; 208365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel_addr->next = common->label_addrs; 208465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->label_addrs = label_addr; 208565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 208665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 208765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void count_match(compiler_common *common) 208865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 208965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 209065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 209165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); 209265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); 209365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 209465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 209565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void allocate_stack(compiler_common *common, int size) 209665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 209765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* May destroy all locals and registers except TMP2. */ 209865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 209965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 210065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); 210165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef DESTROY_REGISTERS 210265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); 210365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP3, 0, TMP1, 0); 210465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); 210565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0); 210665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); 210765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 210865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_stub(common, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); 210965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 211065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 211165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void free_stack(compiler_common *common, int size) 211265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 211365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 211465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); 211565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 211665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 211765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void reset_ovector(compiler_common *common, int length) 211865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 211965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 212065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *loop; 212165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i; 212265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 212365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* At this point we can freely use all temporary registers. */ 212465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(length > 1); 212565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* TMP1 returns with begin - 1. */ 212665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); 212765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (length < 8) 212865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 212965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich for (i = 1; i < length; i++) 213065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0); 213165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 213265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 213365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 213465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START); 213565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1); 213665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich loop = LABEL(); 213765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0); 213865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1); 213965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, loop); 214065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 214165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 214265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 214365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void do_reset_match(compiler_common *common, int length) 214465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 214565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 214665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *loop; 214765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i; 214865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 214965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(length > 1); 215065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* OVECTOR(1) contains the "string begin - 1" constant. */ 215165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (length > 2) 215265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); 215365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (length < 8) 215465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 215565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich for (i = 2; i < length; i++) 215665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0); 215765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 215865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 215965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 216065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw)); 216165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2); 216265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich loop = LABEL(); 216365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); 216465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1); 216565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, loop); 216665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 216765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 216865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); 216965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mark_ptr != 0) 217065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0); 217165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->control_head_ptr != 0) 217265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); 217365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack)); 217465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); 217565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base)); 217665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 217765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 217865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg) 217965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 218065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (current != NULL) 218165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 218265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch (current[-2]) 218365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 218465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case type_then_trap: 218565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 218665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 218765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case type_mark: 218865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0) 218965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return current[-4]; 219065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 219165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 219265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 219365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 219465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 219565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 219665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich current = (sljit_sw*)current[-1]; 219765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 219865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn -1; 219965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 220065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 220165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) 220265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 220365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 220465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *loop; 220565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *early_quit; 220665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 220765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* At this point we can freely use all registers. */ 220865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); 220965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0); 221065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 221165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); 221265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mark_ptr != 0) 221365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); 221465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offset_count)); 221565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mark_ptr != 0) 221665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0); 221765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); 221865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin)); 221965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichGET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START); 222065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Unlikely, but possible */ 222165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichearly_quit = CMP(SLJIT_C_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0); 222265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichloop = LABEL(); 222365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0); 222465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw)); 222565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Copy the integer value to the output buffer */ 222665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 222765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT); 222865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 222965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0); 223065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); 223165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_C_NOT_ZERO, loop); 223265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(early_quit); 223365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 223465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Calculate the return value, which is the maximum ovector value. */ 223565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (topbracket > 1) 223665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 223765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw)); 223865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1); 223965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 224065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* OVECTOR(0) is never equal to SLJIT_S2. */ 224165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich loop = LABEL(); 224265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))); 224365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); 224465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop); 224565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0); 224665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 224765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 224865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); 224965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 225065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 225165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit) 225265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 225365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 225465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 225565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 225665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2); 225765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0 225865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); 225965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 226065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); 226165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); 226265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, real_offset_count)); 226365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichCMPTO(SLJIT_C_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 2, quit); 226465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 226565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Store match begin and end. */ 226665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin)); 226765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, offsets)); 226865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 226965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 3); 227065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_S0, 0); 227165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 227265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT); 227365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 227465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), 2 * sizeof(int), SLJIT_R2, 0); 227565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 227665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 227765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); 227865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, SLJIT_S1, 0, STR_END, 0, SLJIT_S0, 0); 227965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 228065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT); 228165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 228265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), sizeof(int), SLJIT_S1, 0); 228365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 228465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0); 228565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 228665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT); 228765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 228865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R2, 0); 228965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 229065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, quit); 229165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 229265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 229365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void check_start_used_ptr(compiler_common *common) 229465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 229565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* May destroy TMP1. */ 229665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 229765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 229865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 229965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mode == JIT_PARTIAL_SOFT_COMPILE) 230065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 230165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The value of -1 must be kept for start_used_ptr! */ 230265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1); 230365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting 230465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ 230565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); 230665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); 230765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 230865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 230965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (common->mode == JIT_PARTIAL_HARD_COMPILE) 231065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 231165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); 231265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); 231365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 231465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 231565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 231665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 231765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc) 231865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 231965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Detects if the character has an othercase. */ 232065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunsigned int c; 232165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 232265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 232365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 232465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 232565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHAR(c, cc); 232665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c > 127) 232765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 232865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 232965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return c != UCD_OTHERCASE(c); 233065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 233165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 233265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 233365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 233465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 233565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return common->fcc[c] != c; 233665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 233765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 233865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 233965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 234065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich c = *cc; 234165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn MAX_255(c) ? common->fcc[c] != c : FALSE; 234265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 234365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 234465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c) 234565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 234665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Returns with the othercase. */ 234765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 234865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf && c > 127) 234965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 235065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 235165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return UCD_OTHERCASE(c); 235265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 235365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return c; 235465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 235565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 235665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 235765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn TABLE_GET(c, common->fcc, c); 235865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 235965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 236065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc) 236165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 236265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Detects if the character and its othercase has only 1 bit difference. */ 236365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunsigned int c, oc, bit; 236465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 236565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint n; 236665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 236765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 236865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 236965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 237065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 237165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHAR(c, cc); 237265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c <= 127) 237365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = common->fcc[c]; 237465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 237565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 237665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 237765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = UCD_OTHERCASE(c); 237865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 237965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = c; 238065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 238165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 238265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 238365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 238465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 238565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich c = *cc; 238665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = TABLE_GET(c, common->fcc, c); 238765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 238865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 238965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichc = *cc; 239065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichoc = TABLE_GET(c, common->fcc, c); 239165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 239265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 239365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(c != oc); 239465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 239565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbit = c ^ oc; 239665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Optimized for English alphabet. */ 239765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (c <= 127 && bit == 0x20) 239865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return (0 << 8) | 0x20; 239965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 240065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Since c != oc, they must have at least 1 bit difference. */ 240165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!is_powerof2(bit)) 240265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return 0; 240365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 240465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 240565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 240665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 240765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf && c > 127) 240865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 240965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich n = GET_EXTRALEN(*cc); 241065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while ((bit & 0x3f) == 0) 241165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 241265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich n--; 241365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit >>= 6; 241465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 241565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return (n << 8) | bit; 241665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 241765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 241865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn (0 << 8) | bit; 241965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 242065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 242165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 242265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 242365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf && c > 65535) 242465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 242565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bit >= (1 << 10)) 242665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit >>= 10; 242765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 242865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8)); 242965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 243065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 243165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); 243265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 243365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE[8|16|32] */ 243465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 243565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 243665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void check_partial(compiler_common *common, BOOL force) 243765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 243865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Checks whether a partial matching is occurred. Does not modify registers. */ 243965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 244065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump = NULL; 244165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 244265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(!force || common->mode != JIT_COMPILE); 244365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 244465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mode == JIT_COMPILE) 244565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 244665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 244765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!force) 244865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); 244965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (common->mode == JIT_PARTIAL_SOFT_COMPILE) 245065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); 245165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 245265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mode == JIT_PARTIAL_SOFT_COMPILE) 245365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); 245465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 245565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 245665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->partialmatchlabel != NULL) 245765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, common->partialmatchlabel); 245865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 245965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); 246065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 246165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 246265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (jump != NULL) 246365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 246465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 246565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 246665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void check_str_end(compiler_common *common, jump_list **end_reached) 246765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 246865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Does not affect registers. Usually used in a tight spot. */ 246965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 247065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 247165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 247265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mode == JIT_COMPILE) 247365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 247465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); 247565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 247665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 247765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 247865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); 247965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mode == JIT_PARTIAL_SOFT_COMPILE) 248065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 248165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); 248265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); 248365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, end_reached, JUMP(SLJIT_JUMP)); 248465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 248565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 248665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 248765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); 248865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->partialmatchlabel != NULL) 248965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, common->partialmatchlabel); 249065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 249165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); 249265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 249365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 249465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 249565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 249665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void detect_partial_match(compiler_common *common, jump_list **backtracks) 249765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 249865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 249965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 250065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 250165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mode == JIT_COMPILE) 250265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 250365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); 250465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 250565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 250665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 250765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Partial matching mode. */ 250865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); 250965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); 251065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mode == JIT_PARTIAL_SOFT_COMPILE) 251165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 251265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); 251365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 251465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 251565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 251665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 251765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->partialmatchlabel != NULL) 251865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, common->partialmatchlabel); 251965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 252065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); 252165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 252265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 252365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 252465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 252565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void peek_char(compiler_common *common, pcre_uint32 max) 252665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 252765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Reads the character into TMP1, keeps STR_PTR. 252865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDoes not check STR_END. TMP2 Destroyed. */ 252965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 253065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 253165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 253265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 253365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 253465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_UNUSED_ARG(max); 253565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 253665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 253765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 253865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 253965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 254065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max < 128) return; 254165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 254265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 254365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 254465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); 254565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 254665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 254765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 254865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ 254965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 255065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE16 255165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 255265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 255365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max < 0xd800) return; 255465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 255565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); 255665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); 255765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 contains the high surrogate. */ 255865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 255965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); 256065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); 256165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); 256265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 256365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 256465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 256565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 256665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 256765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 256865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 256965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 257065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic BOOL is_char7_bitset(const pcre_uint8 *bitset, BOOL nclass) 257165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 257265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Tells whether the character codes below 128 are enough 257365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichto determine a match. */ 257465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst pcre_uint8 value = nclass ? 0xff : 0; 257565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst pcre_uint8* end = bitset + 32; 257665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 257765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbitset += 16; 257865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichdo 257965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 258065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*bitset++ != value) 258165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 258265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 258365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (bitset < end); 258465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn TRUE; 258565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 258665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 258765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void read_char7_type(compiler_common *common, BOOL full_read) 258865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 258965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Reads the precise character type of a character into TMP1, if the character 259065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichis less than 128. Otherwise it returns with zero. Does not check STR_END. The 259165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfull_read argument tells whether characters above max are accepted or not. */ 259265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 259365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 259465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 259565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(common->utf); 259665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 259765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); 259865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 259965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 260065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 260165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 260265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (full_read) 260365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 260465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); 260565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); 260665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 260765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 260865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 260965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 261065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 261165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && COMPILE_PCRE8 */ 261265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 261365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr) 261465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 261565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Reads the precise value of a character into TMP1, if the character is 261665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbetween min and max (c >= min && c <= max). Otherwise it returns with a value 261765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichoutside the range. Does not check STR_END. */ 261865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 261965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 262065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 262165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 262265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 262365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump2; 262465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 262565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 262665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_UNUSED_ARG(update_str_ptr); 262765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_UNUSED_ARG(min); 262865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_UNUSED_ARG(max); 262965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(min <= max); 263065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 263165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 263265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 263365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 263465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 263565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 263665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 263765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max < 128 && !update_str_ptr) return; 263865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 263965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 264065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (min >= 0x10000) 264165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 264265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); 264365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (update_str_ptr) 264465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); 264565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 264665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x7); 264765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); 264865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 264965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 265065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 265165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 265265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 265365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 265465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); 265565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!update_str_ptr) 265665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); 265765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 265865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 265965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 266065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump2); 266165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (update_str_ptr) 266265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); 266365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 266465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (min >= 0x800 && max <= 0xffff) 266565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 266665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0); 266765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (update_str_ptr) 266865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); 266965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 267065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xf); 267165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); 267265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 267365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 267465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 267565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!update_str_ptr) 267665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 267765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 267865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 267965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 268065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump2); 268165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (update_str_ptr) 268265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); 268365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 268465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (max >= 0x800) 268565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); 268665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (max < 128) 268765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 268865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); 268965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 269065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 269165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 269265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 269365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 269465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!update_str_ptr) 269565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 269665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 269765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); 269865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 269965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 270065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 270165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 270265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (update_str_ptr) 270365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); 270465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 270565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 270665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 270765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 270865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 270965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE16 271065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 271165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 271265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max >= 0x10000) 271365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 271465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); 271565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); 271665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 contains the high surrogate. */ 271765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 271865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); 271965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); 272065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 272165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); 272265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 272365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 272465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 272565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 272665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 272765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max < 0xd800 && !update_str_ptr) return; 272865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 272965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Skip low surrogate if necessary. */ 273065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); 273165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); 273265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (update_str_ptr) 273365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 273465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max >= 0xd800) 273565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000); 273665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 273765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 273865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 273965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 274065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 274165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void read_char(compiler_common *common) 274265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 274365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichread_char_range(common, 0, READ_CHAR_MAX, TRUE); 274465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 274565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 274665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void read_char8_type(compiler_common *common, BOOL update_str_ptr) 274765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 274865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ 274965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 275065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 275165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 275265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 275365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 275465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump2; 275565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 275665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 275765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_UNUSED_ARG(update_str_ptr); 275865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 275965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); 276065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 276165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 276265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 276365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 276465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 276565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This can be an extra read in some situations, but hopefully 276665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich it is needed in most cases. */ 276765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 276865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); 276965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!update_str_ptr) 277065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 277165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 277265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 277365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 277465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); 277565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 277665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); 277765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); 277865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); 277965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 278065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump2); 278165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 278265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 278365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); 278465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 278565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 278665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 278765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && COMPILE_PCRE8 */ 278865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 278965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if !defined COMPILE_PCRE8 279065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* The ctypes array contains only 256 values. */ 279165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); 279265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); 279365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 279465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 279565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if !defined COMPILE_PCRE8 279665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 279765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 279865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 279965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE16 280065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf && update_str_ptr) 280165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 280265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Skip low surrogate if necessary. */ 280365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); 280465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); 280565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 280665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 280765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 280865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && COMPILE_PCRE16 */ 280965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 281065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 281165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void skip_char_back(compiler_common *common) 281265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 281365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */ 281465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 281565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 281665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 281765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *label; 281865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 281965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 282065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 282165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 282265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); 282365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 282465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); 282565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); 282665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 282765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 282865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 282965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 283065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 283165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); 283265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 283365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Skip low surrogate if necessary. */ 283465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 283565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); 283665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 283765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 283865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 283965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 284065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 284165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE[8|16] */ 284265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ 284365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 284465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 284565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 284665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch) 284765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 284865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ 284965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 285065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 285165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 285265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (nltype == NLTYPE_ANY) 285365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 285465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); 285565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 285665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 285765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (nltype == NLTYPE_ANYCRLF) 285865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 285965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (jumpifmatch) 286065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 286165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR)); 286265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); 286365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 286465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 286565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 286665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); 286765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); 286865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 286965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 287065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 287165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 287265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 287365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); 287465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); 287565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 287665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 287765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 287865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 287965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 288065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 288165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void do_utfreadchar(compiler_common *common) 288265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 288365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Fast decoding a UTF-8 character. TMP1 contains the first byte 288465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichof the character (>= 0xc0). Return char value in TMP1, length in TMP2. */ 288565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 288665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 288765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 288865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 288965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 289065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 289165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 289265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 289365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 289465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 289565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Searching for the first zero. */ 289665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); 289765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = JUMP(SLJIT_C_NOT_ZERO); 289865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Two byte sequence. */ 289965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 290065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); 290165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 290265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 290365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 290465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 290565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); 290665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 290765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 290865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 290965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 291065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000); 291165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = JUMP(SLJIT_C_NOT_ZERO); 291265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Three byte sequence. */ 291365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 291465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); 291565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 291665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 291765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Four byte sequence. */ 291865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 291965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); 292065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); 292165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 292265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); 292365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 292465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 292565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4)); 292665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 292765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 292865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 292965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void do_utfreadchar16(compiler_common *common) 293065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 293165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Fast decoding a UTF-8 character. TMP1 contains the first byte 293265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichof the character (>= 0xc0). Return value in TMP1. */ 293365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 293465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 293565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 293665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 293765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 293865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 293965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 294065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 294165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 294265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 294365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Searching for the first zero. */ 294465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); 294565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = JUMP(SLJIT_C_NOT_ZERO); 294665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Two byte sequence. */ 294765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 294865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 294965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 295065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 295165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400); 295265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_NOT_ZERO); 295365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* This code runs only in 8 bit mode. No need to shift the value. */ 295465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 295565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 295665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); 295765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); 295865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); 295965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); 296065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Three byte sequence. */ 296165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 296265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 296365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 296465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 296565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void do_utfreadtype8(compiler_common *common) 296665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 296765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Fast decoding a UTF-8 character type. TMP2 contains the first byte 296865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichof the character (>= 0xc0). Return value in TMP1. */ 296965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 297065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 297165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *compare; 297265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 297365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 297465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 297565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); 297665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = JUMP(SLJIT_C_NOT_ZERO); 297765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Two byte sequence. */ 297865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 297965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 298065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); 298165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* The upper 5 bits are known at this point. */ 298265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x3); 298365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); 298465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 298565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); 298665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); 298765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 298865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 298965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(compare); 299065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); 299165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 299265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 299365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* We only have types for characters less than 256. */ 299465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 299565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); 299665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); 299765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 299865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 299965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 300065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 300165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE8 */ 300265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 300365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 300465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 300565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 300665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 300765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* UCD_BLOCK_SIZE must be 128 (see the assert below). */ 300865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define UCD_BLOCK_MASK 127 300965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define UCD_BLOCK_SHIFT 7 301065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 301165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void do_getucd(compiler_common *common) 301265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 301365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Search the UCD record for the character comes in TMP1. 301465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichReturns chartype in TMP1 and UCD offset in TMP2. */ 301565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 301665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 301765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); 301865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 301965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 302065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); 302165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); 302265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); 302365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); 302465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); 302565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); 302665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); 302765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); 302865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); 302965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 303065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 303165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 303265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 303365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline) 303465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 303565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 303665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *mainloop; 303765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *newlinelabel = NULL; 303865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *start; 303965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *end = NULL; 304065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *nl = NULL; 304165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 304265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *singlechar; 304365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 304465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *newline = NULL; 304565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL newlinecheck = FALSE; 304665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL readuchar = FALSE; 304765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 304865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY || 304965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) 305065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich newlinecheck = TRUE; 305165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 305265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 305365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 305465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Search for the end of the first line. */ 305565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->first_line_end != 0); 305665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); 305765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 305865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->nltype == NLTYPE_FIXED && common->newline > 255) 305965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 306065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mainloop = LABEL(); 306165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 306265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 306365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); 306465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 306565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); 306665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); 306765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(end); 306865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 306965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 307065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 307165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 307265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 307365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mainloop = LABEL(); 307465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Continual stores does not cause data dependency. */ 307565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0); 307665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, common->nlmin, common->nlmax, TRUE); 307765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_newlinechar(common, common->nltype, &newline, TRUE); 307865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); 307965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(end); 308065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0); 308165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(newline, LABEL()); 308265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 308365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 308465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); 308565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 308665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 308765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstart = JUMP(SLJIT_JUMP); 308865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 308965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (newlinecheck) 309065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 309165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich newlinelabel = LABEL(); 309265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 309365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 309465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 309565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); 309665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 309765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 309865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); 309965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 310065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 310165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich nl = JUMP(SLJIT_JUMP); 310265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 310365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 310465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmainloop = LABEL(); 310565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 310665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Increasing the STR_PTR here requires one less jump in the most common case. */ 310765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 310865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) readuchar = TRUE; 310965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 311065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (newlinecheck) readuchar = TRUE; 311165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 311265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (readuchar) 311365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 311465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 311565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (newlinecheck) 311665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); 311765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 311865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 311965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 312065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 312165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 312265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 312365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 312465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); 312565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 312665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(singlechar); 312765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 312865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 312965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 313065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 313165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); 313265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 313365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); 313465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 313565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 313665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 313765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(singlechar); 313865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 313965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE[8|16] */ 314065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ 314165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(start); 314265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 314365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (newlinecheck) 314465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 314565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(end); 314665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(nl); 314765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 314865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 314965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn mainloop; 315065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 315165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 315265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MAX_N_CHARS 16 315365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define MAX_N_BYTES 8 315465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 315565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void add_prefix_byte(pcre_uint8 byte, pcre_uint8 *bytes) 315665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 315765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint8 len = bytes[0]; 315865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i; 315965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 316065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (len == 255) 316165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 316265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 316365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (len == 0) 316465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 316565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bytes[0] = 1; 316665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bytes[1] = byte; 316765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 316865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 316965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 317065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = len; i > 0; i--) 317165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bytes[i] == byte) 317265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 317365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 317465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (len >= MAX_N_BYTES - 1) 317565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 317665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bytes[0] = 255; 317765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 317865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 317965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 318065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlen++; 318165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbytes[len] = byte; 318265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbytes[0] = len; 318365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 318465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 318565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars) 318665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 318765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Recursive function, which scans prefix literals. */ 318865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL last, any, caseless; 318965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint len, repeat, len_save, consumed = 0; 319065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint32 chr, mask; 319165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *alternative, *cc_save, *oc; 319265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 319365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar othercase[8]; 319465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined SUPPORT_UTF && defined COMPILE_PCRE16 319565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar othercase[2]; 319665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 319765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar othercase[1]; 319865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 319965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 320065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichrepeat = 1; 320165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (TRUE) 320265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 320365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich last = TRUE; 320465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = FALSE; 320565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich caseless = FALSE; 320665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch (*cc) 320765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 320865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHARI: 320965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich caseless = TRUE; 321065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHAR: 321165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich last = FALSE; 321265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 321365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 321465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 321565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SOD: 321665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SOM: 321765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SET_SOM: 321865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORD_BOUNDARY: 321965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORD_BOUNDARY: 322065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EODN: 322165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EOD: 322265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRC: 322365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRCM: 322465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLL: 322565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLLM: 322665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Zero width assertions. */ 322765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 322865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 322965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 323065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT: 323165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_NOT: 323265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK: 323365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK_NOT: 323465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = bracketend(cc); 323565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 323665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 323765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUSI: 323865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUSI: 323965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUSI: 324065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich caseless = TRUE; 324165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUS: 324265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUS: 324365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUS: 324465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 324565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 324665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 324765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACTI: 324865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich caseless = TRUE; 324965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACT: 325065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat = GET2(cc, 1); 325165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich last = FALSE; 325265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE; 325365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 325465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 325565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERYI: 325665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERYI: 325765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERYI: 325865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich caseless = TRUE; 325965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERY: 326065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERY: 326165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERY: 326265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich len = 1; 326365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 326465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 326565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); 326665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 326765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars); 326865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max_chars == 0) 326965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 327065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich last = FALSE; 327165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 327265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 327365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_KET: 327465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 327565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 327665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 327765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ALT: 327865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 327965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 328065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 328165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE: 328265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE_NC: 328365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRA: 328465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOS: 328565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 328665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 328765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alternative = cc + GET(cc, 1); 328865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (*alternative == OP_ALT) 328965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 329065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars); 329165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max_chars == 0) 329265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 329365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alternative += GET(alternative, 1); 329465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 329565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 329665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_CBRA || *cc == OP_CBRAPOS) 329765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += IMM2_SIZE; 329865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + LINK_SIZE; 329965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 330065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 330165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 330265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 330365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && !is_char7_bitset((const pcre_uint8 *)(cc + 1), FALSE)) return consumed; 330465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 330565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 330665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 32 / sizeof(pcre_uchar); 330765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 330865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 330965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 331065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 331165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) return consumed; 331265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 331365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 331465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 32 / sizeof(pcre_uchar); 331565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 331665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 331765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 331865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 331965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 332065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) return consumed; 332165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 332265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 332365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 332465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 332565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 332665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 332765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DIGIT: 332865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 332965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_digit, FALSE)) 333065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 333165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 333265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 333365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 333465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 333565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 333665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WHITESPACE: 333765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 333865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_space, FALSE)) 333965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 334065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 334165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 334265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 334365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 334465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 334565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORDCHAR: 334665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 334765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_word, FALSE)) 334865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 334965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 335065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 335165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 335265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 335365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 335465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT: 335565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTI: 335665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 335765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Fall through. */ 335865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_DIGIT: 335965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WHITESPACE: 336065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORDCHAR: 336165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANY: 336265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ALLANY: 336365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 336465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) return consumed; 336565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 336665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 336765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 336865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 336965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 337065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 337165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPROP: 337265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PROP: 337365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 337465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) return consumed; 337565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 337665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 337765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 2; 337865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 337965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 338065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 338165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEEXACT: 338265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat = GET2(cc, 1); 338365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE; 338465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 338565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 338665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACT: 338765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACTI: 338865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 338965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) return consumed; 339065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 339165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich any = TRUE; 339265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat = GET2(cc, 1); 339365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE + 1; 339465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 339565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 339665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 339765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 339865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 339965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 340065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (any) 340165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 340265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 340365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask = 0xff; 340465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 340565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask = 0xffff; 340665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 340765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask = 0xffffffff; 340865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 340965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 341065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 341165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 341265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do 341365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 341465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[0] = mask; 341565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[1] = mask; 341665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bytes[0] = 255; 341765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 341865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich consumed++; 341965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (--max_chars == 0) 342065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 342165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars += 2; 342265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bytes += MAX_N_BYTES; 342365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 342465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (--repeat > 0); 342565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 342665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat = 1; 342765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 342865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 342965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 343065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich len = 1; 343165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 343265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); 343365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 343465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 343565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (caseless && char_has_othercase(common, cc)) 343665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 343765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 343865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 343965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 344065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHAR(chr, cc); 344165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len) 344265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 344365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 344465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 344565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 344665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 344765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chr = *cc; 344865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich othercase[0] = TABLE_GET(chr, common->fcc, chr); 344965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 345065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 345165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 345265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich caseless = FALSE; 345365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 345465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich len_save = len; 345565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc_save = cc; 345665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (TRUE) 345765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 345865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = othercase; 345965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do 346065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 346165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chr = *cc; 346265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE32 346365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(chr == NOTACHAR)) 346465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 346565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 346665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_prefix_byte((pcre_uint8)chr, bytes); 346765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 346865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask = 0; 346965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (caseless) 347065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 347165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_prefix_byte((pcre_uint8)*oc, bytes); 347265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask = *cc ^ *oc; 347365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chr |= mask; 347465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 347565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 347665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE32 347765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (chars[0] == NOTACHAR && chars[1] == 0) 347865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 347965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (chars[0] == NOTACHAR) 348065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 348165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 348265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[0] = chr; 348365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[1] = mask; 348465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 348565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 348665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 348765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask |= chars[0] ^ chr; 348865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chr |= mask; 348965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[0] = chr; 349065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[1] |= mask; 349165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 349265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 349365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich len--; 349465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich consumed++; 349565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (--max_chars == 0) 349665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 349765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars += 2; 349865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bytes += MAX_N_BYTES; 349965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 350065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc++; 350165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 350265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (len > 0); 350365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 350465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (--repeat == 0) 350565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 350665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 350765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich len = len_save; 350865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = cc_save; 350965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 351065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 351165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat = 1; 351265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (last) 351365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return consumed; 351465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 351565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 351665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 351765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline) 351865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 351965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 352065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *start; 352165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *quit; 352265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint32 chars[MAX_N_CHARS * 2]; 352365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint8 bytes[MAX_N_CHARS * MAX_N_BYTES]; 352465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint8 ones[MAX_N_CHARS]; 352565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offsets[3]; 352665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint32 mask; 352765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint8 *byte_set, *byte_set_end; 352865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i, max, from; 352965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint range_right = -1, range_len = 3 - 1; 353065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_ub *update_table = NULL; 353165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL in_range; 353265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 353365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* This is even TRUE, if both are NULL. */ 353465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(common->read_only_data_ptr == common->read_only_data); 353565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 353665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = 0; i < MAX_N_CHARS; i++) 353765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 353865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[i << 1] = NOTACHAR; 353965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[(i << 1) + 1] = 0; 354065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bytes[i * MAX_N_BYTES] = 0; 354165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 354265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 354365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmax = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS); 354465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 354565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (max <= 1) 354665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 354765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 354865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = 0; i < max; i++) 354965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 355065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask = chars[(i << 1) + 1]; 355165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ones[i] = ones_in_half_byte[mask & 0xf]; 355265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask >>= 4; 355365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (mask != 0) 355465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 355565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ones[i] += ones_in_half_byte[mask & 0xf]; 355665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mask >>= 4; 355765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 355865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 355965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 356065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichin_range = FALSE; 356165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfrom = 0; /* Prevent compiler "uninitialized" warning */ 356265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = 0; i <= max; i++) 356365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 356465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (in_range && (i - from) > range_len && (bytes[(i - 1) * MAX_N_BYTES] <= 4)) 356565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 356665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich range_len = i - from; 356765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich range_right = i - 1; 356865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 356965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 357065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (i < max && bytes[i * MAX_N_BYTES] < 255) 357165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 357265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!in_range) 357365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 357465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich in_range = TRUE; 357565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich from = i; 357665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 357765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 357865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (in_range) 357965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich in_range = FALSE; 358065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 358165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 358265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (range_right >= 0) 358365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 358465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Since no data is consumed (see the assert in the beginning 358565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich of this function), this space can be reallocated. */ 358665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data) 358765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->read_only_data); 358865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 358965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->read_only_data_size += 256; 359065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size); 359165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data == NULL) 359265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 359365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 359465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich update_table = (sljit_ub *)common->read_only_data; 359565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->read_only_data_ptr = (sljit_uw *)(update_table + 256); 359665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich memset(update_table, IN_UCHARS(range_len), 256); 359765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 359865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich for (i = 0; i < range_len; i++) 359965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 360065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich byte_set = bytes + ((range_right - i) * MAX_N_BYTES); 360165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(byte_set[0] > 0 && byte_set[0] < 255); 360265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich byte_set_end = byte_set + byte_set[0]; 360365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich byte_set++; 360465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (byte_set <= byte_set_end) 360565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 360665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (update_table[*byte_set] > IN_UCHARS(i)) 360765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich update_table[*byte_set] = IN_UCHARS(i); 360865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich byte_set++; 360965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 361065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 361165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 361265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 361365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichoffsets[0] = -1; 361465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Scan forward. */ 361565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = 0; i < max; i++) 361665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ones[i] <= 2) { 361765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offsets[0] = i; 361865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 361965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 362065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 362165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offsets[0] < 0 && range_right < 0) 362265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 362365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 362465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offsets[0] >= 0) 362565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 362665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Scan backward. */ 362765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offsets[1] = -1; 362865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich for (i = max - 1; i > offsets[0]; i--) 362965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ones[i] <= 2 && i != range_right) 363065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 363165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offsets[1] = i; 363265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 363365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 363465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 363565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This case is handled better by fast_forward_first_char. */ 363665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[1] == -1 && offsets[0] == 0 && range_right < 0) 363765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 363865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 363965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offsets[2] = -1; 364065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We only search for a middle character if there is no range check. */ 364165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[1] >= 0 && range_right == -1) 364265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 364365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Scan from middle. */ 364465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++) 364565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ones[i] <= 2) 364665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 364765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offsets[2] = i; 364865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 364965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 365065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 365165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[2] == -1) 365265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 365365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--) 365465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ones[i] <= 2) 365565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 365665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offsets[2] = i; 365765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 365865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 365965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 366065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 366165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 366265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1])); 366365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2])); 366465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 366565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[0] = chars[offsets[0] << 1]; 366665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[1] = chars[(offsets[0] << 1) + 1]; 366765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[2] >= 0) 366865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 366965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[2] = chars[offsets[2] << 1]; 367065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[3] = chars[(offsets[2] << 1) + 1]; 367165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 367265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[1] >= 0) 367365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 367465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[4] = chars[offsets[1] << 1]; 367565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich chars[5] = chars[(offsets[1] << 1) + 1]; 367665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 367765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 367865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 367965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmax -= 1; 368065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 368165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 368265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->first_line_end != 0); 368365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); 368465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); 368565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); 368665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich quit = CMP(SLJIT_C_LESS_EQUAL, STR_END, 0, TMP1, 0); 368765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); 368865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(quit); 368965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 369065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 369165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); 369265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 369365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) 369465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (range_right >= 0) 369565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table); 369665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 369765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 369865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstart = LABEL(); 369965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichquit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 370065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 370165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0); 370265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 370365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (range_right >= 0) 370465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 370565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) 370665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); 370765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 370865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); 370965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 371065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 371165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) 371265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); 371365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 371465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); 371565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 371665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 371765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); 371865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 371965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 372065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offsets[0] >= 0) 372165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 372265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0])); 372365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[1] >= 0) 372465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1])); 372565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 372665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 372765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (chars[1] != 0) 372865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]); 372965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start); 373065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[2] >= 0) 373165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1)); 373265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 373365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[1] >= 0) 373465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 373565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (chars[5] != 0) 373665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]); 373765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start); 373865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 373965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 374065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offsets[2] >= 0) 374165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 374265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (chars[3] != 0) 374365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]); 374465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start); 374565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 374665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 374765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 374865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 374965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(quit); 375065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 375165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 375265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 375365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (range_right >= 0) 375465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); 375565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); 375665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (range_right >= 0) 375765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 375865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich quit = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); 375965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); 376065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(quit); 376165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 376265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 376365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 376465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); 376565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn TRUE; 376665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 376765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 376865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef MAX_N_CHARS 376965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef MAX_N_BYTES 377065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 377165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline) 377265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 377365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 377465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *start; 377565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *quit; 377665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *found; 377765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar oc, bit; 377865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 377965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 378065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 378165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->first_line_end != 0); 378265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); 378365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); 378465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 378565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 378665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstart = LABEL(); 378765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichquit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 378865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 378965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 379065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichoc = first_char; 379165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (caseless) 379265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 379365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = TABLE_GET(first_char, common->fcc, first_char); 379465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) 379565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (first_char > 127 && common->utf) 379665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = UCD_OTHERCASE(first_char); 379765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 379865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 379965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (first_char == oc) 380065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char); 380165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 380265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 380365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit = first_char ^ oc; 380465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (is_powerof2(bit)) 380565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 380665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); 380765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit); 380865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 380965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 381065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 381165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char); 381265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 381365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); 381465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 381565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich found = JUMP(SLJIT_C_NOT_ZERO); 381665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 381765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 381865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 381965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 382065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, start); 382165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(found); 382265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(quit); 382365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 382465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 382565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); 382665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 382765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 382865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline) 382965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 383065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 383165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *loop; 383265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *lastchar; 383365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *firstchar; 383465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *quit; 383565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *foundcr = NULL; 383665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *notfoundnl; 383765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *newline = NULL; 383865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 383965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 384065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 384165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->first_line_end != 0); 384265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); 384365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); 384465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 384565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 384665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->nltype == NLTYPE_FIXED && common->newline > 255) 384765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 384865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 384965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 385065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 385165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 385265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); 385365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 385465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); 385565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); 385665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL); 385765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 385865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); 385965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 386065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 386165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 386265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich loop = LABEL(); 386365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 386465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 386565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); 386665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); 386765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); 386865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); 386965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 387065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(quit); 387165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(firstchar); 387265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(lastchar); 387365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 387465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (firstline) 387565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); 387665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 387765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 387865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 387965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 388065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 388165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfirstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); 388265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichskip_char_back(common); 388365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 388465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichloop = LABEL(); 388565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->ff_newline_shortcut = loop; 388665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 388765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichread_char_range(common, common->nlmin, common->nlmax, TRUE); 388865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 388965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) 389065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); 389165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcheck_newlinechar(common, common->nltype, &newline, FALSE); 389265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(newline, loop); 389365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 389465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) 389565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 389665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich quit = JUMP(SLJIT_JUMP); 389765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(foundcr); 389865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 389965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 390065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); 390165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 390265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 390365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); 390465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 390565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 390665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(notfoundnl); 390765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(quit); 390865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 390965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(lastchar); 391065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(firstchar); 391165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 391265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 391365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); 391465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 391565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 391665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks); 391765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 391865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, pcre_uint8 *start_bits, BOOL firstline) 391965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 392065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 392165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *start; 392265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *quit; 392365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *found = NULL; 392465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *matches = NULL; 392565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 392665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 392765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 392865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 392965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 393065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 393165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->first_line_end != 0); 393265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0); 393365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); 393465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 393565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 393665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstart = LABEL(); 393765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichquit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 393865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 393965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 394065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 394165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); 394265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 394365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 394465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches)) 394565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 394665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 394765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255); 394865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); 394965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 395065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 395165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); 395265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); 395365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); 395465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); 395565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); 395665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich found = JUMP(SLJIT_C_NOT_ZERO); 395765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 395865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 395965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 396065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 396165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 396265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 396365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 396465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 396565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 396665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 396765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 396865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); 396965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); 397065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 397165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 397265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 397365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 397465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 397565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); 397665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 397765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); 397865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 397965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 398065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 398165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 398265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE[8|16] */ 398365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 398465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, start); 398565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (found != NULL) 398665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(found); 398765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (matches != NULL) 398865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(matches, LABEL()); 398965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(quit); 399065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 399165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (firstline) 399265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0); 399365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 399465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 399565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar) 399665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 399765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 399865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *loop; 399965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *toolong; 400065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *alreadyfound; 400165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *found; 400265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *foundoc = NULL; 400365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *notfound; 400465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint32 oc, bit; 400565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 400665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(common->req_char_ptr != 0); 400765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); 400865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX); 400965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtoolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); 401065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichalreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); 401165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 401265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (has_firstchar) 401365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 401465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 401565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); 401665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 401765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichloop = LABEL(); 401865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichnotfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0); 401965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 402065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); 402165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichoc = req_char; 402265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (caseless) 402365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 402465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = TABLE_GET(req_char, common->fcc, req_char); 402565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) 402665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (req_char > 127 && common->utf) 402765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = UCD_OTHERCASE(req_char); 402865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 402965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 403065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (req_char == oc) 403165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); 403265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 403365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 403465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit = req_char ^ oc; 403565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (is_powerof2(bit)) 403665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 403765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); 403865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); 403965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 404065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 404165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 404265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); 404365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc); 404465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 404565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 404665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); 404765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, loop); 404865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 404965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(found); 405065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (foundoc) 405165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(foundoc); 405265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0); 405365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(alreadyfound); 405465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(toolong); 405565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn notfound; 405665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 405765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 405865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void do_revertframes(compiler_common *common) 405965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 406065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 406165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 406265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *mainloop; 406365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 406465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 406565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); 406665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichGET_LOCAL_BASE(TMP3, 0, 0); 406765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 406865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Drop frames until we reach STACK_TOP. */ 406965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmainloop = LABEL(); 407065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); 407165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0); 407265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = JUMP(SLJIT_C_SIG_LESS_EQUAL); 407365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 407465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); 407565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); 407665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw)); 407765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw)); 407865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, mainloop); 407965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 408065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 408165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = JUMP(SLJIT_C_SIG_LESS); 408265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* End of dropping frames. */ 408365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 408465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 408565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 408665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_NEG, TMP2, 0, TMP2, 0); 408765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); 408865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); 408965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); 409065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, mainloop); 409165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 409265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 409365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void check_wordboundary(compiler_common *common) 409465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 409565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 409665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *skipread; 409765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *skipread_list = NULL; 409865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF 409965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 410065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 410165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 410265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); 410365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 410465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); 410565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Get type of the previous char, and put it to LOCALS1. */ 410665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 410765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 410865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0); 410965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichskipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); 411065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichskip_char_back(common); 411165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcheck_start_used_ptr(common); 411265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichread_char(common); 411365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 411465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Testing char type. */ 411565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 411665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->use_ucp) 411765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 411865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); 411965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); 412065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 412165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); 412265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); 412365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); 412465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); 412565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); 412665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 412765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 412865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); 412965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 413065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 413165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 413265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 413365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 413465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 413565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined SUPPORT_UTF 413665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Here LOCALS1 has already been zeroed. */ 413765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = NULL; 413865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 413965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 414065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE8 */ 414165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); 414265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); 414365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 414465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); 414565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 414665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 414765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined SUPPORT_UTF 414865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (jump != NULL) 414965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 415065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE8 */ 415165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 415265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(skipread); 415365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 415465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); 415565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcheck_str_end(common, &skipread_list); 415665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpeek_char(common, READ_CHAR_MAX); 415765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 415865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Testing char type. This is a code duplication. */ 415965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 416065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->use_ucp) 416165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 416265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); 416365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); 416465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 416565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); 416665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); 416765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); 416865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); 416965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); 417065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 417165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 417265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 417365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 417465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 417565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 417665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 417765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 may be destroyed by peek_char. */ 417865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); 417965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 418065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined SUPPORT_UTF 418165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); 418265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = NULL; 418365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 418465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 418565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 418665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); 418765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); 418865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); 418965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 419065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 419165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined SUPPORT_UTF 419265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (jump != NULL) 419365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 419465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE8 */ 419565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 419665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(skipread_list, LABEL()); 419765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 419865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); 419965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); 420065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 420165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 420265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks) 420365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 420465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 420565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint ranges[MAX_RANGE_SIZE]; 420665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint8 bit, cbit, all; 420765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i, byte, length = 0; 420865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 420965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbit = bits[0] & 0x1; 421065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* All bits will be zero or one (since bit is zero or one). */ 421165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichall = -bit; 421265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 421365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = 0; i < 256; ) 421465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 421565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich byte = i >> 3; 421665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((i & 0x7) == 0 && bits[byte] == all) 421765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich i += 8; 421865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 421965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 422065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cbit = (bits[byte] >> (i & 0x7)) & 0x1; 422165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cbit != bit) 422265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 422365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (length >= MAX_RANGE_SIZE) 422465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 422565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ranges[length] = i; 422665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length++; 422765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit = cbit; 422865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich all = -cbit; 422965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 423065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich i++; 423165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 423265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 423365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 423465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (((bit == 0) && nclass) || ((bit == 1) && !nclass)) 423565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 423665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (length >= MAX_RANGE_SIZE) 423765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 423865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ranges[length] = 256; 423965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length++; 424065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 424165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 424265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (length < 0 || length > 4) 424365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 424465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 424565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbit = bits[0] & 0x1; 424665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (invert) bit ^= 0x1; 424765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 424865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* No character is accepted. */ 424965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (length == 0 && bit == 0) 425065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 425165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 425265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(length) 425365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 425465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 0: 425565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* When bit != 0, all characters are accepted. */ 425665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 425765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 425865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 1: 425965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); 426065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 426165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 426265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 2: 426365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ranges[0] + 1 != ranges[1]) 426465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 426565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); 426665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); 426765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 426865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 426965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); 427065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 427165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 427265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 3: 427365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bit != 0) 427465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 427565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); 427665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ranges[0] + 1 != ranges[1]) 427765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 427865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); 427965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); 428065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 428165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 428265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); 428365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 428465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 428565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 428665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[0])); 428765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ranges[1] + 1 != ranges[2]) 428865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 428965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]); 429065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); 429165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 429265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 429365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1])); 429465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 429565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 429665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 4: 429765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2]) 429865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2] 429965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich && is_powerof2(ranges[2] - ranges[0])) 430065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 430165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]); 430265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ranges[2] + 1 != ranges[3]) 430365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 430465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); 430565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); 430665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 430765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 430865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); 430965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 431065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 431165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 431265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bit != 0) 431365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 431465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich i = 0; 431565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ranges[0] + 1 != ranges[1]) 431665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 431765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); 431865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); 431965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich i = ranges[0]; 432065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 432165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 432265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); 432365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 432465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ranges[2] + 1 != ranges[3]) 432565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 432665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i); 432765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); 432865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 432965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 433065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i)); 433165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 433265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 433365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 433465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); 433565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0])); 433665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ranges[1] + 1 != ranges[2]) 433765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 433865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]); 433965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); 434065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 434165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 434265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); 434365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return TRUE; 434465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 434565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 434665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 434765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return FALSE; 434865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 434965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 435065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 435165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void check_anynewline(compiler_common *common) 435265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 435365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ 435465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 435565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 435665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 435765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 435865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); 435965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); 436065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); 436165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); 436265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 436365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 436465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 436565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 436665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 436765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 436865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); 436965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); 437065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 437165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 437265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 437365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ 437465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 437565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 437665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 437765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 437865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void check_hspace(compiler_common *common) 437965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 438065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ 438165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 438265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 438365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 438465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 438565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); 438665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 438765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); 438865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 438965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); 439065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 439165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 439265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 439365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 439465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 439565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 439665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); 439765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 439865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); 439965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 440065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); 440165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); 440265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 440365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); 440465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 440565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); 440665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 440765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); 440865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 440965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 441065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 441165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ 441265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 441365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 441465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 441565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 441665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 441765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void check_vspace(compiler_common *common) 441865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 441965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ 442065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 442165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 442265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 442365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 442465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); 442565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); 442665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); 442765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); 442865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 442965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 443065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 443165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 443265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 443365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 443465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); 443565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); 443665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 443765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 443865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 443965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ 444065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 444165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 444265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 444365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 444465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 444565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHAR1 STR_END 444665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHAR2 STACK_TOP 444765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 444865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void do_casefulcmp(compiler_common *common) 444965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 445065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 445165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 445265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *label; 445365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 445465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 445565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 445665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); 445765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0); 445865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); 445965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 446065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 446165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel = LABEL(); 446265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); 446365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 446465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); 446565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); 446665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_C_NOT_ZERO, label); 446765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 446865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 446965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 447065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, CHAR1, 0, TMP3, 0); 447165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); 447265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 447365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 447465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 447565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define LCC_TABLE STACK_LIMIT 447665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 447765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void do_caselesscmp(compiler_common *common) 447865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 447965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 448065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 448165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *label; 448265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 448365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, RETURN_ADDR, 0); 448465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 448565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 448665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); 448765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0); 448865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0); 448965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc); 449065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); 449165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 449265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 449365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel = LABEL(); 449465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); 449565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 449665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 449765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255); 449865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 449965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); 450065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 450165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 450265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255); 450365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 450465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); 450565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifndef COMPILE_PCRE8 450665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 450765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 450865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); 450965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); 451065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_C_NOT_ZERO, label); 451165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 451265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 451365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 451465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0); 451565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); 451665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); 451765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, RETURN_ADDR, 0); 451865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 451965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 452065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef LCC_TABLE 452165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CHAR1 452265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CHAR2 452365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 452465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined SUPPORT_UCP 452565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 452665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1) 452765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 452865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* This function would be ineffective to do in JIT level. */ 452965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint32 c1, c2; 453065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst pcre_uchar *src2 = args->uchar_ptr; 453165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst pcre_uchar *end2 = args->end; 453265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst ucd_record *ur; 453365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst pcre_uint32 *pp; 453465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 453565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (src1 < end1) 453665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 453765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (src2 >= end2) 453865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return (pcre_uchar*)1; 453965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARINC(c1, src1); 454065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARINC(c2, src2); 454165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ur = GET_UCD(c2); 454265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c1 != c2 && c1 != c2 + ur->other_case) 454365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 454465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich pp = PRIV(ucd_caseless_sets) + ur->caseset; 454565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich for (;;) 454665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 454765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c1 < *pp) return NULL; 454865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c1 == *pp++) break; 454965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 455065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 455165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 455265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn src2; 455365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 455465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 455565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && SUPPORT_UCP */ 455665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 455765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc, 455865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compare_context* context, jump_list **backtracks) 455965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 456065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 456165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunsigned int othercasebit = 0; 456265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *othercasechar = NULL; 456365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 456465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint utflength; 456565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 456665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 456765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (caseless && char_has_othercase(common, cc)) 456865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 456965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich othercasebit = char_get_othercase_bit(common, cc); 457065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(othercasebit); 457165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Extracting bit difference info. */ 457265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 457365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich othercasechar = cc + (othercasebit >> 8); 457465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich othercasebit &= 0xff; 457565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 457665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Note that this code only handles characters in the BMP. If there 457765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ever are characters outside the BMP whose othercase differs in only one 457865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit from itself (there currently are none), this code will need to be 457965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich revised for COMPILE_PCRE32. */ 458065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich othercasechar = cc + (othercasebit >> 9); 458165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((othercasebit & 0x100) != 0) 458265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich othercasebit = (othercasebit & 0xff) << 8; 458365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 458465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich othercasebit &= 0xff; 458565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE[8|16|32] */ 458665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 458765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 458865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (context->sourcereg == -1) 458965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 459065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 459165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 459265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->length >= 4) 459365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 459465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (context->length >= 2) 459565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 459665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 459765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 459865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 459965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 460065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 460165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->length >= 4) 460265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 460365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 460465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 460565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 460665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 460765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); 460865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE[8|16|32] */ 460965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->sourcereg = TMP2; 461065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 461165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 461265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 461365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichutflength = 1; 461465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf && HAS_EXTRALEN(*cc)) 461565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich utflength += GET_EXTRALEN(*cc); 461665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 461765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichdo 461865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 461965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 462065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 462165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->length -= IN_UCHARS(1); 462265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16) 462365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 462465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Unaligned read is supported. */ 462565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (othercasebit != 0 && othercasechar == cc) 462665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 462765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->c.asuchars[context->ucharptr] = *cc | othercasebit; 462865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->oc.asuchars[context->ucharptr] = othercasebit; 462965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 463065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 463165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 463265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->c.asuchars[context->ucharptr] = *cc; 463365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->oc.asuchars[context->ucharptr] = 0; 463465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 463565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->ucharptr++; 463665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 463765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 463865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) 463965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 464065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->ucharptr >= 2 || context->length == 0) 464165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 464265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 464365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->length >= 4) 464465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 464565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (context->length >= 2) 464665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 464765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 464865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (context->length >= 1) 464965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 465065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE8 */ 465165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; 465265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 465365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(context->ucharptr) 465465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 465565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 4 / sizeof(pcre_uchar): 465665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->oc.asint != 0) 465765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); 465865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); 465965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 466065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 466165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 2 / sizeof(pcre_uchar): 466265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->oc.asushort != 0) 466365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); 466465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); 466565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 466665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 466765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 466865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 1: 466965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->oc.asbyte != 0) 467065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); 467165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); 467265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 467365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 467465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 467565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 467665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 467765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 467865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 467965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->ucharptr = 0; 468065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 468165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 468265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 468365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 468465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Unaligned read is unsupported or in 32 bit mode. */ 468565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (context->length >= 1) 468665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); 468765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 468865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; 468965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 469065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (othercasebit != 0 && othercasechar == cc) 469165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 469265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); 469365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); 469465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 469565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 469665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); 469765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 469865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 469965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 470065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 470165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 470265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich utflength--; 470365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 470465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (utflength > 0); 470565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 470665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 470765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc; 470865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 470965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 471065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 471165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 471265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SET_TYPE_OFFSET(value) \ 471365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((value) != typeoffset) \ 471465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { \ 471565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((value) < typeoffset) \ 471665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ 471765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else \ 471865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ 471965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } \ 472065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich typeoffset = (value); 472165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 472265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define SET_CHAR_OFFSET(value) \ 472365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((value) != charoffset) \ 472465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { \ 472565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((value) < charoffset) \ 472665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \ 472765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else \ 472865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \ 472965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } \ 473065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich charoffset = (value); 473165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 473265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) 473365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 473465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 473565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *found = NULL; 473665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks; 473765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX; 473865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump = NULL; 473965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccbegin; 474065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint compares, invertcmp, numberofcmps; 474165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16) 474265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL utf = common->utf; 474365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 474465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 474565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 474665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; 474765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL charsaved = FALSE; 474865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint typereg = TMP1, scriptreg = TMP1; 474965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst pcre_uint32 *other_cases; 475065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_uw typeoffset; 475165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 475265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 475365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Scanning the necessary info. */ 475465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc++; 475565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichccbegin = cc; 475665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompares = 0; 475765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (cc[-1] & XCL_MAP) 475865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 475965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min = 0; 476065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 32 / sizeof(pcre_uchar); 476165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 476265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 476365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (*cc != XCL_END) 476465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 476565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compares++; 476665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == XCL_SINGLE) 476765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 476865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc ++; 476965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARINCTEST(c, cc); 477065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c > max) max = c; 477165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c < min) min = c; 477265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 477365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich needschar = TRUE; 477465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 477565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 477665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (*cc == XCL_RANGE) 477765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 477865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc ++; 477965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARINCTEST(c, cc); 478065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c < min) min = c; 478165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARINCTEST(c, cc); 478265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c > max) max = c; 478365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 478465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich needschar = TRUE; 478565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 478665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 478765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 478865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 478965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 479065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); 479165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 479265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == PT_CLIST) 479365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 479465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich other_cases = PRIV(ucd_caseless_sets) + cc[1]; 479565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (*other_cases != NOTACHAR) 479665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 479765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*other_cases > max) max = *other_cases; 479865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*other_cases < min) min = *other_cases; 479965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich other_cases++; 480065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 480165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 480265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 480365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 480465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max = READ_CHAR_MAX; 480565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min = 0; 480665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 480765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 480865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 480965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 481065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_ANY: 481165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 481265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 481365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_LAMP: 481465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_GC: 481565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PC: 481665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_ALNUM: 481765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich needstype = TRUE; 481865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 481965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 482065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_SC: 482165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich needsscript = TRUE; 482265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 482365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 482465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_SPACE: 482565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PXSPACE: 482665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_WORD: 482765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PXGRAPH: 482865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PXPRINT: 482965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PXPUNCT: 483065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich needstype = TRUE; 483165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich needschar = TRUE; 483265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 483365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 483465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_CLIST: 483565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_UCNC: 483665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich needschar = TRUE; 483765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 483865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 483965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 484065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 484165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 484265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 484365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2; 484465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 484565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 484665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 484765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 484865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* We are not necessary in utf mode even in 8 bit mode. */ 484965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc = ccbegin; 485065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichdetect_partial_match(common, backtracks); 485165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichread_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0); 485265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 485365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((cc[-1] & XCL_HASPROP) == 0) 485465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 485565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((cc[-1] & XCL_MAP) != 0) 485665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 485765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 485865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found)) 485965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 486065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); 486165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); 486265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); 486365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); 486465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); 486565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO)); 486665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 486765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 486865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 486965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 487065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 487165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 32 / sizeof(pcre_uchar); 487265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 487365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 487465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 487565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min); 487665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, max - min)); 487765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 487865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 487965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if ((cc[-1] & XCL_MAP) != 0) 488065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 488165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); 488265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 488365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich charsaved = TRUE; 488465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 488565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list)) 488665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 488765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 488865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->utf); 488965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 489065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 489165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 489265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); 489365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); 489465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); 489565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); 489665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); 489765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO)); 489865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 489965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 490065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 490165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 490265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 490365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 32 / sizeof(pcre_uchar); 490465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 490565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 490665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 490765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Simple register allocation. TMP1 is preferred if possible. */ 490865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (needstype || needsscript) 490965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 491065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needschar && !charsaved) 491165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); 491265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 491365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needschar) 491465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 491565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needstype) 491665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 491765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); 491865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich typereg = RETURN_ADDR; 491965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 492065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 492165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needsscript) 492265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich scriptreg = TMP3; 492365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 492465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 492565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (needstype && needsscript) 492665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich scriptreg = TMP3; 492765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* In all other cases only one of them was specified, and that can goes to TMP1. */ 492865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 492965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needsscript) 493065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 493165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (scriptreg == TMP1) 493265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 493365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); 493465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3); 493565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 493665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 493765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 493865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); 493965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); 494065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0); 494165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 494265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 494365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 494465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 494565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 494665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Generating code. */ 494765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcharoffset = 0; 494865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichnumberofcmps = 0; 494965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 495065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtypeoffset = 0; 495165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 495265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 495365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (*cc != XCL_END) 495465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 495565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compares--; 495665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich invertcmp = (compares == 0 && list != backtracks); 495765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = NULL; 495865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 495965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == XCL_SINGLE) 496065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 496165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc ++; 496265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARINCTEST(c, cc); 496365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 496465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) 496565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 496665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); 496765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL); 496865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich numberofcmps++; 496965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 497065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (numberofcmps > 0) 497165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 497265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); 497365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 497465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 497565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich numberofcmps = 0; 497665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 497765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 497865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 497965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); 498065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich numberofcmps = 0; 498165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 498265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 498365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (*cc == XCL_RANGE) 498465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 498565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc ++; 498665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARINCTEST(c, cc); 498765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_CHAR_OFFSET(c); 498865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARINCTEST(c, cc); 498965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 499065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) 499165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 499265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); 499365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL); 499465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich numberofcmps++; 499565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 499665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (numberofcmps > 0) 499765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 499865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); 499965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 500065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 500165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich numberofcmps = 0; 500265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 500365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 500465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 500565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); 500665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich numberofcmps = 0; 500765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 500865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 500965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 501065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 501165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 501265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == XCL_NOTPROP) 501365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich invertcmp ^= 0x1; 501465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 501565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 501665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 501765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_ANY: 501865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (list != backtracks) 501965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 502065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0)) 502165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 502265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 502365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (cc[-1] == XCL_NOTPROP) 502465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue; 502565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_JUMP); 502665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 502765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 502865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_LAMP: 502965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); 503065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 503165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); 503265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 503365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); 503465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 503565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 503665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 503765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 503865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_GC: 503965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich c = PRIV(ucp_typerange)[(int)cc[1] * 2]; 504065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_TYPE_OFFSET(c); 504165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); 504265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 504365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 504465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PC: 504565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); 504665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 504765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 504865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_SC: 504965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]); 505065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 505165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 505265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_SPACE: 505365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PXSPACE: 505465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_CHAR_OFFSET(9); 505565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9); 505665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); 505765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 505865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); 505965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 506065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 506165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); 506265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 506365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 506465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_TYPE_OFFSET(ucp_Zl); 506565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); 506665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 506765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 506865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 506965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 507065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_WORD: 507165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset)); 507265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 507365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Fall through. */ 507465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 507565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_ALNUM: 507665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_TYPE_OFFSET(ucp_Ll); 507765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); 507865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL); 507965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_TYPE_OFFSET(ucp_Nd); 508065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); 508165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 508265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 508365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 508465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 508565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_CLIST: 508665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich other_cases = PRIV(ucd_caseless_sets) + cc[1]; 508765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 508865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* At least three characters are required. 508965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Otherwise this case would be handled by the normal code path. */ 509065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR); 509165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); 509265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 509365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Optimizing character pairs, if their difference is power of 2. */ 509465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (is_powerof2(other_cases[1] ^ other_cases[0])) 509565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 509665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (charoffset == 0) 509765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); 509865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 509965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 510065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); 510165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); 510265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 510365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]); 510465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 510565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich other_cases += 2; 510665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 510765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (is_powerof2(other_cases[2] ^ other_cases[1])) 510865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 510965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (charoffset == 0) 511065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]); 511165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 511265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 511365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); 511465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); 511565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 511665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]); 511765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 511865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 511965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset)); 512065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 512165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 512265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich other_cases += 3; 512365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 512465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 512565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 512665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); 512765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 512865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 512965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 513065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (*other_cases != NOTACHAR) 513165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 513265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); 513365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 513465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 513565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 513665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 513765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 513865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_UCNC: 513965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); 514065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 514165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); 514265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 514365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); 514465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 514565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 514665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_CHAR_OFFSET(0xa0); 514765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); 514865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 514965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_CHAR_OFFSET(0); 515065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0); 515165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL); 515265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 515365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 515465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 515565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PXGRAPH: 515665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* C and Z groups are the farthest two groups. */ 515765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_TYPE_OFFSET(ucp_Ll); 515865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); 515965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER); 516065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 516165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); 516265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 516365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* In case of ucp_Cf, we overwrite the result. */ 516465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_CHAR_OFFSET(0x2066); 516565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); 516665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); 516765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 516865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); 516965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 517065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 517165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); 517265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 517365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 517465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 517565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); 517665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 517765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 517865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PXPRINT: 517965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* C and Z groups are the farthest two groups. */ 518065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_TYPE_OFFSET(ucp_Ll); 518165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); 518265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER); 518365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 518465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll); 518565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL); 518665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 518765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); 518865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 518965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* In case of ucp_Cf, we overwrite the result. */ 519065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_CHAR_OFFSET(0x2066); 519165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); 519265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); 519365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 519465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); 519565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); 519665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 519765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 519865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); 519965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 520065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 520165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PT_PXPUNCT: 520265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_TYPE_OFFSET(ucp_Sc); 520365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc); 520465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); 520565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 520665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_CHAR_OFFSET(0); 520765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff); 520865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 520965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 521065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_TYPE_OFFSET(ucp_Pc); 521165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc); 521265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); 521365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); 521465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 521565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 521665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 2; 521765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 521865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 521965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 522065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (jump != NULL) 522165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, compares > 0 ? list : backtracks, jump); 522265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 522365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 522465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (found != NULL) 522565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(found, LABEL()); 522665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 522765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 522865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef SET_TYPE_OFFSET 522965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef SET_CHAR_OFFSET 523065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 523165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 523265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 523365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) 523465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 523565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 523665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint length; 523765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunsigned int c, oc, bit; 523865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompare_context context; 523965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump[4]; 524065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *end_list; 524165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 524265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *label; 524365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 524465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar propdata[5]; 524565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 524665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 524765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 524865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(type) 524965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 525065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SOD: 525165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 525265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 525365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); 525465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 525565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 525665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SOM: 525765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 525865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 525965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); 526065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 526165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 526265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORD_BOUNDARY: 526365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORD_BOUNDARY: 526465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); 526565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 526665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 526765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 526865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_DIGIT: 526965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DIGIT: 527065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Digits are usually 0-9, so it is worth to optimize them. */ 527165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 527265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 527365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE)) 527465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char7_type(common, type == OP_NOT_DIGIT); 527565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 527665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 527765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char8_type(common, type == OP_NOT_DIGIT); 527865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Flip the starting bit in the negative case. */ 527965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); 528065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); 528165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 528265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 528365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WHITESPACE: 528465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WHITESPACE: 528565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 528665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 528765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE)) 528865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char7_type(common, type == OP_NOT_WHITESPACE); 528965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 529065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 529165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char8_type(common, type == OP_NOT_WHITESPACE); 529265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); 529365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); 529465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 529565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 529665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORDCHAR: 529765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORDCHAR: 529865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 529965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 530065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE)) 530165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char7_type(common, type == OP_NOT_WORDCHAR); 530265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 530365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 530465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char8_type(common, type == OP_NOT_WORDCHAR); 530565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); 530665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); 530765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 530865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 530965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANY: 531065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 531165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, common->nlmin, common->nlmax, TRUE); 531265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->nltype == NLTYPE_FIXED && common->newline > 255) 531365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 531465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); 531565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end_list = NULL; 531665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode != JIT_PARTIAL_HARD_COMPILE) 531765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); 531865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 531965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_str_end(common, &end_list); 532065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 532165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 532265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); 532365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(end_list, LABEL()); 532465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 532565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 532665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 532765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_newlinechar(common, common->nltype, backtracks, TRUE); 532865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 532965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 533065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ALLANY: 533165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 533265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 533365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 533465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 533565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 533665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 533765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 533865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 533965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 534065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); 534165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 534265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 534365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); 534465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); 534565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); 534665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); 534765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 534865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 534965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 535065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 535165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE[8|16] */ 535265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 535365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 535465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 535565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 535665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 535765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 535865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYBYTE: 535965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 536065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 536165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 536265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 536365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 536465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 536565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPROP: 536665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PROP: 536765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich propdata[0] = XCL_HASPROP; 536865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; 536965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich propdata[2] = cc[0]; 537065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich propdata[3] = cc[1]; 537165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich propdata[4] = XCL_END; 537265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_xclass_matchingpath(common, propdata, backtracks); 537365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 2; 537465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 537565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 537665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 537765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYNL: 537865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 537965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); 538065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); 538165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We don't need to handle soft partial matching case. */ 538265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich end_list = NULL; 538365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode != JIT_PARTIAL_HARD_COMPILE) 538465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); 538565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 538665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_str_end(common, &end_list); 538765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 538865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); 538965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 539065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[2] = JUMP(SLJIT_JUMP); 539165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 539265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); 539365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(end_list, LABEL()); 539465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[1]); 539565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[2]); 539665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 539765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 539865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_HSPACE: 539965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_HSPACE: 540065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 540165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); 540265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); 540365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 540465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 540565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 540665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_VSPACE: 540765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_VSPACE: 540865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 540965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); 541065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); 541165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); 541265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 541365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 541465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 541565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXTUNI: 541665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 541765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char(common); 541865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 541965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); 542065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Optimize register allocation: use a real register. */ 542165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); 542265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); 542365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 542465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 542565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 542665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); 542765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char(common); 542865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); 542965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); 543065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); 543165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 543265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2); 543365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); 543465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); 543565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); 543665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); 543765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, label); 543865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 543965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); 544065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 544165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); 544265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 544365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode == JIT_PARTIAL_HARD_COMPILE) 544465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 544565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); 544665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Since we successfully read a char above, partial matching must occure. */ 544765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, TRUE); 544865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 544965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 545065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 545165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 545265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 545365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EODN: 545465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Requires rather complex checks. */ 545565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); 545665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->nltype == NLTYPE_FIXED && common->newline > 255) 545765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 545865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 545965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 546065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode == JIT_COMPILE) 546165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); 546265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 546365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 546465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); 546565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); 546665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS); 546765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); 546865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL); 546965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL)); 547065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, TRUE); 547165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 547265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[1]); 547365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 547465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 547565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); 547665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); 547765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 547865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (common->nltype == NLTYPE_FIXED) 547965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 548065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 548165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 548265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); 548365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); 548465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 548565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 548665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 548765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 548865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); 548965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 549065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); 549165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[2] = JUMP(SLJIT_C_GREATER); 549265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS)); 549365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Equal. */ 549465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 549565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); 549665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 549765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 549865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[1]); 549965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->nltype == NLTYPE_ANYCRLF) 550065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 550165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 550265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0)); 550365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); 550465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 550565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 550665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 550765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); 550865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, common->nlmin, common->nlmax, TRUE); 550965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); 551065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); 551165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); 551265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); 551365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 551465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[2]); 551565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[3]); 551665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 551765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 551865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, FALSE); 551965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 552065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 552165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EOD: 552265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); 552365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, FALSE); 552465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 552565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 552665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRC: 552765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); 552865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); 552965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0)); 553065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); 553165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 553265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 553365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 553465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRCM: 553565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); 553665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); 553765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0); 553865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); 553965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 554065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = JUMP(SLJIT_JUMP); 554165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[1]); 554265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 554365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); 554465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->nltype == NLTYPE_FIXED && common->newline > 255) 554565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 554665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 554765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0)); 554865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); 554965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); 555065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); 555165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); 555265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 555365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 555465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 555565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich skip_char_back(common); 555665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, common->nlmin, common->nlmax, TRUE); 555765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_newlinechar(common, common->nltype, backtracks, FALSE); 555865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 555965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 556065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 556165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 556265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLL: 556365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); 556465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); 556565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 556665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 556765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!common->endonly) 556865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, OP_EODN, cc, backtracks); 556965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 557065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 557165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); 557265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, FALSE); 557365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 557465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 557565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 557665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLLM: 557765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); 557865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); 557965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); 558065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 558165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, FALSE); 558265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = JUMP(SLJIT_JUMP); 558365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[1]); 558465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 558565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->nltype == NLTYPE_FIXED && common->newline > 255) 558665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 558765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 558865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); 558965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode == JIT_COMPILE) 559065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); 559165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 559265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 559365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); 559465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* STR_PTR = STR_END - IN_UCHARS(1) */ 559565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); 559665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, TRUE); 559765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 559865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[1]); 559965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 560065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 560165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); 560265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); 560365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); 560465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 560565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 560665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 560765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich peek_char(common, common->nlmax); 560865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_newlinechar(common, common->nltype, backtracks, FALSE); 560965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 561065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 561165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 561265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 561365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHAR: 561465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHARI: 561565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length = 1; 561665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 561765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); 561865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 561965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) 562065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 562165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); 562265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); 562365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 562465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context.length = IN_UCHARS(length); 562565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context.sourcereg = -1; 562665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 562765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context.ucharptr = 0; 562865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 562965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); 563065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 563165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 563265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 563365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 563465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 563565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 563665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHAR(c, cc); 563765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 563865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 563965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 564065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich c = *cc; 564165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 564265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (type == OP_CHAR || !char_has_othercase(common, cc)) 564365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 564465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, c, c, FALSE); 564565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); 564665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + length; 564765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 564865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = char_othercase(common, c); 564965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE); 565065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit = c ^ oc; 565165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (is_powerof2(bit)) 565265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 565365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); 565465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); 565565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + length; 565665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 565765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c); 565865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); 565965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 566065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + length; 566165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 566265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT: 566365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTI: 566465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 566565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length = 1; 566665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 566765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 566865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 566965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 567065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich c = *cc; 567165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (c < 128) 567265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 567365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); 567465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (type == OP_NOT || !char_has_othercase(common, cc)) 567565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); 567665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 567765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 567865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ 567965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); 568065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); 568165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 568265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Skip the variable-length character. */ 568365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); 568465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); 568565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); 568665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); 568765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 568865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 1; 568965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 569065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 569165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE8 */ 569265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 569365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GETCHARLEN(c, cc, length); 569465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 569565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 569665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 569765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 569865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich c = *cc; 569965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 570065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (type == OP_NOT || !char_has_othercase(common, cc)) 570165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 570265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, c, c, TRUE); 570365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); 570465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 570565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 570665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 570765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich oc = char_othercase(common, c); 570865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE); 570965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit = c ^ oc; 571065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (is_powerof2(bit)) 571165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 571265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); 571365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); 571465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 571565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 571665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 571765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); 571865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); 571965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 572065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 572165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + length; 572265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 572365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 572465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 572565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich detect_partial_match(common, backtracks); 572665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 572765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 572865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255; 572965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, 0, bit, type == OP_NCLASS); 573065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 573165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich read_char_range(common, 0, 255, type == OP_NCLASS); 573265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 573365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 573465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks)) 573565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 32 / sizeof(pcre_uchar); 573665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 573765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined COMPILE_PCRE8 573865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = NULL; 573965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 574065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 574165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, bit); 574265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (type == OP_CLASS) 574365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 574465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, jump[0]); 574565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = NULL; 574665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 574765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 574865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif !defined COMPILE_PCRE8 574965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); 575065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (type == OP_CLASS) 575165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 575265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, jump[0]); 575365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump[0] = NULL; 575465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 575565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && COMPILE_PCRE8 */ 575665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 575765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); 575865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); 575965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); 576065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); 576165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); 576265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); 576365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 576465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 576565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (jump[0] != NULL) 576665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump[0]); 576765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 576865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 576965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 32 / sizeof(pcre_uchar); 577065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 577165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 577265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 577365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); 577465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + GET(cc, 0) - 1; 577565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 577665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 577765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REVERSE: 577865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich length = GET(cc, 0); 577965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (length == 0) 578065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + LINK_SIZE; 578165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 578265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 578365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 578465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 578565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 578665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); 578765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 578865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); 578965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich skip_char_back(common); 579065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); 579165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, label); 579265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 579365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 579465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 579565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 579665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); 579765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); 579865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); 579965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 580065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_start_used_ptr(common); 580165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + LINK_SIZE; 580265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 580365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT_STOP(); 580465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc; 580565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 580665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 580765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks) 580865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 580965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* This function consumes at least one input character. */ 581065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ 581165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 581265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccbegin = cc; 581365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompare_context context; 581465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint size; 581565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 581665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcontext.length = 0; 581765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichdo 581865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 581965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc >= ccend) 582065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 582165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 582265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_CHAR) 582365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 582465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 1; 582565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 582665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(cc[1])) 582765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size += GET_EXTRALEN(cc[1]); 582865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 582965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 583065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (*cc == OP_CHARI) 583165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 583265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 1; 583365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 583465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf) 583565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 583665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) 583765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 0; 583865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (HAS_EXTRALEN(cc[1])) 583965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size += GET_EXTRALEN(cc[1]); 584065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 584165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 584265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 584365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) 584465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 0; 584565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 584665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 584765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size = 0; 584865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 584965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + size; 585065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context.length += IN_UCHARS(size); 585165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 585265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (size > 0 && context.length <= 128); 585365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 585465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc = ccbegin; 585565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (context.length > 0) 585665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 585765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We have a fixed-length byte sequence. */ 585865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); 585965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); 586065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 586165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context.sourcereg = -1; 586265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED 586365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich context.ucharptr = 0; 586465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 586565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); 586665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 586765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 586865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 586965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* A non-fixed length character will be checked if length == 0. */ 587065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn compile_char1_matchingpath(common, *cc, cc + 1, backtracks); 587165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 587265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 587365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Forward definitions. */ 587465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); 587565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_backtrackingpath(compiler_common *, struct backtrack_common *); 587665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 587765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define PUSH_BACKTRACK(size, ccstart, error) \ 587865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do \ 587965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { \ 588065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack = sljit_alloc_memory(compiler, (size)); \ 588165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ 588265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return error; \ 588365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich memset(backtrack, 0, size); \ 588465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->prev = parent->top; \ 588565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->cc = (ccstart); \ 588665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich parent->top = backtrack; \ 588765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } \ 588865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (0) 588965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 589065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \ 589165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do \ 589265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { \ 589365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack = sljit_alloc_memory(compiler, (size)); \ 589465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ 589565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; \ 589665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich memset(backtrack, 0, size); \ 589765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->prev = parent->top; \ 589865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->cc = (ccstart); \ 589965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich parent->top = backtrack; \ 590065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } \ 590165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (0) 590265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 590365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define BACKTRACK_AS(type) ((type *)backtrack) 590465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 590565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_dnref_search(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) 590665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 590765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* The OVECTOR offset goes to TMP2. */ 590865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 590965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint count = GET2(cc, 1 + IMM2_SIZE); 591065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size; 591165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunsigned int offset; 591265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *found = NULL; 591365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 591465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI); 591565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 591665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); 591765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 591865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcount--; 591965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (count-- > 0) 592065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 592165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset = GET2(slot, 0) << 1; 592265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); 592365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); 592465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich slot += common->name_entry_size; 592565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 592665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 592765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichoffset = GET2(slot, 0) << 1; 592865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichGET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); 592965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (backtracks != NULL && !common->jscript_compat) 593065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); 593165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 593265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(found, LABEL()); 593365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 593465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 593565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) 593665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 593765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 593865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL ref = (*cc == OP_REF || *cc == OP_REFI); 593965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset = 0; 594065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump = NULL; 594165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *partial; 594265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *nopartial; 594365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 594465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ref) 594565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 594665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset = GET2(cc, 1) << 1; 594765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); 594865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* OVECTOR(1) contains the "string begin - 1" constant. */ 594965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (withchecks && !common->jscript_compat) 595065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); 595165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 595265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 595365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); 595465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 595565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF && defined SUPPORT_UCP 595665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf && *cc == OP_REFI) 595765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 595865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2); 595965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ref) 596065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); 596165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 596265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); 596365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 596465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (withchecks) 596565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); 596665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 596765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Needed to save important temporary registers. */ 596865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); 596965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); 597065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0); 597165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); 597265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); 597365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode == JIT_COMPILE) 597465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); 597565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 597665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 597765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); 597865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); 597965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, FALSE); 598065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 598165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(nopartial); 598265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 598365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); 598465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 598565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 598665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF && SUPPORT_UCP */ 598765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 598865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ref) 598965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0); 599065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 599165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); 599265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 599365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (withchecks) 599465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_C_ZERO); 599565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 599665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); 599765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); 599865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode == JIT_COMPILE) 599965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, partial); 600065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 600165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); 600265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 600365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 600465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode != JIT_COMPILE) 600565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 600665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich nopartial = JUMP(SLJIT_JUMP); 600765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(partial); 600865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 -= STR_END - STR_PTR */ 600965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); 601065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); 601165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); 601265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); 601365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); 601465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 601565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(partial); 601665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_partial(common, FALSE); 601765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); 601865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(nopartial); 601965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 602065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 602165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 602265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (jump != NULL) 602365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 602465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (emptyfail) 602565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, backtracks, jump); 602665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 602765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 602865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 602965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 603065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 603165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 603265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 603365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 603465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL ref = (*cc == OP_REF || *cc == OP_REFI); 603565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 603665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar type; 603765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset = 0; 603865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *label; 603965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *zerolength; 604065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump = NULL; 604165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccbegin = cc; 604265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint min = 0, max = 0; 604365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL minimize; 604465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 604565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); 604665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 604765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ref) 604865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset = GET2(cc, 1) << 1; 604965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 605065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += IMM2_SIZE; 605165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtype = cc[1 + IMM2_SIZE]; 605265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 605365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even); 605465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichminimize = (type & 0x1) != 0; 605565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(type) 605665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 605765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRSTAR: 605865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINSTAR: 605965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min = 0; 606065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max = 0; 606165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE + 1; 606265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 606365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPLUS: 606465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINPLUS: 606565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min = 1; 606665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max = 0; 606765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE + 1; 606865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 606965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRQUERY: 607065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINQUERY: 607165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min = 0; 607265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max = 1; 607365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE + 1; 607465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 607565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRRANGE: 607665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINRANGE: 607765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min = GET2(cc, 1 + IMM2_SIZE + 1); 607865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE); 607965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE; 608065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 608165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 608265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 608365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 608465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 608565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 608665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!minimize) 608765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 608865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (min == 0) 608965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 609065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 2); 609165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ref) 609265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); 609365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 609465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); 609565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Temporary release of STR_PTR. */ 609665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); 609765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Handles both invalid and empty cases. Since the minimum repeat, 609865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich is zero the invalid case is basically the same as an empty case. */ 609965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ref) 610065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); 610165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 610265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 610365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_dnref_search(common, ccbegin, NULL); 610465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); 610565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); 610665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); 610765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 610865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Restore if not zero length. */ 610965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); 611065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 611165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 611265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 611365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 611465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ref) 611565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); 611665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 611765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ref) 611865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 611965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); 612065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); 612165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 612265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 612365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 612465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); 612565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); 612665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); 612765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); 612865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 612965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 613065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 613165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (min > 1 || max > 1) 613265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); 613365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 613465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 613565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!ref) 613665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); 613765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); 613865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 613965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (min > 1 || max > 1) 614065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 614165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); 614265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 614365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); 614465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (min > 1) 614565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); 614665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max > 1) 614765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 614865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); 614965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 615065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 615165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, label); 615265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 615365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 615465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 615565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 615665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max == 0) 615765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 615865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Includes min > 1 case as well. */ 615965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 616065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 616165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, label); 616265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 616365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 616465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(zerolength); 616565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); 616665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 616765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count_match(common); 616865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 616965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 617065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 617165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichallocate_stack(common, ref ? 2 : 3); 617265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ref) 617365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); 617465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 617565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (type != OP_CRMINSTAR) 617665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); 617765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 617865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (min == 0) 617965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 618065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Handles both invalid and empty cases. Since the minimum repeat, 618165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich is zero the invalid case is basically the same as an empty case. */ 618265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ref) 618365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); 618465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 618565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 618665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_dnref_search(common, ccbegin, NULL); 618765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); 618865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); 618965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); 619065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 619165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Length is non-zero, we can match real repeats. */ 619265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 619365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_JUMP); 619465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 619565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 619665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 619765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ref) 619865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 619965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); 620065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); 620165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 620265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 620365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 620465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); 620565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); 620665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); 620765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); 620865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 620965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 621065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 621165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); 621265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (max > 0) 621365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); 621465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 621565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!ref) 621665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); 621765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); 621865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 621965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 622065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (min > 1) 622165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 622265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 622365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 622465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 622565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath); 622665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 622765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (max > 0) 622865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); 622965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 623065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (jump != NULL) 623165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 623265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(zerolength); 623365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 623465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcount_match(common); 623565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc; 623665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 623765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 623865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 623965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 624065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 624165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 624265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichrecurse_entry *entry = common->entries; 624365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichrecurse_entry *prev = NULL; 624465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_sw start = GET(cc, 1); 624565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *start_cc; 624665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needs_control_head; 624765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 624865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); 624965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 625065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Inlining simple patterns. */ 625165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack) 625265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 625365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich start_cc = common->start + start; 625465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack); 625565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE; 625665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 1 + LINK_SIZE; 625765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 625865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 625965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (entry != NULL) 626065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 626165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (entry->start == start) 626265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 626365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich prev = entry; 626465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich entry = entry->next; 626565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 626665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 626765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (entry == NULL) 626865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 626965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich entry = sljit_alloc_memory(compiler, sizeof(recurse_entry)); 627065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 627165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 627265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich entry->next = NULL; 627365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich entry->entry = NULL; 627465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich entry->calls = NULL; 627565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich entry->start = start; 627665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 627765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (prev != NULL) 627865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich prev->next = entry; 627965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 628065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->entries = entry; 628165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 628265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 628365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->has_set_som && common->mark_ptr != 0) 628465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 628565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); 628665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 2); 628765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); 628865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 628965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 629065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 629165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (common->has_set_som || common->mark_ptr != 0) 629265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 629365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); 629465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 629565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 629665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 629765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 629865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (entry->entry == NULL) 629965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); 630065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 630165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_FAST_CALL, entry->entry); 630265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Leave if the match is failed. */ 630365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); 630465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc + 1 + LINK_SIZE; 630565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 630665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 630765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector) 630865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 630965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst pcre_uchar *begin = arguments->begin; 631065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint *offset_vector = arguments->offsets; 631165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset_count = arguments->offset_count; 631265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i; 631365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 631465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (PUBL(callout) == NULL) 631565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return 0; 631665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 631765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->version = 2; 631865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->callout_data = arguments->callout_data; 631965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 632065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Offsets in subject. */ 632165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->subject_length = arguments->end - arguments->begin; 632265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin; 632365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin; 632465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 632565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->subject = (PCRE_SPTR)begin; 632665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 632765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->subject = (PCRE_SPTR16)begin; 632865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 632965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->subject = (PCRE_SPTR32)begin; 633065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 633165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 633265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Convert and copy the JIT offset vector to the offset_vector array. */ 633365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->capture_top = 0; 633465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->offset_vector = offset_vector; 633565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = 2; i < offset_count; i += 2) 633665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 633765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset_vector[i] = jit_ovector[i] - begin; 633865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset_vector[i + 1] = jit_ovector[i + 1] - begin; 633965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (jit_ovector[i] >= begin) 634065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich callout_block->capture_top = i; 634165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 634265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 634365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcallout_block->capture_top = (callout_block->capture_top >> 1) + 1; 634465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset_count > 0) 634565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset_vector[0] = -1; 634665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset_count > 1) 634765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset_vector[1] = -1; 634865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn (*PUBL(callout))(callout_block); 634965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 635065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 635165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Aligning to 8 byte. */ 635265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CALLOUT_ARG_SIZE \ 635365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (((int)sizeof(PUBL(callout_block)) + 7) & ~7) 635465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 635565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CALLOUT_ARG_OFFSET(arg) \ 635665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg)) 635765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 635865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 635965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 636065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 636165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 636265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 636365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); 636465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 636565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichallocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); 636665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 636765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); 636865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 636965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(common->capture_last_ptr != 0); 637065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]); 637165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); 637265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 637365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* These pointer sized fields temporarly stores internal variables. */ 637465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); 637565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0); 637665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0); 637765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 637865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mark_ptr != 0) 637965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr)); 638065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2)); 638165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE)); 638265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0); 638365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 638465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Needed to save important temporary registers. */ 638565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); 638665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE); 638765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichGET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START); 638865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout)); 638965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0); 639065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); 639165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfree_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); 639265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 639365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Check return value. */ 639465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); 639565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER)); 639665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->forced_quit_label == NULL) 639765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS)); 639865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 639965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label); 640065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc + 2 + 2 * LINK_SIZE; 640165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 640265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 640365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CALLOUT_ARG_SIZE 640465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CALLOUT_ARG_OFFSET 640565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 640665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) 640765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 640865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 640965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint framesize; 641065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint extrasize; 641165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needs_control_head; 641265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_ptr; 641365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common altbacktrack; 641465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccbegin; 641565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar opcode; 641665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar bra = OP_BRA; 641765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *tmp = NULL; 641865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; 641965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list **found; 642065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Saving previous accept variables. */ 642165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL save_local_exit = common->local_exit; 642265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL save_positive_assert = common->positive_assert; 642365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichthen_trap_backtrack *save_then_trap = common->then_trap; 642465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *save_quit_label = common->quit_label; 642565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *save_accept_label = common->accept_label; 642665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *save_quit = common->quit; 642765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *save_positive_assert_quit = common->positive_assert_quit; 642865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *save_accept = common->accept; 642965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 643065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *brajump = NULL; 643165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 643265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Assert captures then. */ 643365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->then_trap = NULL; 643465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 643565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) 643665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 643765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(!conditional); 643865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bra = *cc; 643965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 644065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 644165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichprivate_data_ptr = PRIVATE_DATA(cc); 644265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(private_data_ptr != 0); 644365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichframesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); 644465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack->framesize = framesize; 644565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack->private_data_ptr = private_data_ptr; 644665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichopcode = *cc; 644765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); 644865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfound = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; 644965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichccbegin = cc; 645065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc += GET(cc, 1); 645165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 645265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAMINZERO) 645365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 645465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This is a braminzero backtrack path. */ 645565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 645665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 645765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 645865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 645965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 646065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (framesize < 0) 646165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 646265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich extrasize = needs_control_head ? 2 : 1; 646365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize == no_frame) 646465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); 646565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, extrasize); 646665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 646765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 646865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 646965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 647065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 647165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); 647265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 647365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 647465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 647565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 647665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 647765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich extrasize = needs_control_head ? 3 : 2; 647865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, framesize + extrasize); 647965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 648065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); 648165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); 648265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 648365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 648465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 648565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 648665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 648765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); 648865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); 648965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); 649065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 649165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 649265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); 649365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); 649465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 649565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 649665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmemset(&altbacktrack, 0, sizeof(backtrack_common)); 649765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) 649865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 649965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Negative assert is stronger than positive assert. */ 650065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->local_exit = TRUE; 650165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit_label = NULL; 650265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit = NULL; 650365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->positive_assert = FALSE; 650465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 650565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 650665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->positive_assert = TRUE; 650765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->positive_assert_quit = NULL; 650865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 650965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (1) 651065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 651165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->accept_label = NULL; 651265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->accept = NULL; 651365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich altbacktrack.top = NULL; 651465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich altbacktrack.topbacktracks = NULL; 651565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 651665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*ccbegin == OP_ALT) 651765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 651865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 651965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich altbacktrack.cc = ccbegin; 652065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); 652165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 652265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 652365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) 652465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 652565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->local_exit = save_local_exit; 652665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit_label = save_quit_label; 652765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit = save_quit; 652865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 652965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->positive_assert = save_positive_assert; 653065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->then_trap = save_then_trap; 653165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->accept_label = save_accept_label; 653265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->positive_assert_quit = save_positive_assert_quit; 653365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->accept = save_accept; 653465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 653565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 653665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->accept_label = LABEL(); 653765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->accept != NULL) 653865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->accept, common->accept_label); 653965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 654065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Reset stack. */ 654165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 654265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 654365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize == no_frame) 654465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 654565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 654665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, extrasize); 654765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 654865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); 654965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 655065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 655165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 655265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) 655365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 655465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ 655565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); 655665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 655765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); 655865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 655965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 656065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 656165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 656265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 656365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw)); 656465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 656565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 656665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 656765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 656865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) 656965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 657065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We know that STR_PTR was stored on the top of the stack. */ 657165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (conditional) 657265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0); 657365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (bra == OP_BRAZERO) 657465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 657565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 657665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); 657765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 657865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 657965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); 658065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw)); 658165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); 658265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 658365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); 658465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 658565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 658665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (framesize >= 0) 658765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 658865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* For OP_BRA and OP_BRAMINZERO. */ 658965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); 659065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 659165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 659265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, found, JUMP(SLJIT_JUMP)); 659365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 659465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_backtrackingpath(common, altbacktrack.top); 659565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 659665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 659765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) 659865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 659965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->local_exit = save_local_exit; 660065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit_label = save_quit_label; 660165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit = save_quit; 660265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 660365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->positive_assert = save_positive_assert; 660465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->then_trap = save_then_trap; 660565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->accept_label = save_accept_label; 660665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->positive_assert_quit = save_positive_assert_quit; 660765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->accept = save_accept; 660865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 660965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 661065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(altbacktrack.topbacktracks, LABEL()); 661165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 661265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc != OP_ALT) 661365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 661465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 661565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ccbegin = cc; 661665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 661765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 661865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 661965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) 662065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 662165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->positive_assert_quit == NULL); 662265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Makes the check less complicated below. */ 662365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->positive_assert_quit = common->quit; 662465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 662565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 662665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* None of them matched. */ 662765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->positive_assert_quit != NULL) 662865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 662965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_JUMP); 663065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->positive_assert_quit, LABEL()); 663165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(framesize != no_stack); 663265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 663365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw)); 663465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 663565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 663665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 663765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 663865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); 663965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 664065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 664165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 664265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 664365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (needs_control_head) 664465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1)); 664565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 664665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) 664765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 664865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Assert is failed. */ 664965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (conditional || bra == OP_BRAZERO) 665065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 665165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 665265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 665365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 665465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The topmost item should be 0. */ 665565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAZERO) 665665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 665765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (extrasize == 2) 665865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 665965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 666065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 666165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 666265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, extrasize); 666365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 666465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 666565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 666665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1)); 666765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The topmost item should be 0. */ 666865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAZERO) 666965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 667065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, framesize + extrasize - 1); 667165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 667265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 667365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 667465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, framesize + extrasize); 667565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); 667665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 667765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_JUMP); 667865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra != OP_BRAZERO) 667965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, target, jump); 668065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 668165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Assert is successful. */ 668265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(tmp, LABEL()); 668365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 668465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 668565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We know that STR_PTR was stored on the top of the stack. */ 668665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); 668765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Keep the STR_PTR on the top of the stack. */ 668865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAZERO) 668965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 669065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); 669165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (extrasize == 2) 669265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 669365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 669465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (bra == OP_BRAMINZERO) 669565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 669665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); 669765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 669865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 669965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 670065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 670165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 670265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRA) 670365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 670465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ 670565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); 670665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw)); 670765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 670865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 670965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 671065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ 671165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw)); 671265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (extrasize == 2) 671365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 671465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 671565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAMINZERO) 671665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 671765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 671865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 671965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 672065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); 672165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); 672265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 672365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 672465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 672565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 672665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAZERO) 672765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 672865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->matchingpath = LABEL(); 672965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_LABEL(jump, backtrack->matchingpath); 673065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 673165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (bra == OP_BRAMINZERO) 673265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 673365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, backtrack->matchingpath); 673465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(brajump); 673565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize >= 0) 673665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 673765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 673865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 673965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); 674065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 674165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(backtrack->common.topbacktracks, LABEL()); 674265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 674365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 674465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 674565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 674665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* AssertNot is successful. */ 674765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 674865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 674965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 675065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra != OP_BRA) 675165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 675265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (extrasize == 2) 675365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 675465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 675565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 675665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 675765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, extrasize); 675865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 675965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 676065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 676165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 676265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1)); 676365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The topmost item should be 0. */ 676465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra != OP_BRA) 676565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 676665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, framesize + extrasize - 1); 676765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 676865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 676965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 677065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, framesize + extrasize); 677165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); 677265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 677365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 677465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAZERO) 677565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->matchingpath = LABEL(); 677665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (bra == OP_BRAMINZERO) 677765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 677865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, backtrack->matchingpath); 677965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(brajump); 678065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 678165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 678265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra != OP_BRA) 678365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 678465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(found == &backtrack->common.topbacktracks); 678565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(backtrack->common.topbacktracks, LABEL()); 678665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->common.topbacktracks = NULL; 678765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 678865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 678965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 679065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) 679165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 679265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->local_exit = save_local_exit; 679365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit_label = save_quit_label; 679465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit = save_quit; 679565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 679665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->positive_assert = save_positive_assert; 679765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->then_trap = save_then_trap; 679865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->accept_label = save_accept_label; 679965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->positive_assert_quit = save_positive_assert_quit; 680065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->accept = save_accept; 680165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc + 1 + LINK_SIZE; 680265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 680365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 680465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void match_once_common(compiler_common *common, pcre_uchar ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head) 680565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 680665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 680765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint stacksize; 680865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 680965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (framesize < 0) 681065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 681165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize == no_frame) 681265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 681365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 681465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 681565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = needs_control_head ? 1 : 0; 681665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KET || has_alternatives) 681765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 681865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, stacksize); 681965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 682065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 682165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 682265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0); 682365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 682465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 which is set here used by OP_KETRMAX below. */ 682565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket == OP_KETRMAX) 682665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); 682765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (ket == OP_KETRMIN) 682865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 682965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Move the STR_PTR to the private_data_ptr. */ 683065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); 683165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 683265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 683365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 683465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 683565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1; 683665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw)); 683765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 683865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0); 683965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 684065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket == OP_KETRMAX) 684165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 684265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 which is set here used by OP_KETRMAX below. */ 684365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 684465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 684565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 684665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (needs_control_head) 684765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0); 684865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 684965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 685065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr) 685165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 685265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 685365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 685465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->capture_last_ptr != 0) 685565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 685665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); 685765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); 685865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); 685965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 686065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 686165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->optimized_cbracket[offset >> 1] == 0) 686265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 686365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); 686465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); 686565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); 686665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 686765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); 686865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); 686965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); 687065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize += 2; 687165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 687265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn stacksize; 687365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 687465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 687565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* 687665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Handling bracketed expressions is probably the most complex part. 687765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 687865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Stack layout naming characters: 687965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich S - Push the current STR_PTR 688065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 0 - Push a 0 (NULL) 688165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich A - Push the current STR_PTR. Needed for restoring the STR_PTR 688265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich before the next alternative. Not pushed if there are no alternatives. 688365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich M - Any values pushed by the current alternative. Can be empty, or anything. 688465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack. 688565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich L - Push the previous local (pointed by localptr) to the stack 688665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich () - opional values stored on the stack 688765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ()* - optonal, can be stored multiple times 688865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 688965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich The following list shows the regular expression templates, their PCRE byte codes 689065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich and stack layout supported by pcre-sljit. 689165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 689265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?:) OP_BRA | OP_KET A M 689365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich () OP_CBRA | OP_KET C M 689465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )* 689565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_SBRA | OP_KETRMAX 0 L M S ( L M S )* 689665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )* 689765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_SBRA | OP_KETRMIN 0 L M S ( L M S )* 689865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )* 689965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )* 690065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )* 690165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )* 690265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 ) 690365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 ) 690465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 ) 690565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 ) 690665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )* 690765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )* 690865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )* 690965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )* 691065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )* 691165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )* 691265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )* 691365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )* 691465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 691565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 691665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Stack layout naming characters: 691765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich A - Push the alternative index (starting from 0) on the stack. 691865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Not pushed if there is no alternatives. 691965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich M - Any values pushed by the current alternative. Can be empty, or anything. 692065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 692165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich The next list shows the possible content of a bracket: 692265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (|) OP_*BRA | OP_ALT ... M A 692365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?()|) OP_*COND | OP_ALT M A 692465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?>|) OP_ONCE | OP_ALT ... [stack trace] M A 692565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A 692665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich Or nothing, if trace is unnecessary 692765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*/ 692865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 692965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 693065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 693165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 693265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 693365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar opcode; 693465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_ptr = 0; 693565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset = 0; 693665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i, stacksize; 693765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint repeat_ptr = 0, repeat_length = 0; 693865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint repeat_type = 0, repeat_count = 0; 693965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccbegin; 694065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *matchingpath; 694165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *slot; 694265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar bra = OP_BRA; 694365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar ket; 694465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichassert_backtrack *assert; 694565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL has_alternatives; 694665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needs_control_head = FALSE; 694765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 694865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *skip; 694965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *rmax_label = NULL; 695065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *braminzero = NULL; 695165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 695265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); 695365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 695465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) 695565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 695665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bra = *cc; 695765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 695865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich opcode = *cc; 695965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 696065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 696165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichopcode = *cc; 696265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichccbegin = cc; 696365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmatchingpath = bracketend(cc) - 1 - LINK_SIZE; 696465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichket = *matchingpath; 696565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0) 696665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 696765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat_ptr = PRIVATE_DATA(matchingpath); 696865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat_length = PRIVATE_DATA(matchingpath + 1); 696965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat_type = PRIVATE_DATA(matchingpath + 2); 697065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat_count = PRIVATE_DATA(matchingpath + 3); 697165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0); 697265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type == OP_UPTO) 697365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ket = OP_KETRMAX; 697465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type == OP_MINUPTO) 697565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ket = OP_KETRMIN; 697665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 697765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 697865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) 697965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 698065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Drop this bracket_backtrack. */ 698165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich parent->top = backtrack->prev; 698265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return matchingpath + 1 + LINK_SIZE + repeat_length; 698365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 698465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 698565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmatchingpath = ccbegin + 1 + LINK_SIZE; 698665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); 698765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); 698865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc += GET(cc, 1); 698965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 699065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichhas_alternatives = *cc == OP_ALT; 699165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND)) 699265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE; 699365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 699465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) 699565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich opcode = OP_SCOND; 699665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) 699765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich opcode = OP_ONCE; 699865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 699965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_CBRA || opcode == OP_SCBRA) 700065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 700165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Capturing brackets has a pre-allocated space. */ 700265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset = GET2(ccbegin, 1 + LINK_SIZE); 700365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->optimized_cbracket[offset] == 0) 700465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 700565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_ptr = OVECTOR_PRIV(offset); 700665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset <<= 1; 700765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 700865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 700965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 701065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset <<= 1; 701165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_ptr = OVECTOR(offset); 701265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 701365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; 701465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich matchingpath += IMM2_SIZE; 701565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 701665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) 701765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 701865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Other brackets simply allocate the next entry. */ 701965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich private_data_ptr = PRIVATE_DATA(ccbegin); 702065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(private_data_ptr != 0); 702165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; 702265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_ONCE) 702365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head); 702465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 702565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 702665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Instructions before the first alternative. */ 702765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstacksize = 0; 702865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) 702965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 703065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAZERO) 703165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 703265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 703365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (stacksize > 0) 703465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, stacksize); 703565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 703665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstacksize = 0; 703765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) 703865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 703965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); 704065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 704165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 704265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 704365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAZERO) 704465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 704565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 704665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAMINZERO) 704765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 704865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */ 704965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 705065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KETRMIN) 705165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 705265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 705365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 705465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 705565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 705665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 705765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_ONCE || opcode >= OP_SBRA) 705865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 705965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 706065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 706165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Nothing stored during the first run. */ 706265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich skip = JUMP(SLJIT_JUMP); 706365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 706465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Checking zero-length iteration. */ 706565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) 706665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 706765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ 706865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 706965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 707065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 707165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 707265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Except when the whole stack frame must be saved. */ 707365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 707465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); 707565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 707665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(skip); 707765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 707865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 707965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 708065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 708165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 708265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 708365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 708465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 708565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 708665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 708765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (repeat_type != 0) 708865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 708965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count); 709065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type == OP_EXACT) 709165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich rmax_label = LABEL(); 709265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 709365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 709465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket == OP_KETRMIN) 709565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); 709665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 709765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket == OP_KETRMAX) 709865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 709965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich rmax_label = LABEL(); 710065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0) 710165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label; 710265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 710365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 710465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Handling capturing brackets and alternatives. */ 710565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_ONCE) 710665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 710765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 0; 710865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 710965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 711065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 711165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 711265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 711365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 711465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) 711565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 711665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Neither capturing brackets nor recursions are found in the block. */ 711765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket == OP_KETRMIN) 711865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 711965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize += 2; 712065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!needs_control_head) 712165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 712265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 712365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 712465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 712565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) 712665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); 712765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket == OP_KETRMAX || has_alternatives) 712865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 712965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 713065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 713165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (stacksize > 0) 713265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, stacksize); 713365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 713465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 0; 713565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 713665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 713765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 713865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 713965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 714065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 714165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket == OP_KETRMIN) 714265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 714365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 714465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 714565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 714665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) 714765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw)); 714865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); 714965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 715065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (ket == OP_KETRMAX || has_alternatives) 715165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 715265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 715365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 715465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 715565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KET || has_alternatives) 715665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 715765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 715865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1; 715965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, stacksize); 716065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 716165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 716265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 716365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 716465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 716565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); 716665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 716765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = needs_control_head ? 1 : 0; 716865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KET || has_alternatives) 716965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 717065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 717165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); 717265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 717365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); 717465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 717565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 717665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 717765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); 717865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); 717965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 718065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE); 718165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 718265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 718365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (opcode == OP_CBRA || opcode == OP_SCBRA) 718465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 718565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Saving the previous values. */ 718665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->optimized_cbracket[offset >> 1] != 0) 718765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 718865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(private_data_ptr == OVECTOR(offset)); 718965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 2); 719065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 719165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); 719265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); 719365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); 719465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); 719565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 719665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 719765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 719865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 719965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 720065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); 720165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 720265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 720365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 720465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (opcode == OP_SBRA || opcode == OP_SCOND) 720565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 720665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Saving the previous value. */ 720765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 720865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 720965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); 721065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 721165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 721265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (has_alternatives) 721365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 721465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Pushing the starting string pointer. */ 721565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 721665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 721765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 721865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 721965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Generating code for the first alternative. */ 722065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_COND || opcode == OP_SCOND) 722165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 722265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*matchingpath == OP_CREF) 722365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 722465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(has_alternatives); 722565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), 722665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); 722765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich matchingpath += 1 + IMM2_SIZE; 722865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 722965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (*matchingpath == OP_DNCREF) 723065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 723165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(has_alternatives); 723265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 723365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich i = GET2(matchingpath, 1 + IMM2_SIZE); 723465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; 723565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); 723665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); 723765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); 723865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich slot += common->name_entry_size; 723965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich i--; 724065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (i-- > 0) 724165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 724265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); 724365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0); 724465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich slot += common->name_entry_size; 724565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 724665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); 724765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO)); 724865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich matchingpath += 1 + 2 * IMM2_SIZE; 724965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 725065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) 725165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 725265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Never has other case. */ 725365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; 725465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(!has_alternatives); 725565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 725665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*matchingpath == OP_RREF) 725765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 725865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = GET2(matchingpath, 1); 725965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->currententry == NULL) 726065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 0; 726165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (stacksize == RREF_ANY) 726265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 1; 726365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (common->currententry->start == 0) 726465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = stacksize == 0; 726565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 726665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); 726765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 726865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (stacksize != 0) 726965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich matchingpath += 1 + IMM2_SIZE; 727065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 727165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 727265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 727365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->currententry == NULL || common->currententry->start == 0) 727465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 0; 727565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 727665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 727765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = GET2(matchingpath, 1 + IMM2_SIZE); 727865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; 727965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); 728065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (stacksize > 0) 728165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 728265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((int)GET2(slot, 0) == i) 728365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 728465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich slot += common->name_entry_size; 728565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize--; 728665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 728765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 728865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 728965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (stacksize != 0) 729065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich matchingpath += 1 + 2 * IMM2_SIZE; 729165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 729265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 729365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The stacksize == 0 is a common "else" case. */ 729465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (stacksize == 0) 729565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 729665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_ALT) 729765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 729865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich matchingpath = cc + 1 + LINK_SIZE; 729965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 730065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 730165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 730265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich matchingpath = cc; 730365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 730465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 730565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 730665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 730765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT); 730865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Similar code as PUSH_BACKTRACK macro. */ 730965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack)); 731065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 731165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 731265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich memset(assert, 0, sizeof(assert_backtrack)); 731365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich assert->common.cc = matchingpath; 731465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->u.assert = assert; 731565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE); 731665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 731765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 731865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 731965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompile_matchingpath(common, matchingpath, cc, backtrack); 732065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 732165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 732265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 732365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_ONCE) 732465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); 732565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 732665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstacksize = 0; 732765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (repeat_type == OP_MINUPTO) 732865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 732965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We need to preserve the counter. TMP2 will be used below. */ 733065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); 733165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 733265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 733365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket != OP_KET || bra != OP_BRA) 733465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 733565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset != 0) 733665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 733765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 733865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 733965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->optimized_cbracket[offset >> 1] == 0) 734065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize += 2; 734165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 734265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (has_alternatives && opcode != OP_ONCE) 734365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 734465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 734565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (stacksize > 0) 734665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, stacksize); 734765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 734865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstacksize = 0; 734965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (repeat_type == OP_MINUPTO) 735065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 735165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 was set above. */ 735265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); 735365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 735465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 735565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 735665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket != OP_KET || bra != OP_BRA) 735765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 735865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KET) 735965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 736065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 736165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); 736265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 736365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 736465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 736565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset != 0) 736665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); 736765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 736865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (has_alternatives) 736965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 737065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 737165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); 737265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KETRMAX) 737365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); 737465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 737565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 737665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Must be after the matchingpath label. */ 737765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset != 0 && common->optimized_cbracket[offset >> 1] != 0) 737865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 737965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); 738065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); 738165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 738265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 738365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket == OP_KETRMAX) 738465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 738565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type != 0) 738665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 738765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (has_alternatives) 738865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); 738965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); 739065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, rmax_label); 739165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Drop STR_PTR for greedy plus quantifier. */ 739265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 739365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 739465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 739565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (opcode == OP_ONCE || opcode >= OP_SBRA) 739665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 739765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (has_alternatives) 739865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); 739965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Checking zero-length iteration. */ 740065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 740165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 740265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label); 740365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Drop STR_PTR for greedy plus quantifier. */ 740465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra != OP_BRAZERO) 740565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 740665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 740765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 740865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 must contain the starting STR_PTR. */ 740965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label); 741065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 741165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 741265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, rmax_label); 741365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); 741465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 741565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 741665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (repeat_type == OP_EXACT) 741765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 741865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count_match(common); 741965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); 742065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, rmax_label); 742165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 742265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (repeat_type == OP_UPTO) 742365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 742465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We need to preserve the counter. */ 742565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); 742665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 742765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 742865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 742965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 743065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAZERO) 743165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL(); 743265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 743365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAMINZERO) 743465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 743565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ 743665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath); 743765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (braminzero != NULL) 743865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 743965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(braminzero); 744065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We need to release the end pointer to perform the 744165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack for the zero-length iteration. When 744265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich framesize is < 0, OP_ONCE will do the release itself. */ 744365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) 744465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 744565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 744665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 744765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 744865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (ket == OP_KETRMIN && opcode != OP_ONCE) 744965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 745065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 745165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Continue to the normal backtrack. */ 745265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 745365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 745465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) 745565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count_match(common); 745665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 745765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Skip the other alternatives. */ 745865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (*cc == OP_ALT) 745965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 746065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc += 1 + LINK_SIZE; 746165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 746265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Temporarily encoding the needs_control_head in framesize. */ 746365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_ONCE) 746465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0); 746565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc + repeat_length; 746665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 746765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 746865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 746965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 747065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 747165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 747265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar opcode; 747365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_ptr; 747465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint cbraprivptr = 0; 747565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needs_control_head; 747665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint framesize; 747765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint stacksize; 747865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset = 0; 747965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL zero = FALSE; 748065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccbegin = NULL; 748165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint stack; /* Also contains the offset of control head. */ 748265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *loop = NULL; 748365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct jump_list *emptymatch = NULL; 748465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 748565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL); 748665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_BRAPOSZERO) 748765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 748865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich zero = TRUE; 748965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 749065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 749165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 749265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichopcode = *cc; 749365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichprivate_data_ptr = PRIVATE_DATA(cc); 749465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(private_data_ptr != 0); 749565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr; 749665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(opcode) 749765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 749865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOS: 749965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRAPOS: 750065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ccbegin = cc + 1 + LINK_SIZE; 750165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 750265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 750365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 750465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 750565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset = GET2(cc, 1 + LINK_SIZE); 750665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This case cannot be optimized in the same was as 750765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich normal capturing brackets. */ 750865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->optimized_cbracket[offset] == 0); 750965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cbraprivptr = OVECTOR_PRIV(offset); 751065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset <<= 1; 751165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE; 751265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 751365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 751465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 751565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 751665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 751765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 751865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 751965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichframesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); 752065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; 752165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (framesize < 0) 752265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 752365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0) 752465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 752565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 2; 752665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 752765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 752865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 752965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 753065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 1; 753165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 753265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 753365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 753465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!zero) 753565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 753665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 753765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; 753865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, stacksize); 753965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize == no_frame) 754065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); 754165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 754265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack = 0; 754365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0) 754465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 754565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack = 2; 754665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); 754765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); 754865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); 754965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 755065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); 755165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); 755265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 755365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 755465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 755565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 755665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); 755765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack = 3; 755865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 755965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 756065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 756165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 756265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 756365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 756465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 756565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack = 1; 756665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 756765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 756865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 756965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack++; 757065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!zero) 757165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1); 757265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 757365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 757465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack--; 757565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); 757665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 757765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 757865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 757965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 758065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = framesize + 1; 758165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!zero) 758265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 758365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 758465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 758565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset == 0) 758665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 758765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; 758865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 758965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, stacksize); 759065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 759165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 759265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 759365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); 759465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 759565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack = 0; 759665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!zero) 759765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 759865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); 759965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack = 1; 760065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 760165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 760265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 760365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); 760465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack++; 760565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 760665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset == 0) 760765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 760865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); 760965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack++; 761065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 761165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); 761265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE); 761365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stack -= 1 + (offset == 0); 761465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 761565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 761665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset != 0) 761765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); 761865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 761965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichloop = LABEL(); 762065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (*cc != OP_KETRPOS) 762165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 762265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->top = NULL; 762365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack->topbacktracks = NULL; 762465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 762565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 762665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_matchingpath(common, ccbegin, cc, backtrack); 762765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 762865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 762965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 763065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 763165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 763265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize == no_frame) 763365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 763465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 763565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0) 763665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 763765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); 763865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); 763965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); 764065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 764165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); 764265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); 764365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 764465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 764565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 764665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_SBRAPOS) 764765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 764865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 764965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 765065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 765165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) 765265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); 765365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 765465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!zero) 765565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); 765665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 765765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 765865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 765965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0) 766065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 766165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw)); 766265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); 766365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); 766465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0); 766565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 766665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1); 766765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); 766865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 766965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 767065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 767165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 767265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); 767365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_SBRAPOS) 767465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); 767565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0); 767665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 767765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 767865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) 767965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); 768065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 768165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!zero) 768265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 768365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 768465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); 768565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 768665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 768765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 768865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 768965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 769065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_control_head) 769165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); 769265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 769365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, loop); 769465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich flush_stubs(common); 769565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 769665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_backtrackingpath(common, backtrack->top); 769765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 769865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 769965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(backtrack->topbacktracks, LABEL()); 770065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 770165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 770265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 770365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0) 770465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); 770565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 770665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 770765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 770865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 770965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 771065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0) 771165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 771265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Last alternative. */ 771365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_KETRPOS) 771465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 771565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr); 771665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 771765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 771865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 771965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 772065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); 772165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 772265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 772365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 772465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_KETRPOS) 772565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 772665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ccbegin = cc + 1 + LINK_SIZE; 772765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 772865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 772965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* We don't have to restore the control head in case of a failed match. */ 773065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 773165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack->topbacktracks = NULL; 773265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!zero) 773365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 773465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (framesize < 0) 773565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); 773665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else /* TMP2 is set to [private_data_ptr] above. */ 773765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0)); 773865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 773965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 774065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* None of them matched. */ 774165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(emptymatch, LABEL()); 774265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcount_match(common); 774365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc + 1 + LINK_SIZE; 774465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 774565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 774665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *max, int *min, pcre_uchar **end) 774765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 774865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint class_len; 774965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 775065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich*opcode = *cc; 775165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*opcode >= OP_STAR && *opcode <= OP_POSUPTO) 775265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 775365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 775465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *type = OP_CHAR; 775565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 775665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI) 775765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 775865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 775965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *type = OP_CHARI; 776065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode -= OP_STARI - OP_STAR; 776165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 776265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO) 776365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 776465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 776565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *type = OP_NOT; 776665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode -= OP_NOTSTAR - OP_STAR; 776765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 776865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI) 776965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 777065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 777165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *type = OP_NOTI; 777265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode -= OP_NOTSTARI - OP_STAR; 777365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 777465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) 777565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 777665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 777765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode -= OP_TYPESTAR - OP_STAR; 777865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *type = 0; 777965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 778065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 778165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 778265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS); 778365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *type = *opcode; 778465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 778565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0); 778665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode = cc[class_len - 1]; 778765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) 778865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 778965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode -= OP_CRSTAR - OP_STAR; 779065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (end != NULL) 779165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *end = cc + class_len; 779265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 779365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) 779465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 779565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode -= OP_CRPOSSTAR - OP_POSSTAR; 779665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (end != NULL) 779765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *end = cc + class_len; 779865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 779965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 780065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 780165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); 780265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *max = GET2(cc, (class_len + IMM2_SIZE)); 780365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *min = GET2(cc, class_len); 780465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 780565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*min == 0) 780665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 780765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(*max != 0); 780865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO); 780965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 781065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*max == *min) 781165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *opcode = OP_EXACT; 781265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 781365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (end != NULL) 781465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *end = cc + class_len + 2 * IMM2_SIZE; 781565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 781665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 781765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 781865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 781965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO) 782065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 782165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *max = GET2(cc, 0); 782265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += IMM2_SIZE; 782365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 782465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 782565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*type == 0) 782665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 782765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *type = *cc; 782865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (end != NULL) 782965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *end = next_opcode(common, cc); 783065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 783165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc; 783265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 783365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 783465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (end != NULL) 783565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 783665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *end = cc + 1; 783765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 783865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); 783965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 784065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 784165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc; 784265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 784365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 784465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 784565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 784665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 784765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 784865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar opcode; 784965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar type; 785065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint max = -1, min = -1; 785165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar* end; 785265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *nomatch = NULL; 785365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump = NULL; 785465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *label; 785565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_ptr = PRIVATE_DATA(cc); 785665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP); 785765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; 785865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); 785965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint tmp_base, tmp_offset; 786065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 786165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); 786265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 786365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end); 786465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 786565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(type) 786665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 786765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_DIGIT: 786865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DIGIT: 786965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WHITESPACE: 787065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WHITESPACE: 787165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORDCHAR: 787265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORDCHAR: 787365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANY: 787465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ALLANY: 787565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYBYTE: 787665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYNL: 787765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_HSPACE: 787865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_HSPACE: 787965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_VSPACE: 788065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_VSPACE: 788165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHAR: 788265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHARI: 788365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT: 788465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTI: 788565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 788665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 788765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp_base = TMP3; 788865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp_offset = 0; 788965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 789065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 789165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 789265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 789365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Fall through. */ 789465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 789565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXTUNI: 789665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 789765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPROP: 789865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PROP: 789965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp_base = SLJIT_MEM1(SLJIT_SP); 790065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tmp_offset = POSSESSIVE0; 790165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 790265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 790365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 790465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(opcode) 790565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 790665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STAR: 790765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUS: 790865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTO: 790965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRRANGE: 791065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (type == OP_ANYNL || type == OP_EXTUNI) 791165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 791265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(private_data_ptr == 0); 791365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_STAR || opcode == OP_UPTO) 791465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 791565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 2); 791665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 791765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); 791865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 791965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 792065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 792165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 792265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 792365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 792465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 792565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_UPTO || opcode == OP_CRRANGE) 792665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); 792765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 792865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 792965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); 793065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_UPTO || opcode == OP_CRRANGE) 793165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 793265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); 793365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 793465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_CRRANGE && min > 0) 793565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); 793665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0)) 793765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); 793865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); 793965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 794065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 794165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We cannot use TMP3 because of this allocate_stack. */ 794265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 794365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 794465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, label); 794565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (jump != NULL) 794665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 794765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 794865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 794965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 795065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_PLUS) 795165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); 795265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 795365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 2); 795465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); 795565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode <= OP_PLUS) 795665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); 795765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 795865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); 795965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 796065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &nomatch); 796165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); 796265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode <= OP_PLUS) 796365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, label); 796465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (opcode == OP_CRRANGE && max == 0) 796565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 796665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1); 796765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, label); 796865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 796965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 797065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 797165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, base, offset1); 797265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 797365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset1, TMP1, 0); 797465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 1, label); 797565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 797665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(nomatch, LABEL()); 797765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_CRRANGE) 797865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, min + 1)); 797965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); 798065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 798165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); 798265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 798365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 798465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTAR: 798565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUS: 798665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_MINPLUS) 798765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); 798865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 798965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 799065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); 799165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); 799265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 799365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 799465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTO: 799565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINRANGE: 799665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 799765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 2); 799865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); 799965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); 800065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_CRMINRANGE) 800165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); 800265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); 800365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 800465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 800565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERY: 800665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERY: 800765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 800865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 800965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); 801065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_QUERY) 801165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); 801265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); 801365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 801465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 801565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACT: 801665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); 801765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 801865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); 801965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); 802065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, label); 802165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 802265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 802365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTAR: 802465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUS: 802565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTO: 802665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_POSPLUS) 802765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); 802865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_POSUPTO) 802965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max); 803065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); 803165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 803265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &nomatch); 803365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); 803465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_POSUPTO) 803565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, label); 803665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 803765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 803865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1); 803965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, label); 804065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 804165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(nomatch, LABEL()); 804265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); 804365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 804465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 804565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERY: 804665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); 804765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &nomatch); 804865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); 804965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(nomatch, LABEL()); 805065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); 805165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 805265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 805365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPOSRANGE: 805465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */ 805565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min); 805665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 805765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); 805865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); 805965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, label); 806065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 806165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max != 0) 806265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 806365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(max - min > 0); 806465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max - min); 806565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 806665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); 806765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 806865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &nomatch); 806965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); 807065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (max == 0) 807165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, label); 807265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 807365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 807465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1); 807565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_C_NOT_ZERO, label); 807665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 807765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(nomatch, LABEL()); 807865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); 807965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 808065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 808165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 808265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 808365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 808465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 808565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 808665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcount_match(common); 808765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn end; 808865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 808965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 809065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 809165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 809265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 809365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 809465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 809565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); 809665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 809765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_FAIL) 809865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 809965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); 810065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 1; 810165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 810265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 810365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty) 810465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 810565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* No need to check notempty conditions. */ 810665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->accept_label == NULL) 810765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); 810865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 810965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, common->accept_label); 811065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 1; 811165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 811265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 811365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->accept_label == NULL) 811465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0))); 811565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 811665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label); 811765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 811865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); 811965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 812065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); 812165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->accept_label == NULL) 812265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0)); 812365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 812465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label); 812565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 812665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->accept_label == NULL) 812765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); 812865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 812965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label); 813065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); 813165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc + 1; 813265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 813365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 813465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc) 813565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 813665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 813765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset = GET2(cc, 1); 813865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL optimized_cbracket = common->optimized_cbracket[offset] != 0; 813965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 814065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Data will be discarded anyway... */ 814165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->currententry != NULL) 814265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return cc + 1 + IMM2_SIZE; 814365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 814465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!optimized_cbracket) 814565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset)); 814665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichoffset <<= 1; 814765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); 814865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!optimized_cbracket) 814965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); 815065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn cc + 1 + IMM2_SIZE; 815165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 815265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 815365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) 815465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 815565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 815665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 815765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar opcode = *cc; 815865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccend = cc + 1; 815965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 816065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG) 816165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ccend += 2 + cc[1]; 816265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 816365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); 816465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 816565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_SKIP) 816665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 816765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 816865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 816965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return ccend; 817065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 817165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 817265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) 817365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 817465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 817565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); 817665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0); 817765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); 817865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 817965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 818065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn ccend; 818165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 818265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 818365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP }; 818465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 818565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) 818665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 818765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 818865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 818965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needs_control_head; 819065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint size; 819165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 819265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); 819365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->then_trap = BACKTRACK_AS(then_trap_backtrack); 819465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; 819565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start); 819665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head); 819765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 819865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsize = BACKTRACK_AS(then_trap_backtrack)->framesize; 819965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsize = 3 + (size < 0 ? 0 : size); 820065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 820165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 820265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichallocate_stack(common, size); 820365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (size > 3) 820465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw)); 820565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 820665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0); 820765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start); 820865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap); 820965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0); 821065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 821165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsize = BACKTRACK_AS(then_trap_backtrack)->framesize; 821265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (size >= 0) 821365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich init_frame(common, cc, ccend, size - 1, 0, FALSE); 821465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 821565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 821665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) 821765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 821865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 821965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common *backtrack; 822065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL has_then_trap = FALSE; 822165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichthen_trap_backtrack *save_then_trap = NULL; 822265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 822365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS)); 822465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 822565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->has_then && common->then_offsets[cc - common->start] != 0) 822665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 822765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0); 822865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich has_then_trap = TRUE; 822965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich save_then_trap = common->then_trap; 823065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Tail item on backtrack. */ 823165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_then_trap_matchingpath(common, cc, ccend, parent); 823265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 823365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 823465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (cc < ccend) 823565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 823665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*cc) 823765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 823865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SOD: 823965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SOM: 824065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORD_BOUNDARY: 824165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORD_BOUNDARY: 824265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_DIGIT: 824365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DIGIT: 824465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WHITESPACE: 824565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WHITESPACE: 824665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_WORDCHAR: 824765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_WORDCHAR: 824865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANY: 824965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ALLANY: 825065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYBYTE: 825165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPROP: 825265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PROP: 825365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ANYNL: 825465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_HSPACE: 825565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_HSPACE: 825665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT_VSPACE: 825765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_VSPACE: 825865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXTUNI: 825965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EODN: 826065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EOD: 826165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRC: 826265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CIRCM: 826365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLL: 826465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DOLLM: 826565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOT: 826665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTI: 826765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REVERSE: 826865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 826965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 827065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 827165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SET_SOM: 827265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); 827365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); 827465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 827565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0); 827665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); 827765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 827865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 827965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 828065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHAR: 828165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CHARI: 828265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->mode == JIT_COMPILE) 828365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 828465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 828565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 828665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 828765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 828865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STAR: 828965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTAR: 829065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUS: 829165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUS: 829265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERY: 829365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERY: 829465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTO: 829565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTO: 829665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACT: 829765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTAR: 829865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUS: 829965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERY: 830065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTO: 830165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STARI: 830265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTARI: 830365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUSI: 830465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUSI: 830565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERYI: 830665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERYI: 830765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTOI: 830865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTOI: 830965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACTI: 831065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTARI: 831165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUSI: 831265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERYI: 831365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTOI: 831465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTSTAR: 831565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINSTAR: 831665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPLUS: 831765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINPLUS: 831865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTQUERY: 831965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINQUERY: 832065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTUPTO: 832165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINUPTO: 832265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACT: 832365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSSTAR: 832465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSPLUS: 832565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSQUERY: 832665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSUPTO: 832765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTSTARI: 832865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINSTARI: 832965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPLUSI: 833065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINPLUSI: 833165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTQUERYI: 833265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINQUERYI: 833365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTUPTOI: 833465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINUPTOI: 833565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACTI: 833665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSSTARI: 833765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSPLUSI: 833865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSQUERYI: 833965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSUPTOI: 834065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPESTAR: 834165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINSTAR: 834265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPLUS: 834365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINPLUS: 834465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEQUERY: 834565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINQUERY: 834665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEUPTO: 834765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINUPTO: 834865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEEXACT: 834965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSSTAR: 835065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSPLUS: 835165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSQUERY: 835265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSUPTO: 835365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_iterator_matchingpath(common, cc, parent); 835465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 835565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 835665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 835765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 835865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE) 835965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_iterator_matchingpath(common, cc, parent); 836065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 836165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 836265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 836365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 836465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 836565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 836665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) 836765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_iterator_matchingpath(common, cc, parent); 836865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 836965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 837065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 837165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 837265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 837365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REF: 837465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REFI: 837565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE) 837665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_ref_iterator_matchingpath(common, cc, parent); 837765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 837865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 837965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); 838065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + IMM2_SIZE; 838165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 838265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 838365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 838465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNREF: 838565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNREFI: 838665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE) 838765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_ref_iterator_matchingpath(common, cc, parent); 838865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 838965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 839065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); 839165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); 839265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 2 * IMM2_SIZE; 839365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 839465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 839565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 839665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_RECURSE: 839765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_recurse_matchingpath(common, cc, parent); 839865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 839965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 840065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CALLOUT: 840165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_callout_matchingpath(common, cc, parent); 840265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 840365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 840465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT: 840565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_NOT: 840665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK: 840765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK_NOT: 840865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); 840965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); 841065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 841165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 841265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAMINZERO: 841365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc); 841465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = bracketend(cc + 1); 841565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) 841665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 841765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 1); 841865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 841965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 842065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 842165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 842265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, 2); 842365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 842465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); 842565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 842665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); 842765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc[1] > OP_ASSERTBACK_NOT) 842865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich count_match(common); 842965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 843065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 843165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE: 843265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE_NC: 843365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRA: 843465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 843565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COND: 843665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRA: 843765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 843865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCOND: 843965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_bracket_matchingpath(common, cc, parent); 844065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 844165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 844265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAZERO: 844365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc[1] > OP_ASSERTBACK_NOT) 844465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_bracket_matchingpath(common, cc, parent); 844565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 844665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 844765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); 844865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); 844965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 845065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 845165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 845265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOS: 845365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 845465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRAPOS: 845565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 845665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOSZERO: 845765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_bracketpos_matchingpath(common, cc, parent); 845865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 845965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 846065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MARK: 846165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); 846265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->mark_ptr != 0); 846365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); 846465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, common->has_skip_arg ? 5 : 1); 846565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 846665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0); 846765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); 846865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0); 846965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); 847065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->has_skip_arg) 847165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 847265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 847365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0); 847465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark); 847565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2)); 847665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); 847765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); 847865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 847965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += 1 + 2 + cc[1]; 848065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 848165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 848265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE: 848365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE_ARG: 848465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIP: 848565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIP_ARG: 848665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN: 848765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN_ARG: 848865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COMMIT: 848965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_control_verb_matchingpath(common, cc, parent); 849065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 849165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 849265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_FAIL: 849365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ACCEPT: 849465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_ACCEPT: 849565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_fail_accept_matchingpath(common, cc, parent); 849665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 849765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 849865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLOSE: 849965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = compile_close_matchingpath(common, cc); 850065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 850165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 850265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIPZERO: 850365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = bracketend(cc + 1); 850465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 850565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 850665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 850765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 850865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 850965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 851065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cc == NULL) 851165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 851265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 851365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 851465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (has_then_trap) 851565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 851665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Head item on backtrack. */ 851765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); 851865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; 851965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap; 852065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->then_trap = save_then_trap; 852165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 852265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(cc == ccend); 852365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 852465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 852565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef PUSH_BACKTRACK 852665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef PUSH_BACKTRACK_NOVALUE 852765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef BACKTRACK_AS 852865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 852965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define COMPILE_BACKTRACKINGPATH(current) \ 853065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do \ 853165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { \ 853265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_backtrackingpath(common, (current)); \ 853365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ 853465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; \ 853565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } \ 853665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (0) 853765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 853865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CURRENT_AS(type) ((type *)current) 853965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 854065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) 854165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 854265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 854365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *cc = current->cc; 854465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar opcode; 854565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar type; 854665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint max = -1, min = -1; 854765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *label = NULL; 854865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump = NULL; 854965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump_list *jumplist = NULL; 855065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_ptr = PRIVATE_DATA(cc); 855165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP); 855265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; 855365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); 855465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 855565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, NULL); 855665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 855765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(opcode) 855865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 855965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STAR: 856065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUS: 856165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTO: 856265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRRANGE: 856365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (type == OP_ANYNL || type == OP_EXTUNI) 856465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 856565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(private_data_ptr == 0); 856665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 856765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 856865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 856965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); 857065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 857165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 857265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 857365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_UPTO) 857465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich min = 0; 857565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode <= OP_PLUS) 857665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 857765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); 857865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1); 857965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 858065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 858165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 858265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, base, offset1); 858365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); 858465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1); 858565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1); 858665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 858765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich skip_char_back(common); 858865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); 858965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); 859065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_CRRANGE) 859165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 859265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 859365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 859465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 2); 859565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_PLUS) 859665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 859765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 859865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 859965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 860065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTAR: 860165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUS: 860265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); 860365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &jumplist); 860465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); 860565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); 860665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(jumplist, LABEL()); 860765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 860865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 860965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_MINPLUS) 861065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 861165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 861265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 861365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTO: 861465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRMINRANGE: 861565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_CRMINRANGE) 861665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 861765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label = LABEL(); 861865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, label); 861965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 862065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); 862165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &jumplist); 862265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 862365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, base, offset1); 862465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); 862565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); 862665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset1, TMP1, 0); 862765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 862865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_CRMINRANGE) 862965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min + 1, label); 863065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 863165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_CRMINRANGE && max == 0) 863265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); 863365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 863465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 2, CURRENT_AS(iterator_backtrack)->matchingpath); 863565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 863665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(jumplist, LABEL()); 863765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 863865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 2); 863965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 864065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 864165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERY: 864265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); 864365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); 864465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); 864565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_JUMP); 864665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 864765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); 864865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); 864965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); 865065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 865165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 865265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 865365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 865465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 865565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERY: 865665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); 865765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); 865865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 865965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_char1_matchingpath(common, type, cc, &jumplist); 866065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); 866165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(jumplist, LABEL()); 866265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 866365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 866465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 866565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 866665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 866765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACT: 866865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUS: 866965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CRPOSRANGE: 867065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 867165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 867265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 867365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTAR: 867465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERY: 867565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTO: 867665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 867765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 867865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 867965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 868065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 868165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 868265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 868365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 868465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) 868565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 868665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 868765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *cc = current->cc; 868865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL ref = (*cc == OP_REF || *cc == OP_REFI); 868965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar type; 869065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 869165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtype = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE]; 869265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 869365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((type & 0x1) == 0) 869465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 869565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Maximize case. */ 869665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 869765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 869865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 869965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); 870065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 870165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 870265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 870365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 870465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichCMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); 870565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(current->topbacktracks, LABEL()); 870665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfree_stack(common, ref ? 2 : 3); 870765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 870865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 870965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current) 871065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 871165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 871265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 871365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (CURRENT_AS(recurse_backtrack)->inlined_pattern) 871465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_backtrackingpath(common, current->top); 871565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(current->topbacktracks, LABEL()); 871665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (CURRENT_AS(recurse_backtrack)->inlined_pattern) 871765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 871865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 871965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->has_set_som && common->mark_ptr != 0) 872065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 872165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 872265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 872365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 2); 872465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP2, 0); 872565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0); 872665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 872765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (common->has_set_som || common->mark_ptr != 0) 872865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 872965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 873065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 873165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); 873265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 873365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 873465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 873565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current) 873665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 873765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 873865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *cc = current->cc; 873965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar bra = OP_BRA; 874065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *brajump = NULL; 874165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 874265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(*cc != OP_BRAMINZERO); 874365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_BRAZERO) 874465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 874565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bra = *cc; 874665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 874765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 874865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 874965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAZERO) 875065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 875165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(current->topbacktracks == NULL); 875265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 875365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 875465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 875565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (CURRENT_AS(assert_backtrack)->framesize < 0) 875665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 875765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 875865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 875965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAZERO) 876065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 876165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 876265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); 876365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 876465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 876565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 876665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 876765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 876865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAZERO) 876965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 877065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) 877165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 877265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 877365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); 877465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 877565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 877665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 877765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 877865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); 877965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 878065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 878165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) 878265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 878365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr); 878465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 878565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw)); 878665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 878765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 878865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 878965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 879065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 879165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 879265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (bra == OP_BRAZERO) 879365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 879465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We know there is enough place on the stack. */ 879565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); 879665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); 879765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath); 879865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(brajump); 879965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 880065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 880165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 880265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current) 880365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 880465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 880565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint opcode, stacksize, alt_count, alt_max; 880665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset = 0; 880765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr; 880865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint repeat_ptr = 0, repeat_type = 0, repeat_count = 0; 880965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *cc = current->cc; 881065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccbegin; 881165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccprev; 881265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar bra = OP_BRA; 881365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar ket; 881465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichassert_backtrack *assert; 881565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_uw *next_update_addr = NULL; 881665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL has_alternatives; 881765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needs_control_head = FALSE; 881865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *brazero = NULL; 881965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *alt1 = NULL; 882065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *alt2 = NULL; 882165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *once = NULL; 882265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *cond = NULL; 882365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *rmin_label = NULL; 882465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *exact_label = NULL; 882565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 882665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) 882765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 882865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich bra = *cc; 882965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc++; 883065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 883165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 883265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichopcode = *cc; 883365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichccbegin = bracketend(cc) - 1 - LINK_SIZE; 883465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichket = *ccbegin; 883565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0) 883665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 883765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat_ptr = PRIVATE_DATA(ccbegin); 883865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat_type = PRIVATE_DATA(ccbegin + 2); 883965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich repeat_count = PRIVATE_DATA(ccbegin + 3); 884065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0); 884165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type == OP_UPTO) 884265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ket = OP_KETRMAX; 884365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type == OP_MINUPTO) 884465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ket = OP_KETRMIN; 884565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 884665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichccbegin = cc; 884765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc += GET(cc, 1); 884865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichhas_alternatives = *cc == OP_ALT; 884965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) 885065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; 885165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_CBRA || opcode == OP_SCBRA) 885265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; 885365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) 885465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich opcode = OP_SCOND; 885565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) 885665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich opcode = OP_ONCE; 885765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 885865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichalt_max = has_alternatives ? no_alternatives(ccbegin) : 0; 885965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 886065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Decoding the needs_control_head in framesize. */ 886165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_ONCE) 886265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 886365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0; 886465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CURRENT_AS(bracket_backtrack)->u.framesize >>= 1; 886565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 886665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 886765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket != OP_KET && repeat_type != 0) 886865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 886965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP1 is used in OP_KETRMIN below. */ 887065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 887165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 887265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type == OP_UPTO) 887365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1); 887465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 887565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0); 887665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 887765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 887865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (ket == OP_KETRMAX) 887965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 888065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAZERO) 888165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 888265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 888365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 888465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0); 888565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 888665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 888765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (ket == OP_KETRMIN) 888865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 888965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra != OP_BRAMINZERO) 889065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 889165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 889265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type != 0) 889365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 889465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP1 was set a few lines above. */ 889565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); 889665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Drop STR_PTR for non-greedy plus quantifier. */ 889765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 889865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 889965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 890065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (opcode >= OP_SBRA || opcode == OP_ONCE) 890165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 890265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Checking zero-length iteration. */ 890365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) 890465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); 890565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 890665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 890765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 890865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); 890965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 891065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Drop STR_PTR for non-greedy plus quantifier. */ 891165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 891265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 891365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 891465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 891565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); 891665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 891765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich rmin_label = LABEL(); 891865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type != 0) 891965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); 892065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 892165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (bra == OP_BRAZERO) 892265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 892365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 892465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 892565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); 892665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 892765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (repeat_type == OP_EXACT) 892865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 892965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); 893065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich exact_label = LABEL(); 893165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 893265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 893365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset != 0) 893465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 893565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 893665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 893765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0); 893865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 893965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 894065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0); 894165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); 894265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 3); 894365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0); 894465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0); 894565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 894665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (common->optimized_cbracket[offset >> 1] == 0) 894765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 894865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 894965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 895065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 2); 895165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); 895265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); 895365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 895465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 895565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 895665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(opcode == OP_ONCE)) 895765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 895865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) 895965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 896065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 896165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 896265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 896365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich once = JUMP(SLJIT_JUMP); 896465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 896565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) 896665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 896765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (has_alternatives) 896865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 896965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Always exactly one alternative. */ 897065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 897165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 897265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 897365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alt_max = 2; 897465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alt1 = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); 897565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 897665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 897765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (has_alternatives) 897865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 897965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 898065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 898165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 898265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (alt_max > 4) 898365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 898465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Table jump if alt_max is greater than 4. */ 898565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich next_update_addr = common->read_only_data_ptr; 898665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->read_only_data_ptr += alt_max; 898765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr); 898865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_label_addr(common, next_update_addr++); 898965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 899065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 899165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 899265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (alt_max == 4) 899365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); 899465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); 899565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 899665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 899765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 899865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichCOMPILE_BACKTRACKINGPATH(current->top); 899965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (current->topbacktracks) 900065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 900165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 900265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) 900365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 900465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Conditional block always has at most one alternative. */ 900565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) 900665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 900765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(has_alternatives); 900865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich assert = CURRENT_AS(bracket_backtrack)->u.assert; 900965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) 901065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 901165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); 901265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 901365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); 901465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 901565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cond = JUMP(SLJIT_JUMP); 901665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); 901765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 901865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) 901965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 902065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(has_alternatives); 902165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cond = JUMP(SLJIT_JUMP); 902265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); 902365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 902465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 902565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(!has_alternatives); 902665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 902765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 902865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (has_alternatives) 902965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 903065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alt_count = sizeof(sljit_uw); 903165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do 903265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 903365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich current->top = NULL; 903465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich current->topbacktracks = NULL; 903565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich current->nextbacktracks = NULL; 903665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Conditional blocks always have an additional alternative, even if it is empty. */ 903765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc == OP_ALT) 903865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 903965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich ccprev = cc + 1 + LINK_SIZE; 904065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 904165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_COND && opcode != OP_SCOND) 904265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 904365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 904465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 904565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr != 0) 904665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); 904765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 904865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 904965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 905065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 905165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); 905265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 905365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_matchingpath(common, ccprev, cc, current); 905465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 905565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 905665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 905765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 905865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Instructions after the current alternative is successfully matched. */ 905965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* There is a similar code in compile_bracket_matchingpath. */ 906065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_ONCE) 906165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); 906265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 906365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 0; 906465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type == OP_MINUPTO) 906565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 906665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We need to preserve the counter. TMP2 will be used below. */ 906765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr); 906865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 906965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 907065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KET || bra != OP_BRA) 907165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 907265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0) 907365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 907465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 907565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 907665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->optimized_cbracket[offset >> 1] == 0) 907765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize += 2; 907865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 907965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 908065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 908165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 908265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (stacksize > 0) 908365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich allocate_stack(common, stacksize); 908465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 908565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = 0; 908665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (repeat_type == OP_MINUPTO) 908765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 908865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* TMP2 was set above. */ 908965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); 909065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 909165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 909265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 909365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KET || bra != OP_BRA) 909465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 909565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (ket != OP_KET) 909665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); 909765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 909865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); 909965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 910065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 910165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 910265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0) 910365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); 910465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 910565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 910665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count); 910765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 910865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0) 910965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 911065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */ 911165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); 911265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); 911365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 911465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 911565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath); 911665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 911765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 911865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 911965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (alt_max > 4) 912065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_label_addr(common, next_update_addr++); 912165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 912265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 912365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (alt_count != 2 * sizeof(sljit_uw)) 912465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 912565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(alt1); 912665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (alt_max == 3 && alt_count == sizeof(sljit_uw)) 912765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); 912865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 912965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 913065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 913165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(alt2); 913265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (alt_max == 4) 913365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw)); 913465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 913565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 913665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich alt_count += sizeof(sljit_uw); 913765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 913865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 913965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich COMPILE_BACKTRACKINGPATH(current->top); 914065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (current->topbacktracks) 914165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 914265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(!current->nextbacktracks); 914365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 914465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich while (*cc == OP_ALT); 914565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 914665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (cond != NULL) 914765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 914865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); 914965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich assert = CURRENT_AS(bracket_backtrack)->u.assert; 915065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) 915165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 915265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); 915365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 915465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); 915565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 915665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(cond); 915765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 915865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 915965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Free the STR_PTR. */ 916065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (private_data_ptr == 0) 916165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 916265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 916365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 916465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset != 0) 916565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 916665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Using both tmp register is better for instruction scheduling. */ 916765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->optimized_cbracket[offset >> 1] != 0) 916865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 916965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 917065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 917165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 2); 917265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); 917365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); 917465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 917565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 917665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 917765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 917865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 917965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); 918065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 918165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 918265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (opcode == OP_SBRA || opcode == OP_SCOND) 918365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 918465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); 918565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 918665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 918765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (opcode == OP_ONCE) 918865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 918965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc = ccbegin + GET(ccbegin, 1); 919065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize = needs_control_head ? 1 : 0; 919165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 919265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) 919365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 919465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Reset head and drop saved frame. */ 919565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1); 919665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 919765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) 919865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 919965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* The STR_PTR must be released. */ 920065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich stacksize++; 920165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 920265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, stacksize); 920365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 920465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(once); 920565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Restore previous private_data_ptr */ 920665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) 920765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw)); 920865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (ket == OP_KETRMIN) 920965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 921065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 921165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* See the comment below. */ 921265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 2); 921365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); 921465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 921565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 921665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 921765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (repeat_type == OP_EXACT) 921865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 921965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); 922065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0); 922165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label); 922265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 922365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (ket == OP_KETRMAX) 922465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 922565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 922665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra != OP_BRAZERO) 922765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 922865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 922965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); 923065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (bra == OP_BRAZERO) 923165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 923265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 923365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); 923465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(brazero); 923565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 923665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 923765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 923865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (ket == OP_KETRMIN) 923965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 924065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 924165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 924265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* OP_ONCE removes everything in case of a backtrack, so we don't 924365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich need to explicitly release the STR_PTR. The extra release would 924465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich affect badly the free_stack(2) above. */ 924565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode != OP_ONCE) 924665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 924765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label); 924865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (opcode == OP_ONCE) 924965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); 925065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (bra == OP_BRAMINZERO) 925165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 925265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 925365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (bra == OP_BRAZERO) 925465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 925565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 925665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); 925765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(brazero); 925865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 925965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 926065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 926165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current) 926265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 926365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 926465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint offset; 926565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 926665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 926765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (CURRENT_AS(bracketpos_backtrack)->framesize < 0) 926865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 926965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) 927065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 927165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; 927265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 927365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); 927465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); 927565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 927665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); 927765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); 927865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->capture_last_ptr != 0) 927965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0); 928065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 928165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 928265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); 928365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 928465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 928565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 928665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr); 928765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 928865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 928965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (current->topbacktracks) 929065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 929165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_JUMP); 929265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 929365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Drop the stack frame. */ 929465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); 929565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 929665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 929765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw)); 929865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 929965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 930065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current) 930165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 930265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichassert_backtrack backtrack; 930365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 930465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcurrent->top = NULL; 930565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcurrent->topbacktracks = NULL; 930665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcurrent->nextbacktracks = NULL; 930765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (current->cc[1] > OP_ASSERTBACK_NOT) 930865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 930965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */ 931065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_bracket_matchingpath(common, current->cc, current); 931165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_bracket_backtrackingpath(common, current->top); 931265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 931365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 931465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 931565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich memset(&backtrack, 0, sizeof(backtrack)); 931665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack.common.cc = current->cc; 931765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath; 931865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Manual call of compile_assert_matchingpath. */ 931965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_assert_matchingpath(common, current->cc, &backtrack, FALSE); 932065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 932165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); 932265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 932365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 932465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current) 932565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 932665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 932765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar opcode = *current->cc; 932865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *loop; 932965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 933065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 933165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_THEN || opcode == OP_THEN_ARG) 933265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 933365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->then_trap != NULL) 933465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 933565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->control_head_ptr != 0); 933665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 933765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 933865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap); 933965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start); 934065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = JUMP(SLJIT_JUMP); 934165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 934265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich loop = LABEL(); 934365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw)); 934465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 934565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop); 934665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop); 934765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP)); 934865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 934965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 935065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (common->positive_assert) 935165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 935265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP)); 935365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 935465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 935565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 935665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 935765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->local_exit) 935865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 935965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->quit_label == NULL) 936065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); 936165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 936265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, common->quit_label); 936365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 936465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 936565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 936665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_SKIP_ARG) 936765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 936865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->control_head_ptr != 0); 936965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); 937065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); 937165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2)); 937265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark)); 937365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); 937465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 937565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); 937665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1)); 937765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 937865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 937965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 938065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (opcode == OP_SKIP) 938165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 938265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 938365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0); 938465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichadd_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); 938565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 938665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 938765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current) 938865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 938965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 939065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 939165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint size; 939265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 939365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (CURRENT_AS(then_trap_backtrack)->then_trap) 939465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 939565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap; 939665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 939765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 939865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 939965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsize = CURRENT_AS(then_trap_backtrack)->framesize; 940065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsize = 3 + (size < 0 ? 0 : size); 940165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 940265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3)); 940365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfree_stack(common, size); 940465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = JUMP(SLJIT_JUMP); 940565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 940665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL()); 940765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* STACK_TOP is set by THEN. */ 940865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (CURRENT_AS(then_trap_backtrack)->framesize >= 0) 940965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 941065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 941165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfree_stack(common, 3); 941265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 941365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 941465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0); 941565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 941665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 941765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) 941865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 941965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 942065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichthen_trap_backtrack *save_then_trap = common->then_trap; 942165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 942265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (current) 942365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 942465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (current->nextbacktracks != NULL) 942565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->nextbacktracks, LABEL()); 942665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(*current->cc) 942765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 942865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SET_SOM: 942965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 943065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, 1); 943165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0); 943265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 943365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 943465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STAR: 943565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTAR: 943665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUS: 943765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUS: 943865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERY: 943965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERY: 944065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTO: 944165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTO: 944265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACT: 944365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTAR: 944465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUS: 944565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERY: 944665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTO: 944765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_STARI: 944865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINSTARI: 944965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PLUSI: 945065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINPLUSI: 945165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_QUERYI: 945265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINQUERYI: 945365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_UPTOI: 945465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MINUPTOI: 945565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_EXACTI: 945665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSSTARI: 945765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSPLUSI: 945865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSQUERYI: 945965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_POSUPTOI: 946065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTSTAR: 946165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINSTAR: 946265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPLUS: 946365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINPLUS: 946465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTQUERY: 946565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINQUERY: 946665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTUPTO: 946765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINUPTO: 946865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACT: 946965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSSTAR: 947065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSPLUS: 947165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSQUERY: 947265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSUPTO: 947365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTSTARI: 947465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINSTARI: 947565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPLUSI: 947665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINPLUSI: 947765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTQUERYI: 947865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINQUERYI: 947965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTUPTOI: 948065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTMINUPTOI: 948165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTEXACTI: 948265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSSTARI: 948365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSPLUSI: 948465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSQUERYI: 948565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NOTPOSUPTOI: 948665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPESTAR: 948765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINSTAR: 948865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPLUS: 948965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINPLUS: 949065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEQUERY: 949165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINQUERY: 949265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEUPTO: 949365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEMINUPTO: 949465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEEXACT: 949565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSSTAR: 949665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSPLUS: 949765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSQUERY: 949865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_TYPEPOSUPTO: 949965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CLASS: 950065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_NCLASS: 950165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 950265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_XCLASS: 950365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 950465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_iterator_backtrackingpath(common, current); 950565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 950665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 950765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REF: 950865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_REFI: 950965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNREF: 951065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_DNREFI: 951165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_ref_iterator_backtrackingpath(common, current); 951265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 951365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 951465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_RECURSE: 951565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_recurse_backtrackingpath(common, current); 951665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 951765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 951865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT: 951965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_NOT: 952065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK: 952165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERTBACK_NOT: 952265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_assert_backtrackingpath(common, current); 952365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 952465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 952565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE: 952665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ONCE_NC: 952765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRA: 952865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRA: 952965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COND: 953065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRA: 953165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRA: 953265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCOND: 953365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_bracket_backtrackingpath(common, current); 953465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 953565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 953665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAZERO: 953765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (current->cc[1] > OP_ASSERTBACK_NOT) 953865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_bracket_backtrackingpath(common, current); 953965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 954065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_assert_backtrackingpath(common, current); 954165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 954265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 954365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOS: 954465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CBRAPOS: 954565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SBRAPOS: 954665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SCBRAPOS: 954765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAPOSZERO: 954865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_bracketpos_backtrackingpath(common, current); 954965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 955065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 955165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_BRAMINZERO: 955265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_braminzero_backtrackingpath(common, current); 955365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 955465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 955565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_MARK: 955665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0)); 955765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->has_skip_arg) 955865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 955965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich free_stack(common, common->has_skip_arg ? 5 : 1); 956065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0); 956165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->has_skip_arg) 956265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0); 956365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 956465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 956565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN: 956665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN_ARG: 956765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE: 956865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_PRUNE_ARG: 956965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIP: 957065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_SKIP_ARG: 957165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_control_verb_backtrackingpath(common, current); 957265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 957365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 957465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_COMMIT: 957565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (!common->local_exit) 957665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); 957765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->quit_label == NULL) 957865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); 957965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 958065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, common->quit_label); 958165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 958265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 958365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_CALLOUT: 958465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_FAIL: 958565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ACCEPT: 958665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_ASSERT_ACCEPT: 958765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(current->topbacktracks, LABEL()); 958865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 958965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 959065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case OP_THEN_TRAP: 959165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* A virtual opcode for then traps. */ 959265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_then_trap_backtrackingpath(common, current); 959365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 959465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 959565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: 959665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT_STOP(); 959765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 959865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 959965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich current = current->prev; 960065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 960165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->then_trap = save_then_trap; 960265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 960365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 960465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic SLJIT_INLINE void compile_recurse(compiler_common *common) 960565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 960665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichDEFINE_COMPILER; 960765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *cc = common->start + common->currententry->start; 960865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); 960965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccend = bracketend(cc); 961065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needs_control_head; 961165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head); 961265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head); 961365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint alternativesize; 961465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichBOOL needs_frame; 961565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common altbacktrack; 961665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 961765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 961865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Recurse captures then. */ 961965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->then_trap = NULL; 962065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 962165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); 962265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichneeds_frame = framesize >= 0; 962365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!needs_frame) 962465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich framesize = 0; 962565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichalternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; 962665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 962765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0); 962865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->currententry->entry = LABEL(); 962965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(common->currententry->calls, common->currententry->entry); 963065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 963165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, TMP2, 0); 963265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichallocate_stack(common, private_data_size + framesize + alternativesize); 963365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); 963465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcopy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); 963565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (needs_control_head) 963665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); 963765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0); 963865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (needs_frame) 963965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE); 964065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 964165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (alternativesize > 0) 964265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); 964365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 964465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmemset(&altbacktrack, 0, sizeof(backtrack_common)); 964565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->quit_label = NULL; 964665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->accept_label = NULL; 964765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->quit = NULL; 964865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->accept = NULL; 964965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichaltbacktrack.cc = ccbegin; 965065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcc += GET(cc, 1); 965165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (1) 965265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 965365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich altbacktrack.top = NULL; 965465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich altbacktrack.topbacktracks = NULL; 965565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 965665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (altbacktrack.cc != ccbegin) 965765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); 965865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 965965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack); 966065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 966165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 966265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 966365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); 966465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 966565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_backtrackingpath(common, altbacktrack.top); 966665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 966765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 966865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(altbacktrack.topbacktracks, LABEL()); 966965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 967065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (*cc != OP_ALT) 967165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 967265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 967365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich altbacktrack.cc = cc + 1 + LINK_SIZE; 967465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich cc += GET(cc, 1); 967565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 967665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 967765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* None of them matched. */ 967865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); 967965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = JUMP(SLJIT_JUMP); 968065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 968165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->quit != NULL) 968265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 968365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->quit, LABEL()); 968465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr); 968565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (needs_frame) 968665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 968765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); 968865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 968965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); 969065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 969165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); 969265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->quit = NULL; 969365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); 969465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 969565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 969665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(common->accept, LABEL()); 969765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr); 969865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (needs_frame) 969965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 970065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); 970165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); 970265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); 970365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 970465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); 970565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 970665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 970765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->quit != NULL) 970865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->quit, LABEL()); 970965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcopy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); 971065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfree_stack(common, private_data_size + framesize + alternativesize); 971165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (needs_control_head) 971265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 971365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw)); 971465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); 971565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP1, 0); 971665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 971765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0); 971865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 971965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 972065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 972165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); 972265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); 972365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP2, 0); 972465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 972565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); 972665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 972765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 972865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef COMPILE_BACKTRACKINGPATH 972965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CURRENT_AS 973065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 973165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichvoid 973265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode) 973365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 973465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_compiler *compiler; 973565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbacktrack_common rootbacktrack; 973665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompiler_common common_data; 973765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompiler_common *common = &common_data; 973865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst pcre_uint8 *tables = re->tables; 973965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_study_data *study; 974065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint private_data_size; 974165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *ccend; 974265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichexecutable_functions *functions; 974365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichvoid *executable_func; 974465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_uw executable_size; 974565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_uw total_length; 974665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel_addr_list *label_addr; 974765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *mainloop_label = NULL; 974865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *continue_match_label; 974965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *empty_match_found_label = NULL; 975065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *empty_match_backtrack_label = NULL; 975165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *reset_match_label; 975265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_label *quit_label; 975365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *jump; 975465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *minlength_check_failed = NULL; 975565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *reqbyte_notfound = NULL; 975665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_jump *empty_match = NULL; 975765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 975865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0); 975965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstudy = extra->study_data; 976065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 976165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!tables) 976265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich tables = PRIV(default_tables); 976365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 976465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmemset(&rootbacktrack, 0, sizeof(backtrack_common)); 976565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmemset(common, 0, sizeof(compiler_common)); 976665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichrootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; 976765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 976865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->start = rootbacktrack.cc; 976965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->read_only_data = NULL; 977065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->read_only_data_size = 0; 977165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->read_only_data_ptr = NULL; 977265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->fcc = tables + fcc_offset; 977365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->lcc = (sljit_sw)(tables + lcc_offset); 977465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->mode = mode; 977565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->might_be_empty = study->minlength == 0; 977665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->nltype = NLTYPE_FIXED; 977765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichswitch(re->options & PCRE_NEWLINE_BITS) 977865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 977965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case 0: 978065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Compile-time default */ 978165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich switch(NEWLINE) 978265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 978365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; 978465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; 978565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: common->newline = NEWLINE; break; 978665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 978765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich break; 978865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; 978965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; 979065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PCRE_NEWLINE_CR+ 979165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break; 979265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; 979365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; 979465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich default: return; 979565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 979665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->nlmax = READ_CHAR_MAX; 979765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->nlmin = 0; 979865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((re->options & PCRE_BSR_ANYCRLF) != 0) 979965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->bsr_nltype = NLTYPE_ANYCRLF; 980065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if ((re->options & PCRE_BSR_UNICODE) != 0) 980165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->bsr_nltype = NLTYPE_ANY; 980265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 980365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 980465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef BSR_ANYCRLF 980565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->bsr_nltype = NLTYPE_ANYCRLF; 980665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 980765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->bsr_nltype = NLTYPE_ANY; 980865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 980965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 981065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->bsr_nlmax = READ_CHAR_MAX; 981165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->bsr_nlmin = 0; 981265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; 981365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->ctypes = (sljit_sw)(tables + ctypes_offset); 981465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->name_table = ((pcre_uchar *)re) + re->name_table_offset; 981565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->name_count = re->name_count; 981665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->name_entry_size = re->name_entry_size; 981765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; 981865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 981965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */ 982065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->utf = (re->options & PCRE_UTF8) != 0; 982165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 982265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->use_ucp = (re->options & PCRE_UCP) != 0; 982365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 982465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utf) 982565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 982665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->nltype == NLTYPE_ANY) 982765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->nlmax = 0x2029; 982865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if (common->nltype == NLTYPE_ANYCRLF) 982965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; 983065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 983165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 983265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* We only care about the first newline character. */ 983365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->nlmax = common->newline & 0xff; 983465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 983565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 983665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->nltype == NLTYPE_FIXED) 983765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->nlmin = common->newline & 0xff; 983865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 983965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; 984065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 984165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->bsr_nltype == NLTYPE_ANY) 984265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->bsr_nlmax = 0x2029; 984365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 984465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; 984565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; 984665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 984765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 984865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichccend = bracketend(common->start); 984965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 985065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Calculate the local space size on the stack. */ 985165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); 985265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1); 985365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!common->optimized_cbracket) 985465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 985565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1 985665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmemset(common->optimized_cbracket, 0, re->top_bracket + 1); 985765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else 985865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmemset(common->optimized_cbracket, 1, re->top_bracket + 1); 985965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 986065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 986165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); 986265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2 986365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->capture_last_ptr = common->ovector_start; 986465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->ovector_start += sizeof(sljit_sw); 986565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 986665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!check_opcode_types(common, common->start, ccend)) 986765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 986865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 986965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 987065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 987165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 987265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Checking flags and updating ovector_start. */ 987365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) 987465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 987565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->req_char_ptr = common->ovector_start; 987665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 987765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 987865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (mode != JIT_COMPILE) 987965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 988065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->start_used_ptr = common->ovector_start; 988165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 988265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (mode == JIT_PARTIAL_SOFT_COMPILE) 988365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 988465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->hit_start = common->ovector_start; 988565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += 2 * sizeof(sljit_sw); 988665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 988765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 988865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 988965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE); 989065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->needs_start_ptr = TRUE; 989165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 989265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 989365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((re->options & PCRE_FIRSTLINE) != 0) 989465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 989565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->first_line_end = common->ovector_start; 989665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 989765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 989865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD 989965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->control_head_ptr = 1; 990065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 990165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->control_head_ptr != 0) 990265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 990365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->control_head_ptr = common->ovector_start; 990465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 990565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 990665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->needs_start_ptr && common->has_set_som) 990765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 990865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Saving the real start pointer is necessary. */ 990965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->start_ptr = common->ovector_start; 991065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 991165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 991265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 991365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->needs_start_ptr = FALSE; 991465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 991565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Aligning ovector to even number of sljit words. */ 991665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((common->ovector_start & sizeof(sljit_sw)) != 0) 991765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->ovector_start += sizeof(sljit_sw); 991865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 991965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->start_ptr == 0) 992065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->start_ptr = OVECTOR(0); 992165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 992265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Capturing brackets cannot be optimized if callouts are allowed. */ 992365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->capture_last_ptr != 0) 992465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich memset(common->optimized_cbracket, 0, re->top_bracket + 1); 992565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 992665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); 992765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); 992865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 992965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichtotal_length = ccend - common->start; 993065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0))); 993165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!common->private_data_ptrs) 993265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 993365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 993465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 993565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 993665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmemset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si)); 993765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 993865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichprivate_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); 993965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_private_data_ptrs(common, &private_data_size, ccend); 994065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (private_data_size > SLJIT_MAX_LOCAL_SIZE) 994165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 994265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->private_data_ptrs); 994365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 994465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 994565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 994665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 994765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->has_then) 994865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 994965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->then_offsets = (pcre_uint8 *)(common->private_data_ptrs + total_length); 995065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich memset(common->then_offsets, 0, total_length); 995165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_then_offsets(common, common->start, NULL); 995265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 995365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 995465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->read_only_data_size > 0) 995565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 995665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size); 995765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data == NULL) 995865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 995965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 996065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->private_data_ptrs); 996165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 996265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 996365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->read_only_data_ptr = common->read_only_data; 996465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 996565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 996665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompiler = sljit_create_compiler(); 996765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (!compiler) 996865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 996965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 997065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->private_data_ptrs); 997165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data) 997265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->read_only_data); 997365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 997465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 997565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->compiler = compiler; 997665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 997765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Main pcre_jit_exec entry. */ 997865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size); 997965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 998065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Register init. */ 998165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreset_ovector(common, (re->top_bracket + 1) * 2); 998265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->req_char_ptr != 0) 998365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0); 998465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 998565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0); 998665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0); 998765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 998865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); 998965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); 999065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); 999165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); 999265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); 999365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0); 999465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 999565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (mode == JIT_PARTIAL_SOFT_COMPILE) 999665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1); 999765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->mark_ptr != 0) 999865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0); 999965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->control_head_ptr != 0) 1000065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); 1000165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1000265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Main part of the matching */ 1000365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((re->options & PCRE_ANCHORED) == 0) 1000465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1000565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); 1000665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue_match_label = LABEL(); 1000765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Forward search if possible. */ 1000865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((re->options & PCRE_NO_START_OPTIMIZE) == 0) 1000965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1001065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0)) 1001165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1001265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* If read_only_data is reallocated, we might have an allocation failure. */ 1001365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data_size > 0 && common->read_only_data == NULL) 1001465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1001565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_free_compiler(compiler); 1001665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 1001765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->private_data_ptrs); 1001865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 1001965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1002065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1002165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if ((re->flags & PCRE_FIRSTSET) != 0) 1002265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); 1002365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if ((re->flags & PCRE_STARTLINE) != 0) 1002465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); 1002565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) 1002665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich fast_forward_start_bits(common, study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); 1002765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1002865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1002965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 1003065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich continue_match_label = LABEL(); 1003165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1003265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) 1003365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1003465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); 1003565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength)); 1003665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich minlength_check_failed = CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0); 1003765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1003865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->req_char_ptr != 0) 1003965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0); 1004065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1004165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Store the current STR_PTR in OVECTOR(0). */ 1004265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0); 1004365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Copy the limit of allowed recursions. */ 1004465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH); 1004565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->capture_last_ptr != 0) 1004665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, -1); 1004765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1004865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->needs_start_ptr) 1004965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1005065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->start_ptr != OVECTOR(0)); 1005165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0); 1005265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1005365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 1005465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->start_ptr == OVECTOR(0)); 1005565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1005665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Copy the beginning of the string. */ 1005765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (mode == JIT_PARTIAL_SOFT_COMPILE) 1005865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1005965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1); 1006065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); 1006165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start + sizeof(sljit_sw), STR_PTR, 0); 1006265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 1006365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1006465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if (mode == JIT_PARTIAL_HARD_COMPILE) 1006565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); 1006665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1006765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompile_matchingpath(common, common->start, ccend, &rootbacktrack); 1006865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 1006965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1007065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_free_compiler(compiler); 1007165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 1007265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->private_data_ptrs); 1007365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data) 1007465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->read_only_data); 1007565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 1007665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1007765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1007865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->might_be_empty) 1007965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1008065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); 1008165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich empty_match_found_label = LABEL(); 1008265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1008365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1008465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->accept_label = LABEL(); 1008565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->accept != NULL) 1008665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->accept, common->accept_label); 1008765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1008865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* This means we have a match. Update the ovector. */ 1008965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcopy_ovector(common, re->top_bracket + 1); 1009065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->quit_label = common->forced_quit_label = LABEL(); 1009165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->quit != NULL) 1009265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->quit, common->quit_label); 1009365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->forced_quit != NULL) 1009465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->forced_quit, common->forced_quit_label); 1009565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (minlength_check_failed != NULL) 1009665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SET_LABEL(minlength_check_failed, common->forced_quit_label); 1009765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); 1009865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1009965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (mode != JIT_COMPILE) 1010065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1010165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->partialmatchlabel = LABEL(); 1010265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->partialmatch, common->partialmatchlabel); 1010365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return_with_partial_match(common, common->quit_label); 1010465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1010565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1010665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->might_be_empty) 1010765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich empty_match_backtrack_label = LABEL(); 1010865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcompile_backtrackingpath(common, rootbacktrack.top); 1010965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 1011065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1011165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_free_compiler(compiler); 1011265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 1011365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->private_data_ptrs); 1011465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data) 1011565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->read_only_data); 1011665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 1011765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1011865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1011965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(rootbacktrack.prev == NULL); 1012065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreset_match_label = LABEL(); 1012165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1012265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (mode == JIT_PARTIAL_SOFT_COMPILE) 1012365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1012465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Update hit_start only in the first time. */ 1012565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); 1012665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr); 1012765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); 1012865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0); 1012965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(jump); 1013065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1013165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1013265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Check we have remaining characters. */ 1013365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0) 1013465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1013565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_ASSERT(common->first_line_end != 0); 1013665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); 1013765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1013865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1013965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); 1014065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1014165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((re->options & PCRE_ANCHORED) == 0) 1014265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1014365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->ff_newline_shortcut != NULL) 1014465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1014565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((re->options & PCRE_FIRSTLINE) == 0) 1014665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut); 1014765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* There cannot be more newlines here. */ 1014865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1014965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 1015065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1015165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if ((re->options & PCRE_FIRSTLINE) == 0) 1015265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label); 1015365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich else 1015465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label); 1015565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1015665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1015765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1015865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* No more remaining characters. */ 1015965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (reqbyte_notfound != NULL) 1016065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(reqbyte_notfound); 1016165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1016265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (mode == JIT_PARTIAL_SOFT_COMPILE) 1016365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel); 1016465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1016565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); 1016665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, common->quit_label); 1016765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1016865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichflush_stubs(common); 1016965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1017065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->might_be_empty) 1017165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1017265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPHERE(empty_match); 1017365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 1017465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); 1017565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label); 1017665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); 1017765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label); 1017865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); 1017965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label); 1018065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, empty_match_backtrack_label); 1018165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1018265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1018365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->currententry = common->entries; 1018465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->local_exit = TRUE; 1018565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichquit_label = common->quit_label; 1018665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (common->currententry != NULL) 1018765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1018865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Might add new entries. */ 1018965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich compile_recurse(common); 1019065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) 1019165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1019265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_free_compiler(compiler); 1019365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->optimized_cbracket); 1019465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->private_data_ptrs); 1019565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data) 1019665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->read_only_data); 1019765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 1019865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1019965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich flush_stubs(common); 1020065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich common->currententry = common->currententry->next; 1020165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1020265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->local_exit = FALSE; 1020365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichcommon->quit_label = quit_label; 1020465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1020565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ 1020665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* This is a (really) rare case. */ 1020765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(common->stackalloc, LABEL()); 1020865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* RETURN_ADDR is not a saved register. */ 1020965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); 1021065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); 1021165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 1021265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); 1021365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0); 1021465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); 1021565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1021665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); 1021765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); 1021865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); 1021965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); 1022065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); 1022165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit)); 1022265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); 1022365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); 1022465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1022565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Allocation failed. */ 1022665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPHERE(jump); 1022765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* We break the return address cache here, but this is a really rare case. */ 1022865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); 1022965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, common->quit_label); 1023065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1023165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Call limit reached. */ 1023265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichset_jumps(common->calllimit, LABEL()); 1023365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichOP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); 1023465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichJUMPTO(SLJIT_JUMP, common->quit_label); 1023565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1023665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->revertframes != NULL) 1023765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1023865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->revertframes, LABEL()); 1023965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do_revertframes(common); 1024065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1024165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->wordboundary != NULL) 1024265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1024365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->wordboundary, LABEL()); 1024465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_wordboundary(common); 1024565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1024665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->anynewline != NULL) 1024765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1024865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->anynewline, LABEL()); 1024965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_anynewline(common); 1025065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1025165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->hspace != NULL) 1025265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1025365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->hspace, LABEL()); 1025465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_hspace(common); 1025565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1025665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->vspace != NULL) 1025765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1025865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->vspace, LABEL()); 1025965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich check_vspace(common); 1026065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1026165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->casefulcmp != NULL) 1026265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1026365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->casefulcmp, LABEL()); 1026465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do_casefulcmp(common); 1026565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1026665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->caselesscmp != NULL) 1026765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1026865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->caselesscmp, LABEL()); 1026965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do_caselesscmp(common); 1027065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1027165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->reset_match != NULL) 1027265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1027365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->reset_match, LABEL()); 1027465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do_reset_match(common, (re->top_bracket + 1) * 2); 1027565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label); 1027665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); 1027765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich JUMPTO(SLJIT_JUMP, reset_match_label); 1027865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1027965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF 1028065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef COMPILE_PCRE8 1028165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utfreadchar != NULL) 1028265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1028365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->utfreadchar, LABEL()); 1028465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do_utfreadchar(common); 1028565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1028665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utfreadchar16 != NULL) 1028765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1028865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->utfreadchar16, LABEL()); 1028965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do_utfreadchar16(common); 1029065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1029165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->utfreadtype8 != NULL) 1029265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1029365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->utfreadtype8, LABEL()); 1029465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do_utfreadtype8(common); 1029565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1029665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* COMPILE_PCRE8 */ 1029765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif /* SUPPORT_UTF */ 1029865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UCP 1029965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (common->getucd != NULL) 1030065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1030165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich set_jumps(common->getucd, LABEL()); 1030265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich do_getucd(common); 1030365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1030465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1030565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1030665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_ASSERT(common->read_only_data + (common->read_only_data_size >> SLJIT_WORD_SHIFT) == common->read_only_data_ptr); 1030765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_FREE(common->optimized_cbracket); 1030865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_FREE(common->private_data_ptrs); 1030965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1031065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichexecutable_func = sljit_generate_code(compiler); 1031165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichexecutable_size = sljit_get_generated_code_size(compiler); 1031265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlabel_addr = common->label_addrs; 1031365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichwhile (label_addr != NULL) 1031465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1031565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *label_addr->update_addr = sljit_get_label_addr(label_addr->label); 1031665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich label_addr = label_addr->next; 1031765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1031865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_free_compiler(compiler); 1031965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (executable_func == NULL) 1032065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1032165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data) 1032265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->read_only_data); 1032365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 1032465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1032565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1032665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Reuse the function descriptor if possible. */ 1032765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) 1032865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich functions = (executable_functions *)extra->executable_jit; 1032965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 1033065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1033165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* Note: If your memory-checker has flagged the allocation below as a 1033265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * memory leak, it is probably because you either forgot to call 1033365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * pcre_free_study() (or pcre16_free_study()) on the pcre_extra (or 1033465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * pcre16_extra) object, or you called said function after having 1033565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * cleared the PCRE_EXTRA_EXECUTABLE_JIT bit from the "flags" field 1033665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * of the object. (The function will only free the JIT data if the 1033765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * bit remains set, as the bit indicates that the pointer to the data 1033865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich * is valid.) 1033965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich */ 1034065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich functions = SLJIT_MALLOC(sizeof(executable_functions)); 1034165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (functions == NULL) 1034265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1034365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich /* This case is highly unlikely since we just recently 1034465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich freed a lot of memory. Not impossible though. */ 1034565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_free_code(executable_func); 1034665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (common->read_only_data) 1034765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(common->read_only_data); 1034865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return; 1034965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1035065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich memset(functions, 0, sizeof(executable_functions)); 1035165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich functions->top_bracket = (re->top_bracket + 1) * 2; 1035265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0; 1035365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich extra->executable_jit = functions; 1035465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; 1035565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1035665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1035765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfunctions->executable_funcs[mode] = executable_func; 1035865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfunctions->read_only_data[mode] = common->read_only_data; 1035965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfunctions->executable_sizes[mode] = executable_size; 1036065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1036165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1036265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func) 1036365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1036465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunion { 1036565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich void* executable_func; 1036665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jit_function call_executable_func; 1036765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} convert_executable_func; 1036865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uint8 local_space[MACHINE_STACK_SIZE]; 1036965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstruct sljit_stack local_stack; 1037065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1037165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlocal_stack.top = (sljit_sw)&local_space; 1037265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlocal_stack.base = local_stack.top; 1037365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlocal_stack.limit = local_stack.base + MACHINE_STACK_SIZE; 1037465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichlocal_stack.max_limit = local_stack.limit; 1037565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments->stack = &local_stack; 1037665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconvert_executable_func.executable_func = executable_func; 1037765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn convert_executable_func.call_executable_func(arguments); 1037865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1037965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1038065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint 1038165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject, 1038265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int length, int start_offset, int options, int *offsets, int offset_count) 1038365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1038465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichexecutable_functions *functions = (executable_functions *)extra_data->executable_jit; 1038565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunion { 1038665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich void* executable_func; 1038765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jit_function call_executable_func; 1038865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} convert_executable_func; 1038965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjit_arguments arguments; 1039065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint max_offset_count; 1039165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint retval; 1039265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint mode = JIT_COMPILE; 1039365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1039465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((options & PCRE_PARTIAL_HARD) != 0) 1039565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mode = JIT_PARTIAL_HARD_COMPILE; 1039665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if ((options & PCRE_PARTIAL_SOFT) != 0) 1039765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mode = JIT_PARTIAL_SOFT_COMPILE; 1039865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1039965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (functions->executable_funcs[mode] == NULL) 1040065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return PCRE_ERROR_JIT_BADOPTION; 1040165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1040265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Sanity checks should be handled by pcre_exec. */ 1040365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.str = subject + start_offset; 1040465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.begin = subject; 1040565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.end = subject + length; 1040665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.mark_ptr = NULL; 1040765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* JIT decreases this value less frequently than the interpreter. */ 1040865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); 1040965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) 1041065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich arguments.limit_match = functions->limit_match; 1041165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.notbol = (options & PCRE_NOTBOL) != 0; 1041265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.noteol = (options & PCRE_NOTEOL) != 0; 1041365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.notempty = (options & PCRE_NOTEMPTY) != 0; 1041465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; 1041565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.offsets = offsets; 1041665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL; 1041765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.real_offset_count = offset_count; 1041865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1041965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of 1042065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichthe output vector for storing captured strings, with the remainder used as 1042165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichworkspace. We don't need the workspace here. For compatibility, we limit the 1042265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichnumber of captured strings in the same way as pcre_exec(), so that the user 1042365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichgets the same result with and without JIT. */ 1042465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1042565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset_count != 2) 1042665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset_count = ((offset_count - (offset_count % 3)) * 2) / 3; 1042765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmax_offset_count = functions->top_bracket; 1042865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset_count > max_offset_count) 1042965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset_count = max_offset_count; 1043065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.offset_count = offset_count; 1043165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1043265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (functions->callback) 1043365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata); 1043465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 1043565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich arguments.stack = (struct sljit_stack *)functions->userdata; 1043665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1043765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (arguments.stack == NULL) 1043865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]); 1043965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse 1044065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1044165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich convert_executable_func.executable_func = functions->executable_funcs[mode]; 1044265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich retval = convert_executable_func.call_executable_func(&arguments); 1044365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1044465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1044565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (retval * 2 > offset_count) 1044665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich retval = 0; 1044765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((extra_data->flags & PCRE_EXTRA_MARK) != 0) 1044865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *(extra_data->mark) = arguments.mark_ptr; 1044965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1045065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn retval; 1045165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1045265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1045365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1045465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DEFN int PCRE_CALL_CONVENTION 1045565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data, 1045665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PCRE_SPTR subject, int length, int start_offset, int options, 1045765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int *offsets, int offset_count, pcre_jit_stack *stack) 1045865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1045965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DEFN int PCRE_CALL_CONVENTION 1046065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, 1046165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PCRE_SPTR16 subject, int length, int start_offset, int options, 1046265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int *offsets, int offset_count, pcre16_jit_stack *stack) 1046365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1046465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DEFN int PCRE_CALL_CONVENTION 1046565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data, 1046665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich PCRE_SPTR32 subject, int length, int start_offset, int options, 1046765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich int *offsets, int offset_count, pcre32_jit_stack *stack) 1046865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1046965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1047065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_uchar *subject_ptr = (pcre_uchar *)subject; 1047165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichexecutable_functions *functions = (executable_functions *)extra_data->executable_jit; 1047265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichunion { 1047365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich void* executable_func; 1047465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich jit_function call_executable_func; 1047565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} convert_executable_func; 1047665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichjit_arguments arguments; 1047765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint max_offset_count; 1047865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint retval; 1047965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint mode = JIT_COMPILE; 1048065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1048165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_UNUSED_ARG(argument_re); 1048265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1048365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Plausibility checks */ 1048465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((options & ~PUBLIC_JIT_EXEC_OPTIONS) != 0) return PCRE_ERROR_JIT_BADOPTION; 1048565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1048665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((options & PCRE_PARTIAL_HARD) != 0) 1048765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mode = JIT_PARTIAL_HARD_COMPILE; 1048865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichelse if ((options & PCRE_PARTIAL_SOFT) != 0) 1048965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich mode = JIT_PARTIAL_SOFT_COMPILE; 1049065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1049165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (functions->executable_funcs[mode] == NULL) 1049265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return PCRE_ERROR_JIT_BADOPTION; 1049365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1049465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* Sanity checks should be handled by pcre_exec. */ 1049565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.stack = (struct sljit_stack *)stack; 1049665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.str = subject_ptr + start_offset; 1049765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.begin = subject_ptr; 1049865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.end = subject_ptr + length; 1049965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.mark_ptr = NULL; 1050065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* JIT decreases this value less frequently than the interpreter. */ 1050165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); 1050265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) 1050365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich arguments.limit_match = functions->limit_match; 1050465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.notbol = (options & PCRE_NOTBOL) != 0; 1050565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.noteol = (options & PCRE_NOTEOL) != 0; 1050665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.notempty = (options & PCRE_NOTEMPTY) != 0; 1050765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; 1050865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.offsets = offsets; 1050965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL; 1051065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.real_offset_count = offset_count; 1051165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1051265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of 1051365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichthe output vector for storing captured strings, with the remainder used as 1051465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichworkspace. We don't need the workspace here. For compatibility, we limit the 1051565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichnumber of captured strings in the same way as pcre_exec(), so that the user 1051665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichgets the same result with and without JIT. */ 1051765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1051865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset_count != 2) 1051965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset_count = ((offset_count - (offset_count % 3)) * 2) / 3; 1052065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmax_offset_count = functions->top_bracket; 1052165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (offset_count > max_offset_count) 1052265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich offset_count = max_offset_count; 1052365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevicharguments.offset_count = offset_count; 1052465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1052565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconvert_executable_func.executable_func = functions->executable_funcs[mode]; 1052665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichretval = convert_executable_func.call_executable_func(&arguments); 1052765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1052865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (retval * 2 > offset_count) 1052965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich retval = 0; 1053065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif ((extra_data->flags & PCRE_EXTRA_MARK) != 0) 1053165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich *(extra_data->mark) = arguments.mark_ptr; 1053265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1053365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn retval; 1053465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1053565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1053665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichvoid 1053765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPRIV(jit_free)(void *executable_funcs) 1053865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1053965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i; 1054065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichexecutable_functions *functions = (executable_functions *)executable_funcs; 1054165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) 1054265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1054365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (functions->executable_funcs[i] != NULL) 1054465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich sljit_free_code(functions->executable_funcs[i]); 1054565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich if (functions->read_only_data[i] != NULL) 1054665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich SLJIT_FREE(functions->read_only_data[i]); 1054765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1054865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichSLJIT_FREE(functions); 1054965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1055065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1055165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint 1055265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPRIV(jit_get_size)(void *executable_funcs) 1055365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1055465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint i; 1055565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_uw size = 0; 1055665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes; 1055765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichfor (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) 1055865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich size += executable_sizes[i]; 1055965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn (int)size; 1056065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1056165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1056265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichconst char* 1056365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPRIV(jit_get_target)(void) 1056465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1056565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn sljit_get_platform_name(); 1056665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1056765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1056865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1056965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL pcre_jit_stack * 1057065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_jit_stack_alloc(int startsize, int maxsize) 1057165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1057265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL pcre16_jit_stack * 1057365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_jit_stack_alloc(int startsize, int maxsize) 1057465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1057565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL pcre32_jit_stack * 1057665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_jit_stack_alloc(int startsize, int maxsize) 1057765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1057865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1057965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (startsize < 1 || maxsize < 1) 1058065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich return NULL; 1058165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (startsize > maxsize) 1058265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich startsize = maxsize; 1058365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstartsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); 1058465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichmaxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); 1058565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize); 1058665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1058765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1058865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1058965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1059065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_jit_stack_free(pcre_jit_stack *stack) 1059165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1059265de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1059365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_jit_stack_free(pcre16_jit_stack *stack) 1059465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1059565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1059665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_jit_stack_free(pcre32_jit_stack *stack) 1059765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1059865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1059965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_free_stack((struct sljit_stack *)stack); 1060065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1060165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1060265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1060365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1060465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) 1060565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1060665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1060765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) 1060865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1060965de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1061065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata) 1061165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1061265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1061365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichexecutable_functions *functions; 1061465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichif (extra != NULL && 1061565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && 1061665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich extra->executable_jit != NULL) 1061765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich { 1061865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich functions = (executable_functions *)extra->executable_jit; 1061965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich functions->callback = callback; 1062065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich functions->userdata = userdata; 1062165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich } 1062265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1062365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1062465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1062565de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1062665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_jit_free_unused_memory(void) 1062765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1062865de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1062965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_jit_free_unused_memory(void) 1063065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1063165de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1063265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_jit_free_unused_memory(void) 1063365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1063465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1063565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichsljit_free_unused_memory_exec(); 1063665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1063765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1063865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else /* SUPPORT_JIT */ 1063965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1064065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* These are dummy functions to avoid linking errors when JIT support is not 1064165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichbeing compiled. */ 1064265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1064365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1064465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL pcre_jit_stack * 1064565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_jit_stack_alloc(int startsize, int maxsize) 1064665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1064765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL pcre16_jit_stack * 1064865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_jit_stack_alloc(int startsize, int maxsize) 1064965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1065065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL pcre32_jit_stack * 1065165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_jit_stack_alloc(int startsize, int maxsize) 1065265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1065365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1065465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich(void)startsize; 1065565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich(void)maxsize; 1065665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichreturn NULL; 1065765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1065865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1065965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1066065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1066165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_jit_stack_free(pcre_jit_stack *stack) 1066265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1066365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1066465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_jit_stack_free(pcre16_jit_stack *stack) 1066565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1066665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1066765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_jit_stack_free(pcre32_jit_stack *stack) 1066865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1066965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1067065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich(void)stack; 1067165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1067265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1067365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1067465de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1067565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) 1067665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1067765de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1067865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) 1067965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1068065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1068165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata) 1068265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1068365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1068465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich(void)extra; 1068565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich(void)callback; 1068665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich(void)userdata; 1068765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1068865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1068965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined COMPILE_PCRE8 1069065de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1069165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre_jit_free_unused_memory(void) 1069265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE16 1069365de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1069465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre16_jit_free_unused_memory(void) 1069565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#elif defined COMPILE_PCRE32 1069665de34233da93a3d65c00b8aad3ff9aad44c57deNick KralevichPCRE_EXP_DECL void 1069765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichpcre32_jit_free_unused_memory(void) 1069865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1069965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich{ 1070065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} 1070165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1070265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif 1070365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich 1070465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich/* End of pcre_jit_compile.c */ 10705